sql - 更改表列以添加约束并且列不为空

标签 sql postgresql

我有这个:

alter table supplier
add constraint supplier_unique
unique (supplier_id) where supplier_id is not null;

但是我收到一个错误。

生成的定义应该是:

CREATE UNIQUE INDEX supplier_unique
ON supplier (supplier_id) WHERE (supplier_id IS NOT NULL)

谢谢。

最佳答案

A unique constraint在 PostgreSQL 中没有 WHERE 子句,因此您在“where”处遇到语法错误。在任何情况下,supplier_id is not null 都不需要唯一约束:

In general, a unique constraint is violated when there is more than one row in the table where the values of all of the columns included in the constraint are equal. However, two null values are not considered equal in this comparison. That means even in the presence of a unique constraint it is possible to store duplicate rows that contain a null value in at least one of the constrained columns. This behavior conforms to the SQL standard, ...

所以你只需要这个:

alter table supplier
add constraint supplier_unique
unique (supplier_id);

并且您的唯一约束将被添加,您可以有多行 supplier_id IS NULL,并且您将获得索引作为唯一约束的副作用。

但是,如果您想直接创建索引,您可以create a partial index带有谓词:

When the WHERE clause is present, a partial index is created. A partial index is an index that contains entries for only a portion of a table, usually a portion that is more useful for indexing than the rest of the table.
[...]
Another possible application is to use WHERE with UNIQUE to enforce uniqueness over a subset of a table.

但在 NULL 的情况下,supplier_id IS NOT NULL 的部分索引不会对唯一性做任何事情,因为 PostgreSQL 唯一约束已经允许多个 NULL 值(可能是因为标准并且因为x = NULL 对所有 x 都是假的。

因此,如果您的意图是将唯一性限制为非 NULL 值,那么您不需要部分索引;但是,如果您只想避免索引 NULL 值,那么您可以通过 CREATE INDEX(而不是 ALTER TABLE)来实现。不过,我不知道在索引中保留 NULL 是否会产生明显的影响。

我认为部分混淆(你的和我的)是 UNIQUE 既是约束又是索引。您可以在将 WHERE 创建为索引时包含它,但在将其创建为约束时则不能。这当然是不一致的。

关于sql - 更改表列以添加约束并且列不为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6785731/

相关文章:

php - JQUERY - PHP - MySQL - 添加结果数组,添加更多信息

sql - 使用 FAST_FORWARD 定义游标有什么好处?

php - 2 表选择不正确显示

带 Postgres 9.0 的 Eclipse Helios Java EE

java - 使用 JDBC 将数据添加到 postgreSQL 中的表的正确方法?

sql - SQL 中跨多列的 Like 语句

SQL 表不遵守其唯一约束

postgresql - idx_scan 统计信息是否自动重置(默认)?

ruby-on-rails - Rails 5 使用已在 PostgreSQL 中创建的用户表生成设计

sql - 如何统计组数?