我试图通过添加一个 PREDICATE
.
在一个案例中,它的工作方式和我预期的一样。在另一种情况下…不是这样
第一个例子,在“cage”上有一个 predicate 。效果很好:
=> CREATE TABLE zoo(
cage INTEGER,
animal TEXT,
EXCLUDE USING GIST (cage WITH =, animal WITH <>) WHERE (cage = 1)
);
CREATE TABLE
=> INSERT INTO zoo VALUES (1, 'zebra');
INSERT 0 1
=> INSERT INTO zoo VALUES (2, 'lion');
INSERT 0 1
=> INSERT INTO zoo VALUES (1, 'lion');
ERROR: conflicting key value violates exclusion constraint "zoo_cage_animal_excl"
DETAIL: Key (cage, animal)=(1, lion) conflicts with existing key (cage, animal)=(1, zebra).
到目前为止,还不错。 (1, lion)
确实与 (1, zebra)
.
第二个例子,用一个谓语“animal”。意外结果:
=> CREATE TABLE zoo(
cage INTEGER,
animal TEXT,
EXCLUDE USING GIST (cage WITH =, animal WITH <>) WHERE (animal = 'lion')
);
CREATE TABLE
=> INSERT INTO zoo VALUES (1, 'zebra');
INSERT 0 1
=> INSERT INTO zoo VALUES (2, 'lion');
INSERT 0 1
=> INSERT INTO zoo VALUES (2, 'zebra');
INSERT 0 1
为什么这最后一句话没有引起矛盾的错误? WHERE (animal = 'lion')
建立部分gist索引。最后一排( (2, zebra)
)应与现有行冲突 (2, lion)
(同一笼子,不同动物: 2 = 2
, zebra <> lion
).
那为什么postgresql允许这一行呢 (2, zebra)
要插入吗?
1条答案
按热度按时间8e2ybdfx1#
自
'zebra' <> 'lion'
,的zebra
部分索引中不包括记录。事实上只是
lion
记录包含在部分索引中。这永远不会是真的
'lion' <> 'lion'
,所以exclude
条件永远不会满足。