我使用PostgreSQL但我正在寻找尽可能标准的SQL答案。
我有下表“docs” -
Column | Type | Modifiers
------------+------------------------+--------------------
id | character varying(32) | not null
version | integer | not null default 1
link_id | character varying(32) |
content | character varying(128) |
Indexes:
"docs_pkey" PRIMARY KEY, btree (id, version)
id和link_id用于彼此之间具有链接关系的文档,因此link_id self引用id。
问题来自版本。现在id不再是主键(也不是唯一的),并且link_id不能将其作为外键引用 -
my_db=# ALTER TABLE docs ADD FOREIGN KEY(link_id) REFERENCES docs (id) ;
ERROR: there is no unique constraint matching given keys for referenced table "docs"
我试图在“if exists”之类的东西上搜索检查约束,但没有找到任何东西。
任何提示都会非常感激。
答案 0 :(得分:4)
我通常喜欢这样:
table document (id, common, columns, current_revision)
table revision (id, doc_id, content, version)
表示该文档与其修订版本具有一对多关系,与当前版本一一对应。
这样,您始终可以通过简单的连接为当前修订选择一个完整的文档,并且您的文档表中只有一个唯一的行可以链接父/子关系,但仍然具有版本。< / p>
答案 1 :(得分:1)
尽可能靠近您的模型,您可以将表格拆分为两个,每个'doc'有一行,另一个''版本'有一行:
您有下表“版本” -
Column | Type | Modifiers
------------+------------------------+--------------------
id | character varying(32) | not null
version | integer | not null default 1
content | character varying(128) |
Indexes:
"versions_pkey" PRIMARY KEY, btree (id, version)
以下表格“docs” -
Column | Type | Modifiers
------------+------------------------+--------------------
id | character varying(32) | not null
link_id | character varying(32) |
Indexes:
"docs_pkey" PRIMARY KEY, btree (id)
现在
my_db=# ALTER TABLE docs ADD FOREIGN KEY(link_id) REFERENCES docs (id) ;
是允许的,您还需要:
my_db=# ALTER TABLE versions ADD FOREIGN KEY(id) REFERENCES docs;
当然,没有什么可以阻止你获得类似于原始表格的“组合”视图:
CREATE VIEW v_docs AS
SELECT id, version, link_id, content from docs join versions using(id);
答案 2 :(得分:0)
根据它是否是您想要的,您只需创建一个包含版本字段的FOREIGN KEY即可。这是指向一个独特行的唯一方法......
如果这不起作用,您可以编写TRIGGER(对于表上的所有UPDATE和INSERT)进行检查。请注意,您还需要在docs表上使用一个触发器,该触发器限制对该表的修改将破坏该键(例如键值本身的DELETE或UPDATE)。
您无法使用CHECK约束执行此操作,因为CHECK约束无法访问另一个表中的数据。