是否可以在mysql中强制执行考虑另一个表中列的特定值的约束?

时间:2017-10-21 18:56:02

标签: mysql sql database

我有一个使用嵌套集模型表示层次数据的基表。

CREATE TABLE trees (
    id INT NOT NULL AUTO_INCREMENT,
    rootId INT DEFAULT NULL,
    lft INT NOT NULL,
    rgt INT NOT NULL,
    PRIMARY KEY(id),
    FOREIGN KEY(rootId) REFERENCES trees(id)
);

因此,此表可以包含多个单独的树,其中rootId指向每个树的顶部节点。

现在我想添加一个新表来扩展带有子类型的树。例如:

CREATE TABLE happyTrees (
    treeId INT NOT NULL,
    PRIMARY KEY(treeId),
    FOREIGN KEY(treeId) REFERENCES trees(id)
);

插入到happyTrees中的行应该只指向树中的根级节点 - 因此树中的行的rootId为null。

我可以在应用程序级别强制执行此操作,但我想知道:在sql中是否有更优雅的方法来强制执行此约束?因此,如果树中相应的rootId为null,则只能将treeId插入到happyTrees中?

2 个答案:

答案 0 :(得分:1)

我会以不同的方式思考设计。

将属性放在trees表(字段is_happy)中,或者创建一个引用树结构的单独tree_attributes表。

因为最终“快乐”的树结构仍然是树结构。

虽然我很欣赏这在插入行时不会创建数据库强制约束。虽然我更喜欢数据库模型,以防止首先插入错误的数据,但有时简单性更好。

答案 1 :(得分:0)

以下适合您的具体情况:

CREATE TABLE trees (
    id INT NOT NULL AUTO_INCREMENT,
    rootId INT DEFAULT NULL,
    lft INT NOT NULL,
    rgt INT NOT NULL,
    PRIMARY KEY(id),
    UNIQUE (rootId, id),  -- redundant, but needed for foreign key relationship
    FOREIGN KEY(rootId) REFERENCES trees(id)
);

CREATE TABLE happyTrees (
    treeId INT NOT NULL,
    _rootId INT NULL, -- actually, ALWAYS NULL
    PRIMARY KEY(treeId),
    FOREIGN KEY(_rootId, treeId) REFERENCES trees(rootId, id);
);

这是添加一个您想要始终为NULL的虚拟列。然后它可以引用另一个表,保证快乐树只指向根。

这是否比在应用程序中完成工作更优雅(或者,更好的是在我看来,存储过程),这是审美趣味的问题。但它更聪明;)