微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用可能为空的多列强制唯一性

如何解决使用可能为空的多列强制唯一性

如果我有一个表,我想根据插入期间可以为空的多个列来强制执行唯一性(使用 postgres),我是否需要创建多个唯一索引,如下所示?

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,它会发生冲突并且不会插入。

认为仅添加 CONSTRAINT "table_a_key" UNIQUE... 仅在所有列都没有任何空值的情况下强制唯一性。

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

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_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,coalesce(c,-1))

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?