Given the following three columns in a Postgres database: first, second, third; how can I create a constraint such that permutations are unique?
E.g. If (\'foo
For only three columns this unique index using only basic expressions should perform very well. No additional modules like hstore or custom function needed:
CREATE UNIQUE INDEX t_abc_uni_idx ON t (
LEAST(a,b,c)
, GREATEST(LEAST(a,b), LEAST(b,c), LEAST(a,c))
, GREATEST(a,b,c)
);
SQL fiddle
Also needs the least disk space:
SELECT pg_column_size(row(hstore(t))) AS hst_row
,pg_column_size(row(hstore(ARRAY[a,b,c], ARRAY[a,b,c]))) AS hst1
,pg_column_size(row(hstore(ARRAY[a,b,c], ARRAY[null,null,null]))) AS hst2
,pg_column_size(row(ARRAY[a,b,c])) AS arr
,pg_column_size(row(LEAST(a,b,c)
, GREATEST(LEAST(a,b), LEAST(b,c), LEAST(a,c))
, GREATEST(a,b,c))) AS columns
FROM t;
hst_row | hst1 | hst2 | arr | columns
---------+------+------+-----+---------
59 | 59 | 56 | 69 | 30
Numbers are bytes for index row in the example in the fiddle, measured with pg_column_size(). My example uses only single characters, the difference in size is constant.