2011-05-21 31 views
3

想象一下這樣的設置:如何處理可能是FK的數據庫記錄?

create table ObservationType 
(
ObservationTypeId int primary key identity(1,1), 
Name nvarchar(32) not null 
) 

create table Observation 
(
ObservationId int primary key identity(1,1), 
ObservationTypeId int foreign key references ObservationType(ObservationTypeId), 
Title nvarchar(32) not null, 
Description nvarchar(1024) not null, 
StudentId int foreign key references Student(StudentId) 
) 

create table Student 
(
foo bar 
) 

現在想象一下這個充滿數據的,它的正常工作。當用戶想要刪除觀察類型時,你如何處理?你會自動刪除任何具有特定類型的觀察結果嗎?

在現實世界中,你是如何處理這種情況的?

回答

2

在很多情況下,這是正確的做法 - 這就是爲什麼ON DELETE CASCADE存在。

這意味着對於刪除的行,在該行上定義爲這樣的外鍵的另一個表中的任何行也將被刪除。

你需要問的問題是它是否是用戶真正想要的東西?在應用程序域內執行這種刪除有意義嗎?詢問你的用戶如果他們刪除了一個觀測類型他們希望發生什麼 - 他們認爲應該發生在現有觀測上。

有時,最好使用軟刪除(在狀態字段中標記具有刪除狀態的行),以便恢復/取消刪除。這不是沒有its share of problems

2

添加級聯刪除到外鍵?另外,你真的想允許從你的數據庫中真正刪除嗎?爲什麼不把它們標記爲不活動?

+0

我通常會這樣做,添加一列以標記它是否是活動/非活動條目,這樣您就不必刪除數據 – Brett 2011-05-21 18:46:05

0

雖然它存在並且可能有用,但我不建議設置級聯刪除。但我同意,軟刪除可能是一件好事。

但是,你想要的東西,爲什麼不創建

  1. 刪除相應的觀測記錄
  2. 刪除ObservationType程序
  3. 日誌(ActivityLog?)什麼已被刪除,爲什麼(一評論)。不需要存儲整套已刪除的數據,但足以滿足合規性(又名SOX)。誰,什麼,什麼時候。
0

如果可能,我更喜歡使用'軟'刪除。這意味着在桌上有刪除位列。 所以,當你刪除你實際上對錶運行update語句設置刪除爲1

但是,如果我想刪除是肯定的,我會用明確的DELETE語句,而不是ON DELETE CASCADE外鍵行。

delete Observation 
where ObservationTypeId = 1 

delete ObservationType 
where ObservationTypeId = 1 

我會盡量避免使用隱式ON DELETE CASCADE,因爲它會導致隱藏危險意外刪除。 如果所有數據庫都建立在級聯刪除外鍵上,那麼有人會誤刪除整個數據庫的內容,只需對所有其他表中引用的一個表執行刪除即可。所以簡單來說,我發現ON DELETE CASCADE是一個容易出錯的解決方案。