Sql 一对多表,确保两个表都来自链上的同一父级

Sql 一对多表,确保两个表都来自链上的同一父级,sql,postgresql,data-structures,relationship,Sql,Postgresql,Data Structures,Relationship,我的Postgres 9.2模式中有以下表格: TABLE Root ( RootId PRIMARY KEY, ... ) 注:。。。表示表中还有其他列 根目录与两个表有一对多关系:NodeOne和nodewo nodewo与表nodewoleaf具有一对多关系 注意:要知道给定的nodewoleaf所属的RootId,必须使用外键nodewoname、nodewocode重新连接到nodewo 问题如下:NodeWoleAF与NodeOne有一对多关系 我如何确保在No

我的Postgres 9.2模式中有以下表格:

TABLE Root (
     RootId PRIMARY KEY,
     ...
)
注:。。。表示表中还有其他列

根目录与两个表有一对多关系:NodeOne和nodewo

nodewo与表nodewoleaf具有一对多关系

注意:要知道给定的nodewoleaf所属的RootId,必须使用外键nodewoname、nodewocode重新连接到nodewo

问题如下:NodeWoleAF与NodeOne有一对多关系


我如何确保在NodeTwoLeaf_X_NodeTwo中,每个NodeTwoLeaf、NodeOne对都有一个公共根,即相同的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)
);
注意:您必须在nodewo上为外键添加一个额外的唯一索引:

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

@乔普,这里没有NodeTwoId。NodeVo中的PK由NodeVoName和NodeVoCode组成。您应该尝试使用表实现树结构。太错了,嘿,雅库布卡尼亚。从8.4开始,Postgres就可以使用递归很好地处理树结构。为什么你说这是错的?因为节点应该存储在行中而不是单独的表中。@JakubKania啊。。。我的错。Root、NodeOne等只是名称,它们不是实际的树节点。例如,Root可以是一所学校,NodeOne可以是一门课程,nodewo可以是一个资格证书,等等。我只是想让这个问题更一般化。这就解决了它!我为自己没看到它而自责。谢谢
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)
);
ALTER TABLE NodeTwo ADD CONSTRAINT UNIQUE(NodeTwoName, NodeTwoCode, RootId);