可延迟,不区分大小写的唯一约束

时间:2013-06-03 21:07:30

标签: postgresql constraints database-indexes

PostgreSQL中是否可以在字符列上创建可延迟的唯一约束,但不区分大小写?

我们假设以下基本表:

CREATE TABLE sample_table ( 
   my_column VARCHAR(100)
);

如果不需要可延迟约束,就像创建具有函数的唯一索引一样简单,例如:

CREATE UNIQUE INDEX my_unique_index ON sample_table(UPPER(my_column));

延迟约束检查需要明确地创建约束,例如:

ALTER TABLE sample_table 
 ADD CONSTRAINT my_unique_constraint UNIQUE(my_column)
 DEFERRABLE INITIALLY IMMEDIATE;

不幸的是,不可能在唯一约束中使用任意函数。

一种可能的解决方法是创建与my_column具有相同内容的其他列,但是大写,在每次更新/插入后通过触发器更新,然后在此人工列上创建可延迟的唯一约束。然而,这听起来像是一个非常难看的黑客。

或者,应该可以使用CREATE CONSTRAINT TRIGGER并手动检查不区分大小写的唯一性(当然,仍然需要常规索引)。对于如此简单(以及流行的,我认为)的要求,这听起来有点过于复杂。

围绕此限制是否有更简单和/或更优雅的方法?

1 个答案:

答案 0 :(得分:13)

您可以使用同名附加模块提供的特殊类型citext来规避限制。引用手册:

  

citext模块提供不区分大小写的字符串类型,   citext。从本质上讲,它在比较值时内部调用较低。   否则,它的行为几乎与text完全相同。

它完全解决了你的情况。每个数据库运行一次:

CREATE EXTENSION citext;

然后你可以:

CREATE TABLE sample_table ( 
   my_column citext
  ,CONSTRAINT my_unique_constraint UNIQUE(my_column)
   DEFERRABLE INITIALLY IMMEDIATE
);