今天這篇文章要講的是我在做項目開發時,遇到的一個思路性的問題:即如何通過刪除某張表的一條數據,完成其關聯表中相關數據的快速、便捷刪除。
問題重現:
我的數據庫中設計了A、B、C、D……等多張表,其中A表的主鍵uuid是B、C、D……表的外鍵。而我在頁面上進行數據展示時,默認展示的是C表中的基礎數據(表1),當用戶需要查看更多的信息時,可以通過點擊 button 來查看選中狀態下的一條數據對應的A、B、D……表中的更多關聯數據(表2)。
eg:(加粗表示選中狀態,傾斜字體表示按鈕)
表1
—————————————
序號 | 姓名 | 年齡 | 性別 |操作 班級信息
—————————————
1 | 張三 | 14 | 男 | 刪除
—————————————
2 | 李四 | 15 | 女 | 刪除
—————————————
當我點擊過“班級信息”按鈕後圖表如下:
表2
—————————————
序號 | 姓名 | 年齡 | 性別 | 操作 班級信息
—————————————
1 | 張三 | 14 | 男 | 刪除
—————————————
1.1 | 學校 | 年級 | 班號
—————————————
| 小學 | 小班 | 一班
—————————————
2 | 李四 | 15 | 女 | 刪除
—————————————
此時,當我刪除“張三”這條數據後,其他表中的相關聯的數據就將成爲垃圾數據。爲了解決這個問題,我想到了以下兩種方式:
- 在 controller 層中,調用“張三”基礎數據刪除方法的同時調用其他相關連表的刪除方法。然而,這樣的弊端將會是“大大的”。首先,我們爲了調用其他表的刪除方法,我們不得不在“張三”基礎數據的controller 層中注入其他表的 service 層接口來幫我們完成其他表的刪除操作。這樣無形中就增加了我們的代碼量。其次,這樣一來會消耗更多的內存空間,並且由於頻繁的與數據庫進行連接操作,直接影響到了代碼的執行效率。
- 通過在mysql數據庫中編寫觸發器,進行相關數據的刪除操作。如此我們就不用注入多個service 層接口,節省了內存空間;而且只需要對數據庫進行一次連接操作即可刪除剩餘垃圾數據;同時,由於觸發器是數據庫中自身的功能所以要比java代碼執行sql更快。
eg:
create trigger deleteAllInfo
after
delete
on vip
for each row
begin
delete from daily where daily.dai_col_uuid = old.vip_col_uuid;
delete from dining where dining.din_col_uuid = old.vip_col_uuid;
delete from environment where environment.env_col_uuid = old.vip_col_uuid;
delete from medicalhistory where medicalhistory.med_col_uuid = old.vip_col_uuid;
delete from otherbehavior where otherbehavior.oth_col_uuid = old.vip_col_uuid;
delete from relatives where relatives.rel_col_uuid = old.vip_col_uuid;
delete from sport where sport.spo_col_uuid = old.vip_col_uuid;
delete from `work` where `work`.wor_col_uuid = old.vip_col_uuid;
delete from collectivity where collectivity.col_uuid = old.vip_col_uuid;
end
PS:1>觸發器相關知識請自行度娘
2>細心的同學不難發現,上面的代碼中單詞 work 前後添加的兩個特殊符號,究其原因是 work 爲mysql中的關鍵字,所以 work 表無法直接被識別,故加上了轉義符號。該符號爲英文狀態下 tab 鍵上方的 ~ 鍵
3>數據表設計時儘量避免數據庫中的關鍵字出現在字段或表名中