【问题标题】:How to add a conditional unique index on PostgreSQL如何在 PostgreSQL 上添加条件唯一索引
【发布时间】:2012-01-18 20:40:26
【问题描述】:

我有一个包含以下列的line_items 表:

product_id
variant_id

variant_id 可以为空。

条件如下:

  • 如果variant_id 为NULL,那么product_id 应该是唯一的。
  • 如果variant_id 有一个值,那么product_idvariant_id 的组合应该是唯一的。

在 PostgreSQL 中可以吗?

【问题讨论】:

    标签: postgresql null indexing


    【解决方案1】:

    (product_id, variant_id) 上创建UNIQUE multicolumn index

    CREATE UNIQUE INDEX line_items_prod_var_idx ON line_items (product_id, variant_id);
    

    但是,这将允许在 (product_id, variant_id) 中输入多个 (1, NULL),因为 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),但它们都不能输入第二次。还可以加快对一列或两列条件的查询。

    dba.SE 上最近的相关答案,几乎直接适用于您的案例:

    【讨论】:

      【解决方案2】:

      另一种选择是在关键字段中使用表达式。当您提出这个问题时,这可能不存在,但可能对现在遇到此问题的其他人有所帮助。

      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

      【讨论】:

        【解决方案3】:

        以下应该也可以 -

        CREATE UNIQUE INDEX line_items_prod_var_idx ON line_items (product_id, coalesce(variant_id,'default'));
        

        有关合并的更多信息 - https://www.postgresql.org/docs/8.1/functions-conditional.html

        【讨论】:

          猜你喜欢
          • 2018-02-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-04
          • 2018-12-02
          • 2020-10-01
          • 2015-04-24
          相关资源
          最近更新 更多