在數據庫中使用外鍵和級聯刪除


前一陣子寫了1個項目,這個項目有ios和android2個版本,都使用了sqlite數據庫。數據庫內容也不是太復雜,但是我們在操作時沒有利用數據庫的級聯刪除等功能,導致代碼復雜,現在分析一下。

比如系統需要2個表,表Person表示人的信息, 包含personID,personName,  表Treatement表示治療方案,包含用葯名稱,用葯劑量,用葯時間。一個人可以對應多個治療方案。

以下是我用的設計

CREATE TABLE "person" ("id" INT , "name" VARCHAR(20))

CREATE TABLE "treatement" ("id" INTEGER, "personId" INTEGER , "time" TEXT)

 

看看這里的問題,

第一,沒有使用主鍵,導致我在添加person時,需要驗證是否已經存在相同的id。

第二,沒有在第二張表中使用外鍵。第二張表中項目,表示一個人對應的治療方案,一個人可以有多條治療方案。如果這個人被刪除了,那么所有的治療方案也該被刪除。這里perosnId應該設置為外鍵,關聯表1的id,這樣就可以利用級聯刪除,保證2張表的一致性。而且,還可以保證不會在表2中產生一個不存在的人的治療方案!

下面從網上摘抄一點關於外鍵和數據庫的知識,感謝原作者的辛勤付出!


 

級聯刪除 
 
刪除包含 主鍵值的行的操作,該值由其它表的現有行中的 外鍵列引用。在級聯刪除中,還刪除其外鍵值引用刪除的 主鍵值的所有行。
語法:
Foreign Key
(column[,...n])
references referenced_table_name[(ref_column[,...n])]
[on delete cascade]
[on update cascade]
注釋:
column:列名
referenced_table_name: 外鍵參考的 主鍵表名稱
ref_name: 外鍵要參考的表的 主鍵
on delete:刪除級聯
on update:更新級聯
SQL級聯刪除——刪除主表同時刪除從表——同時刪除具有主外鍵關系的表
create table a
(
id varchar(20) primary key,
password varchar(20) not null
)
create table b
(
id int identity(1,1) primary key,
name varchar(50) not null,
userId varchar(20),
foreign key (userId) references a(id) on delete cascade
)
表B創建了外碼userId 對應A的主碼ID,聲明了級聯刪除
測試數據:
insert a values ('11','aaa')
insert a values('23','aaa')
insert b values('da','11')
insert b values('das','11')
insert b values('ww','23')
刪除A表內id為‘11’的數據,發現B表內userId 為“11”也被數據庫自動刪除了,這就是級聯刪除
delete a where id='11'

 外鍵的作用

保持數據一致性,完整性,主要目的是控制存儲在外鍵表中的數據。 使兩張表形成關聯,外鍵只能引用外表中的列的值或使用空值。

 


 

如果僅僅聲明了外鍵,而沒有做級聯操作,那么有以下結論:

1. 外鍵約束對insert語句的影響:

 插入數據的外鍵字段值必須在主表中存在,只有從表才有可能違反約束,主表不會。      

2.外鍵約束對delete語句的影響:

刪除主表數據時,如果從表有對該數據的引用,主表才有可能違反約束。

3.外鍵約束對update語句的影響:

主從表都有可能違反外鍵約束,操作一個表必須將另一個表的數據處理好。

比如我有以下2個表,這里person表就是主表,treatement表就是從表,從表參照主表的鍵形成從表的外鍵。

 看看表中的數據

 

之后我試着插入一條treatement數據,這條數據的personID是10,在person表中不存在,如圖

 當我點擊save時,系統報錯,如圖

上邊的例子就是外鍵約束對insert的影響。

在來看看外鍵約束對delete的影響,

如果我想刪除person中的id = 1的條目,系統就會報錯,因為在treatement表中存在外鍵引用,並且引用的值是 1,錯誤截圖如下

如果添加上級聯刪除,操作結果如下

現在表結構為

CREATE TABLE "treatement" ("id" INTEGER PRIMARY KEY, "personId" INTEGER REFERENCES "person" ("id") ON DELETE CASCADE, "time" TEXT)

這時我就可以刪除person表中id = 1 的項目了,刪除后treatement中personId = 1 的項目同時被刪除了。

注意,這里的級聯刪除需要在從表聲明的,說明了自己被系統級聯刪除的參照條件。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM