繁体   English   中英

可能使用多列强制唯一性 null

[英]Enforce uniqueness with multiple columns possibly null

如果我有一个表,我想在 INSERT(使用 postgres)期间基于可以是 null 的多个列强制执行唯一性,我是否需要创建多个唯一索引,如下所示?

CREATE TABLE IF NOT EXISTS table_a (
    id SERIAL PRIMARY KEY,
    table_b_id INT REFERENCES table_b(id) ON DELETE CASCADE,
    column_a INT,
    column_b INT,
    column_c INT,
    created_time BIGINT NOT NULL,
    CONSTRAINT "table_a_key" UNIQUE ("table_b_id", "column_a", "column_b", "column_c")
);

column_acolumn_bcolumn_c都可以是 null。我只想要表中每条记录的这些列的唯一组合。

有效插入

table_b_id | column_a | column_b | column_c

 1   |   1   |   2   |  3
 1   |   1   |  null |  null
 1   |  null |   2   |  3
 1   |  null |   2   |  null

但是,如果我尝试插入1 | null | 2 | null 1 | null | 2 | null 又是1 | null | 2 | null ,会冲突不插入。

考虑仅添加CONSTRAINT "table_a_key" UNIQUE...如果所有列都没有任何 null 值,则仅强制执行唯一性。

我是否需要创建所有这些索引以强制执行唯一性? 有没有更好的办法?

CREATE UNIQUE INDEX table_all_null_index ON table_a (table_b_id)
WHERE column_a IS NULL AND column_b IS NULL AND column_c IS NULL;

CREATE UNIQUE INDEX table_a_col_a_index ON table_a (table_b_id, column_a)
WHERE column_a IS NOT NULL AND column_b IS NULL AND column_c IS NULL;

CREATE UNIQUE INDEX table_a_col_b_index ON table_a (table_b_id, column_b)
WHERE column_b IS NOT NULL AND column_a IS NULL AND column_c IS NULL;

CREATE UNIQUE INDEX table_a_col_c_index ON table_a (table_b_id, column_c)
WHERE column_c IS NOT NULL AND column_a IS NULL AND column_b IS NULL;

CREATE UNIQUE INDEX table_a_col_a_b_index ON table_a (table_b_id, column_a, column_b)
WHERE column_a IS NOT NULL AND column_b IS NOT NULL AND column_c IS NULL;

CREATE UNIQUE INDEX table_a_col_a_c_index ON table_a (table_b_id, column_a, column_c)
WHERE column_a IS NOT NULL AND column_c IS NOT NULL AND column_b IS NULL;

CREATE UNIQUE INDEX table_a_col_b_c_index ON table_a (table_b_id, column_b, column_c)
WHERE column_b IS NOT NULL AND column_c IS NOT NULL AND column_a IS NULL;

如果您想允许多个NULL列,那么这就是常规唯一索引或约束的作用:

unique (a, b, c)

如果您不想重复NULL值,那么最简单的方法是将它们默认为一个公共值,例如-1

unique (coalesce(a, -1), coalesce(b, -1), coalesce(c, -1))

这可能并非在所有情况下都有效,但在许多情况下都有效,因为-1 (或其他一些值)未被使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM