如何使用可为空的列创建复合 UNIQUE 约束?

How to create composite UNIQUE constraint with nullable columns?

假设我有一个 table,其中包含多个列 [a, b, c, d],它们都可以为空。这个 table 是用 Typeorm 管理的。 我想在 [a, b, c] 上创建一个唯一约束。但是,如果这些列之一为 NULL,则此约束不起作用。例如,我可以插入 [a=0, b= 1, c=NULL, d=0][a=0, b= 1, c=NULL, d=1],其中 d 具有不同的值。

使用原始 SQL,我可以设置多个部分约束 (Create unique constraint with null columns) 但是,在我的例子中,唯一约束是在 10 列上。为每一种可能的组合设置约束似乎很荒谬...

我也可以创建一种哈希函数,但这种方法对我来说似乎不合适?

Typeorm 是否提供针对此类情况的解决方案?

如果您有永远不会出现在这些列中的值,您可以在索引中使用它们作为替代:

create unique index on the_table (coalesce(a,-1), coalesce(b, -1), coalesce(c, -1));

这样 NULL 值在索引中被视为相同,而不需要在 table 中使用它们。

如果这些列是 numericfloat(而不是 integerbigint),使用 '-Infinity' 可能是更好的替换值。


不过这有一个缺点:

但是,除非您还使用 coalesce() 表达式,否则该索引将不可用于对这些列的查询。因此,使用上述索引,查询如下:

select *
from the_table
where a = 10
  and b = 100;

不会使用索引。您需要使用与索引本身相同的表达式:

select *
from the_table
where coalesce(a, -1) = 10
  and coalesce(b, -1) = 100;