你的唯一索引,后来编辑了。
CREATE UNIQUE INDEX feedback_unique_user_subject_and_sale_null
ON feedback(user_id, subject_id, sale_id)
WHERE deleted_at IS NULL
您的独特索引至少有两个副作用,可能会导致您一些麻烦。
- 在其他表中,您不能设置引用“反馈”的外键约束。外键引用要求将某些列的组合声明为
primary key
或unique
。
- 您的唯一索引允许在“deleted_at”时间戳中存在只有不同的行。所以它的可能结束与下面的例子看起来像行。这是否是一个问题取决于应用程序。
例
user_id subject_id sale_id deleted_at
--
1 1 1 2012-01-01 08:00:01.33
1 1 1 2012-01-01 08:00:01.34
1 1 1 2012-01-01 08:00:01.35
PostgreSQL的文档这种指标作为部分索引,你应该需要一段时间谷歌它。其他平台使用不同的术语 - 已过滤的索引就是其中之一。您可以用一对部分索引在一定程度上限制问题。
CREATE UNIQUE INDEX feedback_unique_user_subject_and_sale_null
ON feedback(user_id, subject_id, sale_id)
WHERE deleted_at IS NULL
CREATE UNIQUE INDEX feedback_unique_user_subject_and_sale_not_null
ON feedback(user_id, subject_id, sale_id)
WHERE deleted_at IS NOT NULL
但我看不出有任何理由去这么多的麻烦,特别是考虑到与外键的潜在问题。如果你的餐桌看起来像这样
create table feedback (
feedback_id integer primary key,
user_id ...
subject_id ...
sale_id ...
deleted_at ...
constraint unique_user_subj_sale
unique (user_id, subject_id, sale_id)
);
那么你需要的就是{user_id,subject_id,sale_id}上的唯一约束。您可能会进一步考虑使所有删除使用“deleted_at”列而不是进行硬删除。
我没有发布完整模式,但反馈有一个整数(串行)主键。此外,user_id,sale_id和subject_id被声明为外键(并且具有索引)。我们只需要强制执行唯一性作为附加约束。 – d11wtq
是的,对于唯一索引来说,它允许仅在deleted_at时间戳中有所不同的行是正确的......这是我试图实现的事情;) – d11wtq
如果您有a)串行主键和b)部分如您所描述的那样,并且在我测试过的情况下,其他引用“反馈”的表格仍然存在潜在的问题。假设我在上面的示例中发布的三行具有串行主键1,2和3.哪个引用表选择其外键?如何知道所有引用表都会选择相同的*值? –