我有一个line_items
表,其中包含以下列:
product_id
variant_id
variant_id
可以为空。
以下是条件:
variant_id
为NULL,则product_id
应该是唯一的。 variant_id
有值,则product_id
和variant_id
的组合应该是唯一的。在PostgreSQL中可以吗?
答案 0 :(得分:26)
在(product_id, variant_id)
上创建UNIQUE
multicolumn index:
CREATE UNIQUE INDEX line_items_prod_var_idx ON line_items (product_id, variant_id);
但是,这会允许(1, NULL)
(product_id, variant_id)
多次输入,因为NULL
值不一致。
为了弥补这一点,另外在product_id
上创建partial UNIQUE
index:
CREATE UNIQUE INDEX line_items_prod_var_null_idx ON line_items (product_id)
WHERE variant_id IS NULL;
这样您就可以输入(1,2)
,(1,3)
和(1, NULL)
,但不能再次输入{{1}},{{1}}和{{1}}。还可以加快查询条件中的一列或两列条件。
最近,关于dba.SE的相关答案,几乎直接适用于您的案例:
答案 1 :(得分:1)
另一种选择是在关键字段中使用表达式。当您提出问题时,这可能不存在,但现在可能对其他遇到此问题的人有帮助。
CREATE UNIQUE INDEX line_items_prod_id_var_id_idx
ON line_items ( product_id, (coalesce(variant_id, 0)) );
当然,这假定您的variant_id
是一个从1开始的自动递增整数。还要注意表达式周围的括号。根据文档,它们是必需的。
http://www.postgresql.org/docs/9.3/static/sql-createindex.html