你的唯一索引,後來編輯了。
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.哪個引用表選擇其外鍵?如何知道所有引用表都會選擇相同的*值? –