我想在PostgreSQL中设计包含两个表彼此交叉引用的模式。但是,如果不添加冗余UNIQUE
约束(请参阅下面的代码)我收到错误:ERROR: there is no unique constraint matching given keys for referenced table "nodes"
。为什么需要这个UNIQUE约束?
所以我的问题是:为什么这个额外的唯一约束是必要的,有没有办法避免它的创建? (以减少运行时间开销)。
CREATE TABLE objects (
object_id serial NOT NULL PRIMARY KEY,
root_node integer
);
CREATE TABLE nodes (
node_id integer NOT NULL PRIMARY KEY,
object_id integer REFERENCES objects
);
ALTER TABLE objects
ADD CONSTRAINT root_node_fkey
FOREIGN KEY (root_node) REFERENCES nodes(node_id);
-- Why this constaint is needed? Since node_id is primary key this combination should be already UNIQUE
ALTER TABLE nodes ADD CONSTRAINT node_id_object_id_unique UNIQUE (node_id, object_id);
ALTER TABLE objects
ADD CONSTRAINT objects_nodes_fkey
FOREIGN KEY (object_id, root_node)
REFERENCES nodes (object_id, node_id);
Bill,是否有一种方法来强制执行类似的约束(要求'root_node'来自同一个'object')以不同的(可能更有效的方式)?或者这是最好的方法? – Yatima
@Yatima,考虑到你已经在对象表中冗余地存储root_node了。我的意思是,如果你引用了object_id,那么你就可以知道哪个root_node与该节点的object_id相关联。 –
我不确定我是否遵循...这个想法是,每个对象都会有与其关联的'nodes'集合,并且只有一个节点可能是根节点。或者你看到更好的方法来做到这一点?我试着在这里问这个问题:http://stackoverflow.com/questions/40985510/what-is-best-design-for-one-to-many-relationship-with-back-references-to-each-ot但它看起来目前的方案是迄今为止最好的方法。顺便说一句,谢谢你写反面书,我学到了很多东西。 – Yatima