Postgresql

numrange 和 boolean 的複合約束

  • December 21, 2017

我有一個像這樣的目前約束:

ALTER TABLE myschema.my_table ADD CONSTRAINT my_constraint EXCLUDE USING gist((<uuidcol>::text) WITH =, numrange(<start>, <end>) WITH &&);

這很好用,但我需要在約束中再添加一件事,它必須只對列為boolean真的行強制執行(我們稱之為它active)。我試過這個:

ALTER TABLE myschema.my_table ADD CONSTRAINT my_constraint EXCLUDE USING gist((<uuidcol>::text) WITH =, numrange(<start>, <end>) WITH && active = TRUE);

這會引發語法錯誤:

ERROR: syntax error at or near "active"
SQL state: 42601

是否可以讓約束也包含該active列?

您可以添加一個WHERE子句以使其成為部分 EXCLUSION約束(創建部分索引來實現它):

ALTER TABLE myschema.my_table ADD CONSTRAINT my_constraint
 EXCLUDE USING gist ((uuidcol::text) WITH =, numrange(start, end) WITH &&)
 WHERE (active);

括號不是可選的。手冊:

謂詞允許您在表的子集上指定排除約束;在內部這會創建一個部分索引。請注意,謂詞周圍需要括號。

順便說一句,在Postgres 10或更高版本中,您可以安裝附加模組btree_gist以添加(除其他外)必要的運算符類以輸入uuidGiST 索引。所以你可以簡化:

ALTER TABLE myschema.my_table ADD CONSTRAINT my_constraint
 EXCLUDE USING gist (uuidcol WITH =, numrange(start, end) WITH &&)
 WHERE (active);

比強制轉換為text. 有關的:

引用自:https://dba.stackexchange.com/questions/193688