sql - 一对多表确保两个表都来自链上的同一父表

标签 sql postgresql data-structures relationship

我的 Postgres 9.2 架构中有以下表格:

TABLE Root (
     RootId PRIMARY KEY,
     ...
)

注意: ... 表示表中还有其他列

Root 与两个表具有一对多关系:NodeOneNodeTwo

TABLE NodeOne (
    NodeOneName,
    NodeOneCode,
    RootId REFERENCES Root(RootId),
    ...,
    PRIMARY KEY (NodeOneName, NodeOneCode)
)

TABLE NodeTwo (
    NodeTwoName,
    NodeTwoCode,
    RootId REFERENCES Root(RootId),
    ...,
    PRIMARY KEY (NodeTwoName, NodeTwoCode)
)

NodeTwo 与表 NodeTwoLeaf

是一对多的关系
TABLE NodeTwoLeaf (
    NodeTwoLeafId PRIMARY KEY,
    NodeTwoName,
    NodeTwoCode,
    ...,
    CONSTRAINT FOREIGN KEY(NodeTwoName, NodeTwoCode)
        REFERENCES NodeTwo(NodeTwoName, NodeTwoCode)
)

注意:要知道给定 NodeTwoLeaf 所属的 RootId,必须JOIN 备份到 NodeTwo 使用 FOREIGN KEY(NodeTwoName, NodeTwoCode)

问题如下:NodeTwoLeafNodeOne是一对多的关系

NodeTwoLeaf_X_NodeOne (
    NodeTwoLeafId REFERENCES NodeTwoLeaf(NodeTwoLeafId),
    NodeOneName,
    NodeOneCode,
    ...,
    PRIMARY KEY (NodeTwoLeafId, NodeOneName, NodeOneCode),
    CONSTRAINT FOREIGN KEY(NodeOneName, NodeOneCode)
        REFERENCES NodeOne(NodeOneName, NodeOneCode)
)

如何在 NodeTwoLeaf_X_NodeTwo 中确保每个 (NodeTwoLeaf, NodeOne) 对都有一个共同的 Root,即相同的 RootId? (最好只使用约束,即不使用触发器)

最佳答案

使用复合键。而不是:

TABLE NodeTwoLeaf (
    NodeTwoLeafId PRIMARY KEY,
    NodeTwoName,
    NodeTwoCode,
    ...,
    CONSTRAINT FOREIGN KEY(NodeTwoName, NodeTwoCode)
        REFERENCES NodeTwo(NodeTwoName, NodeTwoCode)
);

改为:

TABLE NodeTwoLeaf (
    NodeTwoLeafId PRIMARY KEY,
    RootID int,
    NodeTwoName,
    NodeTwoCode,
    ...,
    CONSTRAINT FOREIGN KEY(NodeTwoName, NodeTwoCode, RootId)
        REFERENCES NodeTwo(NodeTwoName, NodeTwoCode, RootId)
);

请注意,您必须在 NodeTwo 上为外键添加一个额外的 UNIQUE 索引:

ALTER TABLE NodeTwo ADD CONSTRAINT UNIQUE(NodeTwoName, NodeTwoCode, RootId);

关于sql - 一对多表确保两个表都来自链上的同一父表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18979577/

相关文章:

sql - 您可以在 PostgreSQL 存储过程 IF 子句中执行 WHERE 子句吗?

postgresql - 如何在使用递归选择后代的 Postgres 查询中打印深度级别?

java - 如何在不依赖方法的情况下删除链表末尾的节点?

sql - 有子句与子查询

MySQL:从select distinct中选择所有行

linux - Postgres 按时间戳排序适用于 mac 但不适用于 linux

c++ - 高效搜索的数据结构

c - 迭代中序遍历

mysql - SQL 选择类似字符串包含 ' '

sql - 检测存储过程中的脏读