0

我使用PostgreSQL,但我在尋找答案的SQL標準越好。(PostgreSQL的)「高級」檢查約束問題

我有以下表「文檔」 -

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自我引用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" 

我試圖尋找檢查約束的東西,如「是否存在「但沒有找到任何東西。

任何尖端將不勝感激。

回答

4

我經常這樣做:

table document (id, common, columns, current_revision) 
table revision (id, doc_id, content, version) 

這意味着該文件有一個一對多的關係與它的修改,和一比一至當前的版本。

這樣,您可以隨時通過簡單連接選擇當前修訂版的完整文檔,並且文檔表中只有一行可以鏈接父/子關係,但仍具有版本控制。

0

取決於它是否是你想要的,你可以簡單地創建一個外鍵,包括版本字段。這是指向一個獨特的行的唯一方式......

如果不工作,你可以寫一個觸發條件(表上的所有更新和插入),使檢查。請注意,您還需要對文檔表的觸發器,制約該表將打破鍵(如關鍵數值本身刪除或更新)的修改。

你不能用一個CHECK約束做到這一點,因爲CHECK約束不能訪問其它表的數據。

1

堅持儘可能靠近你的模型成爲可能,您可以將表格一分爲二,其中一個具有每「DOC」 1排和一個與每個「版本」 1行:

您有以下表「版本」 -

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) 

和下面的表中 「文檔」 -

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); 
+0

謝謝,我想接受你的答案只是發現SO每個問題只有一個接受答案的限制。由於我更傾向於jishi的答案(因爲它更貼近我的應用程序設計),我所能做的就是投票。對不起。 – Jerry 2011-03-07 09:03:01

+0

@ jishi的回答很好 - 我很高興你接受了它。您可能需要了解[推遲](http://www.postgresql.org/docs/8.4/static/sql-createtable.html#AEN58820)約束條件才能按照他的建議實施 – 2011-03-07 09:12:57