0

我的表中有两个字段,如果它们(tat 和 dim)相等,我将丢弃它们,即

id| tat | dim | visible
1 | 11  | 22  | true
2 | 11  | 22  | false

1这被认为不是 ids和的有效条目2。因为我想允许dim每个tat. 所以我有一个脚本为我清理了这些重复项,然后我在这个表上添加了索引以防止这种情况发生:

CREATE UNIQUE INDEX dim_tat_idx
ON predictions (tat, dim);

正如这个答案中很好地解释的那样:

https://stackoverflow.com/a/8918141/169277

现在在这种情况下更进一步

This way you can enter (1,2), (1,3) and (1, NULL)
but neither of them a second time

我将创建什么类型的索引,或者我将在数据库级别使用什么其他机制来允许输入1, NULL组合但防止(1,2)多次输入(1,3)

4

1 回答 1

2

这似乎是一种误解。

您对我的回答的引用有点误导,因为它仅适用于您还创建附加部分索引,如那里所述:
How to add a conditional unique index on PostgreSQL

如果您不添加第二个索引(就像您没有添加一样),似乎已经有了解决方案。仅使用多列唯一索引,您可以输入(1, NULL)多次,但(1,2)(1,3)只能输入一次。

空字符串

如果您错误地考虑了空字符串 ( '')(对于字符类型)而不是NULL值:它们的处理方式与任何其他值一样。您可以使用多列、部分功能的唯一索引表达式上的索引)来处理这种情况:

CREATE UNIQUE INDEX predictions _dim_tat_uni_idx
ON predictions (tat, NULLIF(dim, ''));

这样你就可以进入(1, 'a')(1, 'b')只有一次。
但是(1, NULL)(1, '')多次。

副作用

该索引仍将完全支持对第一列 ( tat) 的普通查询。
但是两列上的查询都必须匹配表达式才能充分利用潜力。这会更快,即使它似乎没有意义:

SELECT * FROM predictions
WHERE  tat = 1
AND    NULLIF(dim, '') = 'foo';

.. 比这个:

SELECT * FROM predictions
WHERE  tat = 1
AND    dim = 'foo';

..因为第一个查询可以使用两个索引列。结果将是相同的(搜索''or时除外NULL)。dba.SE 上此相关答案中的详细信息

于 2013-09-20T14:04:56.647 回答