數據庫中的參照完整性(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關系
create table department ( dept_name varchar(20), building varchar(15), primary key(department) )
以下普通情況下我們的staff關系
<pre name="code" class="sql">create table staff ( ID varchar(15), name varchar(20), not null dept_name varchar(20), primary key (ID), foreign key(dept_name) reference department )
create table staff ( ID varchar(15), name varchar(20), not null dept_name varchar(20), primary key (ID), foreign key(dept_name) reference department on delete cascade on update cascade )
類似的。on update cascade會在更新時同步進行參照關系中元祖的更新。SQL還同意foreign key子句指明除了cascade以外的其它動作,假設約束被違反,可將參考與置為null(用set null取代 cascade)。或者置為默認值(set default)。
可是,一般來說,我們習慣的使用方法是。不同意刪除。假設實在要刪除。能夠在被參照關系中加一個字段,來表明當前的記錄被刪除了。這樣也方便日後查詢等相關操作。
數據庫中的參照完整性(Foreign Key)