【问题标题】:Postgres case-insensitive exclusion constraintPostgres 不区分大小写的排除约束
【发布时间】:2016-12-24 14:15:24
【问题描述】:

我正在尝试创建一个排除约束,以防止重叠的有效时间戳范围,但仅比较具有相同文本值的记录的范围。我希望文本值比较不区分大小写。我可以将= 运算符与文本字段一起使用,但不能与citext 字段一起使用,并且~~* 运算符不可交换。

这是 PostgreSQL 9.5,在数据库上创建了 citextbtree_gist 扩展。

CREATE TABLE customer_product_categories (
  id serial PRIMARY KEY, 
  name text NOT NULL, 
  effective tstzrange DEFAULT '[-infinity,infinity]', 
  EXCLUDE USING gist (name WITH ~~*, effective WITH &&)
)
ERROR: operator ~~*(text,text) is not commutative
CREATE TABLE customer_product_categories (
  id serial PRIMARY KEY, 
  name citext NOT NULL, 
  effective tstzrange DEFAULT '[-infinity,infinity]', 
  EXCLUDE USING gist (name WITH =, effective WITH &&)
)
ERROR: operator =(citext,citext) is not a member of operator family "gist_text_ops"
  • ILIKE 怎么不能交换?
  • 有没有办法做我想做的事,还是我在做傻事?

【问题讨论】:

  • 二元运算是commutative,如果改变操作数的顺序不会改变结果。 ILIKE 不可交换,例如'a' ~~* '%a' 给出 true 但 '%a' ~~* 'a' 是 false。
  • 呃。通配符。谢谢@klin。

标签: postgresql database-design constraints


【解决方案1】:

啊哈!我想到了。我不得不去老学校:

CREATE TABLE "customer_product_categories" (
  "id" serial PRIMARY KEY, 
  "name" text NOT NULL, 
  "effective" tstzrange DEFAULT '[-infinity,infinity]', 
  EXCLUDE USING gist (LOWER("name") WITH =, "effective" WITH &&)
)

【讨论】:

  • 即使您将 name 列保留为 citext,此 EXCLUDE 语句也应该有效。
  • @NikitaZhuk 是的,但我不需要 name 成为 citext,我只是更改类型以尝试使 EXCLUDE 工作。
猜你喜欢
  • 2020-07-22
  • 1970-01-01
  • 2019-07-14
  • 2013-05-30
  • 2020-12-25
  • 2014-03-14
  • 2015-07-05
  • 2016-08-21
相关资源
最近更新 更多