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
并手动检查不区分大小写的唯一性(当然,仍然需要常规索引)。对于如此简单(以及流行的,我认为)的要求,这听起来有点过于复杂。
围绕此限制是否有更简单和/或更优雅的方法?
答案 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
);