尽管SQL标准允许在有唯一约束的列上存在多个空值,PostgreSQL 也是这样做的 ,但是还有一些数据库系统(例如MS_SQL)在上述情况下只允许有一个空值。当这些数据库系统的用户向PostgreSQL做迁移时,他们希望在PostgreSQL中也能效仿这种处理方式。
这是可以实现的。
首先,展示一下PostgreSQL里默认的方式:
在PostgreSQL中,唯一约束可以防止在一列中出现多个相同的值。这可以通过在一列中创建一个唯一索引来实现。如下图所示:
图1
从图1结果可以看出插入多个相同的非空值时,会提示报错,但是多个空值可以被插入到一个有唯一约束的列上。
如果我们想让唯一列中只允许有一个空值,我们可以创建局部表达式索引,它只索引空值,在唯一索引中使用IS NULL 存储逻辑值true。过程如图2所示:
图2
从上图的结果可以看出,此时在列上只允许存在一个空值。
这种方法也可以被用于创建一个只允许在每个非空复合索引的值上有一个空值对应的约束。过程如图3所示:
图3
从图3的结果来看, 我们创建的uniquetest_idx2这个索引只允许每个col1值有一个NULL的col2值与之对应。所以图3中第三次插入操作会报错。但是从最后两次插入的结果可以看出,插入相同的非空值是可行的,因为我们创建的唯一索引只索引空值。这种方式在某些特定的数据模型中非常有用。
参考文献:
1、PostgreSQL 9.6.7 Documentation
2、PostgreSQL Introduction and Concepts