【问题标题】:Partial unique index in postgres in relation to other rowspostgres 中相对于其他行的部分唯一索引
【发布时间】:2019-10-06 06:58:48
【问题描述】:

我一般都知道 PostgreSQL 中的部分唯一索引,但我需要设置一个不适合我认为的部分索引领域的约束。或者也许有某种方式来表达它。

小例子

CREATE TABLE table (user INT, type INT, flag BOOL, text VARCHAR (50));

要求是:

  1. user 可以有多行相同的type,但前提是flag 为假。

  2. 如果user 的行中特定的typeflag 设置为true,则usertype 不能有其他行。

因此,例如,如果该表具有以下行:

| user | type | flag  | text |
| 1    | 1    | false | foo  |
| 1    | 1    | false | bar  |

那么我们不能插入 (1, 1, true, 'whatever')


如果表格有:

| user | type | flag | text |
| 1    | 1    | true | foo  |

我们不能插入 (1, 1, false, 'bar') 也不能插入 (1, 1, true, 'baz')


有没有办法在 PostgreSQL 中表达这样的约束?

【问题讨论】:

    标签: postgresql unique-constraint


    【解决方案1】:

    您需要partial unique indexexclusion constraint 的组合。不幸的是,没有可用于排除约束中的布尔列的运算符系列,因此可以使用整数列代替。 btree_gist extension 是模拟整数列的 gist 索引所必需的。

    create extension if not exists btree_gist;
    

    表定义(标识符稍作修改):

    drop table if exists my_table;
    create table my_table (
        user_id integer,
        type_id integer, 
        flag integer check (flag in (0, 1)),
        text varchar (50),
        exclude using gist (user_id with =, type_id with =, flag with <>)
    );
    
    create unique index on my_table (user_id, type_id) where flag = 1;
    

    示例性插入:

    insert into my_table
    values
    (1, 1, 0, 'foo'),
    (1, 1, 0, 'bar'),
    (2, 2, 1, 'foo');
    
    INSERT 0 3
    
    insert into my_table
    values
    (1, 1, 1, 'whatever');
    
    ERROR:  conflicting key value violates exclusion constraint "my_table_user_id_type_id_flag_excl"
    DETAIL:  Key (user_id, type_id, flag)=(1, 1, 1) conflicts with existing key (user_id, type_id, flag)=(1, 1, 0).
    
    insert into my_table
    values
    (2, 2, 0, 'whatever');
    
    ERROR:  conflicting key value violates exclusion constraint "my_table_user_id_type_id_flag_excl"
    DETAIL:  Key (user_id, type_id, flag)=(2, 2, 0) conflicts with existing key (user_id, type_id, flag)=(2, 2, 1).
    
    insert into my_table
    values
    (2, 2, 1, 'whatever');
    
    ERROR:  duplicate key value violates unique constraint "my_table_user_id_type_id_idx"
    DETAIL:  Key (user_id, type_id)=(2, 2) already exists.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-14
      • 2019-10-02
      • 1970-01-01
      • 2012-09-06
      • 1970-01-01
      • 2019-05-05
      相关资源
      最近更新 更多