具有 Null 值的 PostgreSQL 约束
PostgreSQL constraint with Null Value
我有这个table。我需要使 [seller_id、product_id、sold_out_date] 的组合独一无二,但问题是
CONSTRAINT u_product UNIQUE (seller_id, product_id, sold_out_date)
由于 NULL 值,无法停止重复行。将其设为主键也不起作用,因为它不能为 NULL。
之所以需要它是唯一的,是因为当产品售罄时,将输入 sold_out_date
,当产品有货时,我需要创建一个新行,所以组合这三个必须是唯一的。
创建此约束后,我想执行如下查询:
INSERT INTO my_table
(seller_id, product_id, sold_out_date)
VALUES (1, 'A', NULL)
ON CONFLICT DO NOTHING;
而是像这样添加一个唯一索引,你会没事的
create unique index ux_indx on my_table(seller_id, product_id, coalesce(sold_out_date,'1990-01-01'));
db<>fiddle here
如果您需要更新冲突:
INSERT INTO my_table
VALUES (1, 'A', NULL)
ON CONFLICT (seller_id, product_id, coalesce(sold_out_date,'1990-01-01')) DO UPDATE set sold_out_date = '2020-01-10';
尝试使用 EXCLUDE
ALTER TABLE my_table
ADD CONSTRAINT excl1 EXCLUDE USING btree (
seller_id ASC NULLS LAST WITH =,
product_id ASC NULLS LAST WITH =,
COALESCE(sold_out_date, '2020-01-01') ASC NULLS LAST WITH =);
和ON CONFLICT DO NOTHING
会起作用
在数据库中使用基于散列的 id 是一种常见的做法,因此您可以在这三个字段的组合上创建散列并将其用作 id,然后在该 id 字段上创建主键约束,例如
INSERT INTO my_table
(seller_id, product_id, sold_out_date, id)
VALUES (1, 'A', null, encode(digest(concat('1','A',null) , 'sha1'),'base64'))
ON CONFLICT DO NOTHING;
您的数据库中必须存在 pgcrypto 扩展,如果不使用:
create extension pgcrypto;
我有这个table。我需要使 [seller_id、product_id、sold_out_date] 的组合独一无二,但问题是
CONSTRAINT u_product UNIQUE (seller_id, product_id, sold_out_date)
由于 NULL 值,无法停止重复行。将其设为主键也不起作用,因为它不能为 NULL。
之所以需要它是唯一的,是因为当产品售罄时,将输入 sold_out_date
,当产品有货时,我需要创建一个新行,所以组合这三个必须是唯一的。
创建此约束后,我想执行如下查询:
INSERT INTO my_table
(seller_id, product_id, sold_out_date)
VALUES (1, 'A', NULL)
ON CONFLICT DO NOTHING;
而是像这样添加一个唯一索引,你会没事的
create unique index ux_indx on my_table(seller_id, product_id, coalesce(sold_out_date,'1990-01-01'));
db<>fiddle here
如果您需要更新冲突:
INSERT INTO my_table
VALUES (1, 'A', NULL)
ON CONFLICT (seller_id, product_id, coalesce(sold_out_date,'1990-01-01')) DO UPDATE set sold_out_date = '2020-01-10';
尝试使用 EXCLUDE
ALTER TABLE my_table
ADD CONSTRAINT excl1 EXCLUDE USING btree (
seller_id ASC NULLS LAST WITH =,
product_id ASC NULLS LAST WITH =,
COALESCE(sold_out_date, '2020-01-01') ASC NULLS LAST WITH =);
和ON CONFLICT DO NOTHING
会起作用
在数据库中使用基于散列的 id 是一种常见的做法,因此您可以在这三个字段的组合上创建散列并将其用作 id,然后在该 id 字段上创建主键约束,例如
INSERT INTO my_table
(seller_id, product_id, sold_out_date, id)
VALUES (1, 'A', null, encode(digest(concat('1','A',null) , 'sha1'),'base64'))
ON CONFLICT DO NOTHING;
您的数据库中必须存在 pgcrypto 扩展,如果不使用:
create extension pgcrypto;