PostgreSQL独特的价值acreoss多列
我有PostgreSQL表
id ColA ColB ------------------ 1 'a' 'b' 2 'c' 'd' 我想让ColA和ColB中的值在两列中都是唯一的,即任何这些插入都是禁止的: INSERT INTO table (ColA,ColB) values('a','e'); INSERT INTO table (ColA,ColB) values('z','a'); INSERT INTO table (ColA,ColB) values('d','g'); 并允许任何这些插入: INSERT INTO table (ColA,ColB) values('l','k'); 所以 CONSTRAINT unique_name UNIQUE (ColA,ColB) 不适合,因为它将允许以前的4个插入中的任何一个.
遗憾的是,使用简单独特的约束/索引(如果可以用它们解决它)就无法轻易解决这个问题.
你需要的是exclusion constraint:基于碰撞之类的东西排除某些行的能力.唯一约束只是特定的排除约束(它们基于相等冲突). 所以,从理论上讲,你只需要排除每个row1,其中已经有一个row2,这个表达式为真:ARRAY [row1.cola,row1.colb]&& ARRAY [row2.cola,row2.colb] 该索引可以完成这项工作(目前只有gist索引支持排除约束): ALTER TABLE table_name ADD CONSTRAINT table_name_exclusion EXCLUDE USING gist ((ARRAY[cola,colb]) WITH &&); 但不幸的是,数组没有默认的运算符类(使用gist).有一个 如果你真的想要解决这个问题,你总是可以滥用 -- there is no built-in type for text ranges neither,-- but it can can be created fairly easily: CREATE TYPE textrange AS RANGE ( SUBTYPE = text ); ALTER TABLE table_name ADD CONSTRAINT table_name_exclusion EXCLUDE USING gist ((textrange(least(cola,colb),greatest(cola,colb))) WITH -|-); -- the exclusion constraint above does not handle all situations: ALTER TABLE table_name ADD CONSTRAINT table_name_check CHECK (cola is distinct from colb); -- without this,empty ranges could be created,-- which are not adjacent to any other range CREATE UNIQUE INDEX table_name_unique ON table_name ((ARRAY[least(cola,colb)])); -- without this,duplicated rows could be created,-- because ranges are not adjacent to themselves …但我担心,通过一点点数据库重构可以更轻松地解决原始问题;这给我们带来了一个问题:你想用什么问题解决这个问题? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |