Postgresql
不同列的唯一約束
我正在嘗試製作一個表格來儲存有向圖的邊緣,但希望避免兩個方向上的重複邊緣。我當然可以把它變成一個方向:
CREATE TABLE edge (parent integer, child integer, UNIQUE(parent, child));
但是我如何確保我也不允許新的 (parent, child) 已經作為 (child, parent) 存在?
任何想法將不勝感激!
使用
GREATEST
和LEAST
本質上,如果我們可以對索引中的列進行排序,我們可以確保重複條目會導致衝突和違反約束,這是因為
sort(5,2) = sort(2,5)
. 因為沒有sort
,所以我們使用greatest
andleast
。CREATE TABLE edge ( parent int, child int ); CREATE UNIQUE INDEX ON edge ( greatest(parent,child), least(parent,child) ); INSERT INTO edge(parent,child) VALUES (42,7), (42,9), (5,7); INSERT INTO edge(parent,child) VALUES (7,42); ERROR: duplicate key value violates unique constraint "edge_greatest_least_idx" DETAIL: Key ((GREATEST(parent, child)), (LEAST(parent, child)))=(42, 7) already exists.