在PostgreSQL中检查唯一约束冲突时不允许

在PostgreSQL中检查唯一约束冲突时不允许,postgresql,unaccent,Postgresql,Unaccent,我们在一个表上有一个唯一的约束,以防止我们的城市名称和州id组合被复制。我们发现的问题是,口音绕过了这一点 示例: “魁北克”蒙特勒阿尔 和 “蒙特利尔”“魁北克” 我们需要一种方法来运行unique约束uncent(),最好将其包装在LOWER()中,以便更好地度量。这可能吗?您可以在表达式上创建唯一的索引,请参阅Postgres手册: 所以在你的情况下可能是 在my_表上创建唯一索引idx_foo(uncent(较低(城市名称)),state_id)您可以创建不可变版本的uncent: C

我们在一个表上有一个
唯一的
约束,以防止我们的
城市名称
州id
组合被复制。我们发现的问题是,口音绕过了这一点

示例:
“魁北克”蒙特勒阿尔
和
“蒙特利尔”“魁北克”


我们需要一种方法来运行unique约束
uncent()
,最好将其包装在
LOWER()
中,以便更好地度量。这可能吗?

您可以在表达式上创建唯一的索引,请参阅Postgres手册:

所以在你的情况下可能是


在my_表上创建唯一索引idx_foo(uncent(较低(城市名称)),state_id)
您可以创建不可变版本的
uncent

CREATE FUNCTION noaccent(text) RETURNS text
   LANGUAGE sql IMMUTABLE STRICT AS
'SELECT unaccent(lower($1))';
并在列上的唯一索引中使用它


另一种方法是使用
BEGORE INSERT或UPDATE
触发器,该触发器用未注释的值填充新列,并对该列施加唯一约束。

还应注意,任何希望使用该索引的查询也必须在
uncent(较低(城市名称))上进行过滤
而不仅仅是
city\u name
如何使用支票而不是索引?值得注意的是,这不会是一个很重的写表,因为它的性质主要是读取的。不只是不正确的稳定,这意味着它不能直接用于索引函数?可能最简单的方法是有两列:第一列只显示包含像
“Montréal”
这样的值,第二列用于检查、索引、搜索、过滤等,其中包含像
“montreal”
这样的值。。。