我有一个line_items
表列如下:如何添加一个有条件的唯一索引PostgreSQL的
product_id
variant_id
variant_id
为空。
这里的条件:
- 如果
variant_id
为NULL,则product_id
应该是唯一的。 - 如果
variant_id
有一个值,则product_id
和variant_id
的组合应该是唯一的。
PostgreSQL中可能吗?
我有一个line_items
表列如下:如何添加一个有条件的唯一索引PostgreSQL的
product_id
variant_id
variant_id
为空。
这里的条件:
variant_id
为NULL,则product_id
应该是唯一的。variant_id
有一个值,则product_id
和variant_id
的组合应该是唯一的。PostgreSQL中可能吗?
创建UNIQUE multicolumn INDEX上(product_id, variant_id)
:
CREATE UNIQUE INDEX line_items_prod_id_var_id_idx
ON line_items (product_id, variant_id);
然而,这将允许(1, NULL)
多个条目(product_id, variant_id)
因为NULL
值不被认为是相同的。
为了弥补的是,另外创建一个partial UNIQUE INDEX上product_id
:
CREATE UNIQUE INDEX line_items_prod_id_var_null_idx
ON line_items (product_id)
WHERE variant_id IS NULL;
这样你就可以进入(1,2)
,(1,3)
和(1, NULL)
,但他们都没有第二次。还可以加快一列或两列的查询条件。
这answer on dba.SE我最近写的是非常相似,几乎直接适用于你的问题。
另一种选择是在关键字段中使用表达式。当你问这个问题时,这可能还没有出现,但对现在遇到的其他人可能会有所帮助。
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