这是我在博士后中遇到的一种奇怪的、不受欢迎的行为:

例如

CREATE TABLE distributors (m_id integer, x_id integer, PRIMARY KEY(m_id, x_id));

m_id列和x_id列强制执行NOT NULL约束,这是我不想要的!

我知道PRIMARY KEY会自动执行UNIQUENOT NULL,但这对于单列主键来说是有意义的.在多列主键表中,唯一性由组合决定.

有什么简单的方法可以避免博士后的这种行为吗

CREATE TABLE distributors (m_id integer, x_id integer);

当然,我没有得到任何NOT NULL条限制.

推荐答案

如果要允许空值,请使用UNIQUE constraint而不是PRIMARY KEY(并添加一个代理PK列,我建议使用serial).这允许列为空:

CREATE TABLE distributor (
   distributor_id serial PRIMARY KEY
 , m_id integer
 , x_id integer
 , UNIQUE(m_id, x_id)
);

Note,但是(per documentation):

对于唯一约束,空值不被视为相等.

在您的情况下,您可以在不违反约束的情况下多次输入(1, NULL)(m_id, x_id).Postgres从不考虑两个空值equal——根据SQL标准中的定义.

如果需要将NULL个值视为等于不允许此类"重复",I see two options:

1.两个部分索引

In addition到上面的UNIQUE约束:

CREATE UNIQUE INDEX dist_m_uni_idx ON distributor (m_id) WHERE x_id IS NULL;
CREATE UNIQUE INDEX dist_x_uni_idx ON distributor (x_id) WHERE m_id IS NULL;

但如果有两个以上的列可以为NULL,那么这个问题很快就会失控.见:

2. A multi-column UNIQUE index on expressions

而不是唯一的约束.我们需要一个在相关列中永远不存在的自由默认值,比如-1.添加CHECK个限制以禁止它:

CREATE TABLE distributor (
   distributor serial PRIMARY KEY
 , m_id integer
 , x_id integer
 , CHECK (m_id <> -1)
 , CHECK (x_id <> -1)
);
CREATE UNIQUE INDEX distributor_uni_idx ON distributor (COALESCE(m_id, -1)
                                                      , COALESCE(x_id, -1))

How certain RDBMS handle things并不总是正确行为的有用指标.Postgres manual hints at this人:

这意味着即使存在唯一的约束,也有可能

我的.

Postgresql相关问答推荐

如何获取实例化视图的列级权限?

在Docker Compose中获取CSV文件数据?

使用 pgx 扫描范围类型

使用来自 docker 图像的 postgres 设置 Keycloak 21

Power BI + Postgres:只读用户

如何在postgresql中按时间查询

无法从外部连接到在 AWS EC2 实例上运行的 Postgres

在 postgresql 中查找表的所有依赖项

如何在 PostgreSQL 中使用正则表达式删除单词之间的所有特殊字符和多余空格

PostgreSQL - 继承表的常见自动增量

Spring:如何在 PostgreSQL 中使用 KeyHolder

Postgres中的GROUP BY - JSON数据类型不相等?

在psql中,为什么有些命令没有效果?

?(问号)运算符在 Rails 中查询 Postgresql JSONB 类型

plpgsql:使用 2 个 OUT 参数调用函数

错误:must be owner of language plpgsql

Postgresql 中的 NOT EXISTS 子句

具有 DEFAULT NULL 的 MySQL 列 ?

如何在postgres中将整数分钟转换为间隔

提高查询速度:simple SELECT in big postgres table