Postgres-具有多个列和NULL值的唯一约束

时间:2020-02-13 11:53:37

标签: postgresql

我对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值。 也许我可以解决很多约束问题,但这根本不方便。

是否有更简单的方法来保持像这样的行的唯一性?

2 个答案:

答案 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)
);
相关问题