我对多列可能包含 NULL 值的 Postgres 唯一约束有问题。
让我们假设这种情况:
CREATE TEMP TABLE test (
foo TEXT,
bar TEXT,
UNIQUE (foo, bar)
);
INSERT INTO test
VALUES
('foo', NULL),
('foo', NULL),
('foo', 'bar'),
('foo', 'bar')
ON CONFLICT (foo, bar) DO NOTHING;
Run Code Online (Sandbox Code Playgroud)
Insert 将插入 ('foo', 'bar') 一次和 ('foo', NULL) 两次(即使直觉说它应该插入一次)。
在这种情况下,解决方案非常简单。我可以添加唯一索引
CREATE UNIQUE INDEX indx ON test (foo) WHERE bar IS NULL;
Run Code Online (Sandbox Code Playgroud)
但是当有更多列和不同类型(不仅仅是文本)时,问题就开始了。假设我们有 10 列,其中 9 列可以NULL有价值。也许我可以用大量的约束来解决它,但它根本不方便。
有没有更简单的方法来保持这样的行的唯一性?
禁止 NULL 的良好解决方案的替代方法是创建唯一索引。
您只需要一个保证不会出现在您的数据集中的值(在我的示例中'@@'):
CREATE UNIQUE INDEX ON test (
coalesce(foo, '@@'),
coalesce(bar, '@@')
);
Run Code Online (Sandbox Code Playgroud)
顺便说一句,从版本 15 开始,Postgress 支持 SQL 规范 F292 \xc2\xabUnique nulltreatment\xc2\xbb 的可选功能。它允许在唯一约束中控制行为 NULL 值
\ncreate table ... (\n ..........,\n UNIQUE NULLS [NOT] DISTINCT (...)\n);\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1653 次 |
| 最近记录: |