我对Postgres Unique约束有很多列可能包含NULL值的问题。
让我们假设这种情况:
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;
插入将插入('foo','bar')一次,并且('foo',NULL)插入两次(即使直觉表明它应该插入一次)。
在这种情况下,解决方案非常简单。我可以添加唯一索引
CREATE UNIQUE INDEX indx ON test (foo) WHERE bar IS NULL;
但是,当列数更多且类型不同(不仅是文本)时,问题就开始了。
假设我们有10列,其中9列可以具有NULL
值。
也许我可以解决很多约束问题,但这根本不方便。
是否有更简单的方法来保持像这样的行的唯一性?
答案 0 :(得分:3)
创建NULL的最佳方法之一是创建唯一索引。
您需要的是一个保证不会出现在数据集中的值(在我的示例'@@'
中):
CREATE UNIQUE INDEX ON test (
coalesce(foo, '@@'),
coalesce(bar, '@@')
);
答案 1 :(得分:2)
您通常可以考虑使用列定义,因为两者均以文本形式表示,您可以让它们为非空值,并提供默认值作为''(空字符串)。这样,您可以确定foo不会被保存两次。另外,在实践中,NULL值也不是那么好,因为它只是表明存在MISSING值。
CREATE TEMP TABLE test (
foo TEXT DEFAULT '' NOT NULL,
bar TEXT DEFAULT '' NOT NULL,
UNIQUE (foo, bar)
);