天天看點

資料庫中的參照完整性(Foreign Key)

之前在項目中遇到了這樣一個問題,我舉得簡單的例子來說明,

比如我們有兩個表,一個表(department)存放的是部門的資訊,例如部門id,部門名稱等;另一個表是員工表(staff),員工表裡面肯定要存放每個員工所在的部門。那問題來了,如果我們這個時候删除了部門表中的某條記錄,在staff表中會發生什麼?

為了解答上面的問題,讓我們先來回顧一下什麼是參照完整性。

我們常常希望保證在一個關系中給定屬性集上的取值也在另一個關系的特定屬性集的取值中出現。這種情況稱為參照完整性(referential integrity)

正如我們可以用外碼在sql中的create table語句一部分的foreign key子句來聲名。

例如staff表中的我們可以用  foreign key(dep_name) references department  來表明在每個員工組中指定的部門名稱dep_name必須在department關系中存在。

更一般地,令關系r1和r2的屬性集分别為r1和r2,主碼分别為k1和k2。如果要求對r2中任意元祖t2,均存在r1中元祖t1使得t1.k1 = t2.α,我們稱r2的子集α為參照關系r1中k1的外碼(foreign key)

當我們違反了參照完整性限制時,通常的處理是拒絕執行導緻完整性破壞的操作(即進行更新操作的事務被復原)。但是,在foreign key子句中可以指明:如果被參照關系上的删除或更新動作違反了限制,那麼系統必須采取一些步驟通過修改參照關系中的元祖來恢複完整性限制,而不是拒絕這樣的操作。

來看下面的例子:

這是我們的department關系

下面一般情況下我們的staff關系

下面是特定更新動作的staff關系

由于有了外碼聲名相關聯的on delete cascade子句,如果删除department中的元祖導緻了此參照完整性限制被違反,則删除并不被系統拒絕,而是對staff關系作聯機删除,即删除參照了被删除系的元祖。類似的,on

update cascade會在更新時同步進行參照關系中元祖的更新。sql還允許foreign key子句指明除了cascade以外的其他動作,如果限制被違反,可将參考與置為null(用set null代替 cascade),或者置為預設值(set default)。

但是,一般來說,我們習慣的用法是,不允許删除。如果實在要删除,可以在被參照關系中加一個字段,來表明目前的記錄被删除了,這樣也友善日後查詢等相關操作。