Postgres 对索引的唯一约束不起作用
Postgres unique constraint on index does not work
很简单table
CREATE TABLE collectionmaster
(
id character varying(32) NOT NULL,
version integer,
publisherid character varying(12),
title character varying(1024),
subtitle character varying(1024),
type character varying(255) NOT NULL,
CONSTRAINT collectionmaster_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
CREATE INDEX idx_coll_title
ON collectionmaster
USING btree
(title COLLATE pg_catalog."default");
我尝试通过唯一索引添加唯一检查
CREATE UNIQUE INDEX idx_uni_coll_title
ON collectionmaster
USING btree
(publisherid COLLATE pg_catalog."default", title COLLATE pg_catalog."default", (COALESCE(subtitle, 'no_sub'::character varying)) COLLATE pg_catalog."default");
或通过唯一约束
ALTER TABLE collectionmaster
ADD CONSTRAINT uni_coll_title UNIQUE(publisherid, title, subtitle);
意外地拦截在多个线程中执行的 java 服务(spring-jpa on hibernate)的多次创建。但奇怪的是,索引和约束都没有按预期工作。根据单独事务中的约束或索引,八个线程添加了八条记录,这些记录不是唯一的,但没有抛出唯一违规,并且所有记录都被插入到 table 中。并且 none 的值是空的,就像这里其他问题中的问题一样。
约束没有被延迟,索引作为约束有效。
Postgres 版本是 9.2.
我这里一窍不通
编辑:这些是从 pgAdmin 中提取的 table 中的查询结果(这里很难格式化):
"id";"version";"publisherid";"title";"subtitle";"type"
"53b3df625baf40bf885b48daa366fbc8";1;"5109138";"Titel";"Untertitel";"set"
"2673ef9a33f84289995d6f7288f07b46";1;"5109138";"Titel";"Untertitel";"set"
"ef7c385205034fdc89fe39e3eca48408";1;"5109138";"Titel";"Untertitel";"set"
"527922f2f3464f91826dbae2e2b67caf";1;"5109138";"Titel";"Untertitel";"set"
"794638a725324319852d10b828257df7";1;"5109138";"Titel";"Untertitel";"set"
"dbe2201058974d63a2107131f0080233";1;"5109138";"Titel";"Untertitel";"set"
"cbb77c7c1adb415db006853a6f6244ac";1;"5109138";"Titel";"Untertitel";"set"
"0b6606fe015040fbbc85444361ab414c";1;"5109138";"Titel";"Untertitel";"set"
连这些我都能执行
insert into collectionmaster(id, version, publisherid, title, subtitle, type) values('aaa',1,'5109138','Titel','Untertitel','set')
没有违反约束。我也不敢相信,但这就是问题所在...
确保您的 spring-jpa 配置 spring.jpa.hibernate.ddl-auto
未设置为 create-drop
。
这样,hibernate 将始终删除并重新创建您的整个模式,其中不包含您的自定义唯一约束,也不包含您的索引。
很简单table
CREATE TABLE collectionmaster
(
id character varying(32) NOT NULL,
version integer,
publisherid character varying(12),
title character varying(1024),
subtitle character varying(1024),
type character varying(255) NOT NULL,
CONSTRAINT collectionmaster_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
CREATE INDEX idx_coll_title
ON collectionmaster
USING btree
(title COLLATE pg_catalog."default");
我尝试通过唯一索引添加唯一检查
CREATE UNIQUE INDEX idx_uni_coll_title
ON collectionmaster
USING btree
(publisherid COLLATE pg_catalog."default", title COLLATE pg_catalog."default", (COALESCE(subtitle, 'no_sub'::character varying)) COLLATE pg_catalog."default");
或通过唯一约束
ALTER TABLE collectionmaster
ADD CONSTRAINT uni_coll_title UNIQUE(publisherid, title, subtitle);
意外地拦截在多个线程中执行的 java 服务(spring-jpa on hibernate)的多次创建。但奇怪的是,索引和约束都没有按预期工作。根据单独事务中的约束或索引,八个线程添加了八条记录,这些记录不是唯一的,但没有抛出唯一违规,并且所有记录都被插入到 table 中。并且 none 的值是空的,就像这里其他问题中的问题一样。 约束没有被延迟,索引作为约束有效。 Postgres 版本是 9.2.
我这里一窍不通
编辑:这些是从 pgAdmin 中提取的 table 中的查询结果(这里很难格式化):
"id";"version";"publisherid";"title";"subtitle";"type"
"53b3df625baf40bf885b48daa366fbc8";1;"5109138";"Titel";"Untertitel";"set"
"2673ef9a33f84289995d6f7288f07b46";1;"5109138";"Titel";"Untertitel";"set"
"ef7c385205034fdc89fe39e3eca48408";1;"5109138";"Titel";"Untertitel";"set"
"527922f2f3464f91826dbae2e2b67caf";1;"5109138";"Titel";"Untertitel";"set"
"794638a725324319852d10b828257df7";1;"5109138";"Titel";"Untertitel";"set"
"dbe2201058974d63a2107131f0080233";1;"5109138";"Titel";"Untertitel";"set"
"cbb77c7c1adb415db006853a6f6244ac";1;"5109138";"Titel";"Untertitel";"set"
"0b6606fe015040fbbc85444361ab414c";1;"5109138";"Titel";"Untertitel";"set"
连这些我都能执行
insert into collectionmaster(id, version, publisherid, title, subtitle, type) values('aaa',1,'5109138','Titel','Untertitel','set')
没有违反约束。我也不敢相信,但这就是问题所在...
确保您的 spring-jpa 配置 spring.jpa.hibernate.ddl-auto
未设置为 create-drop
。
这样,hibernate 将始终删除并重新创建您的整个模式,其中不包含您的自定义唯一约束,也不包含您的索引。