我認爲這會有點深奧,但是想要拋出這種情況,以防萬一有人試過這樣的事情,或者如果有人已經嘗試過,發現它是不可能的。使用基於函數的索引推遲唯一約束?
我們有一張表,它需要對某一組列進行唯一性約束,但它也有一個「軟刪除」指示器。已被標記爲「已刪除」的記錄不應包括在唯一性檢查中。
這很好,我可以用一個獨特的基於函數的索引輕鬆解決這個問題。然而,問題更復雜的是,如果我們要在數據庫中實現這個約束,它必須是一個延遲約束,因爲Hibernate的工作方式。如果它不能完成,我們將不得不忽略這個約束,而且我不希望如果可能的話。
例如:
CREATE TABLE jkemp_test
(id NUMBER NOT NULL
, deleted_ind CHAR(1) DEFAULT 'N' NOT NULL);
CREATE UNIQUE INDEX jkemp_test_funique
ON jkemp_test
(CASE WHEN deleted_ind = 'N' THEN id END);
-- make this use the function-based index, maybe?
ALTER TABLE jkemp_test
ADD CONSTRAINT jkemp_test_unique
UNIQUE (id)
DEFERRABLE INITIALLY DEFERRED;
INSERT INTO jkemp_test VALUES (1,'N');
INSERT INTO jkemp_test VALUES (2,'N');
COMMIT;
UPDATE jkemp_test SET deleted_ind='Y' WHERE id=1;
COMMIT;
-- depending on whether the constraint is deferred or not, either
-- the insert or the commit will fail "unique constraint violated"
INSERT INTO jkemp_test VALUES (1,'N');
COMMIT;
一個雙贏的局面將是最後一次提交成功,同時還允許約束被推遲。 (我知道唯一索引的存在意味着約束不是當前推遲的。)
我們現在唯一的選擇是使用應用程序來實現約束,這不會是可靠的。另外,我們不想過多地更改數據模型(例如,我們可以將刪除的行移動到不同的表中,例如JKEMP_TEST_DELETED
,但這會涉及應用程序中的太多複雜情況)。
這是在Oracle 11.2.0.1.0上。
+1非常好,我沒有想到一個計算列。謝謝! – 2011-03-28 05:15:14