關系型數據庫(RDBMS)級聯刪除
數據庫操作中,級聯刪除(Cascade)是一種處理數據表之間關聯數據的方式。用于在刪除主表(父表)中的一條記錄時,自動刪除與該條數據相關聯的子表內的數據。
1. 適用數據庫
級聯刪除(Cascade Delete)適用于多個主流的關系數據庫管理系統(RDBMS):
1) PostgreSQL:
支持級聯刪除,使用 ON DELETE CASCADE 在定義外鍵時指定。
當父表中刪除記錄時,所有在子表內與之關聯的記錄也會被自動刪除。
2) MySQL
支持級聯刪除,使用 ON DELETE CASCADE 在外鍵定義時被指定。
注意:MySQL中的 InnoDB 引擎支持級聯刪除,但MyISAM 引擎并不支持外鍵約束,故不支持級聯刪除。
3) Orcla
支持級聯刪除,使用 ON DELETE CASCADE。
當刪除父表中的記錄時,Orcla 會 自動刪除子表的對應的記錄。
4) SQL Server
支持級聯刪除,使用 ON DELETE CASCADE。
可以創建或修改外鍵時指定級聯刪除行為。
5) SQLite
支持級聯刪除,但需在啟用外鍵約束的情況下使用。
使用 PRAGMA foreign_keys = on; 啟用外鍵約束后,可以使用 ON DELETE CASCADE。
6) MariaDB
作為MySQL的一個分支,MariaDB也支持級聯刪除,方式與 MySQL 類型。
7) DB2(IBM)
支持級聯刪除,使用 ON DELETE CASCADE。
在DB2中,可以在外鍵約束中指定級聯刪除規則。
2. 使用場景
使用場景:
級聯刪除在數據庫設計,有明確的父子表關系場景中;如訂單及其項、用戶及其日志記錄等。在這些場景時,級聯刪除可以確保在刪除父表中的記錄時,不會遺留無用的子表記錄,從而保持數據的一致性和完整性。
3. 實現方式
級聯刪除可以通過兩種方式實現:
1) 使用事務手動實現級聯刪除
在事務中執行多個 delete 語句,根據外鍵關系依次刪除相關的記錄。
這種方法需要明確控制刪除順序,確保在刪除父記錄前先刪除相關的子記錄,以避免外鍵約束的沖突。
創建表 和 外鍵關系:(orders-父表 和 order_items-子表;從表中的每條數據與父表的單條數據關聯)。
-- 創建父表 orders CREATE TABLE orders ( id SERIAL PRIMARY KEY, -- 自增主鍵 order_date DATE NOT NULL, customer_name VARCHAR(255) NOT NULL ); -- 創建子表 order_items CREATE TABLE order_items ( id SERIAL PRIMARY KEY, -- 自增主鍵 order_id INT NOT NULL, -- 外鍵,引用 orders 表 product_name VARCHAR(255) NOT NULL, quantity INT NOT NULL, FOREIGN KEY (order_id) REFERENCES orders(id) -- 定義外鍵約束 );
刪除 orders 表內的數據與子表所有與之關聯的 order_item的數據。
順序:必須先刪除子表的記錄,然后再刪除父標的記錄。
事務:確保操作是原子性的,要么全部成功,要么全部失敗,以確保數據的一致性。
SQL是這樣的:
BEGIN; -- 開始事務 -- 刪除子表 order_items 中與 order_id = 1 關聯的所有記錄 DELETE FROM order_items WHERE order_id = 1; -- 刪除父表 orders 中 id = 1 的記錄 DELETE FROM orders WHERE id = 1; COMMIT; -- 提交事務
使用 Mybtis 時 xml 文件執行:
<delete id="deleteOrderWithItems"> <!-- 刪除子表 order_items 中與 order_id 關聯的所有記錄 --> DELETE FROM order_items WHERE order_id = #{id}; <!-- 刪除父表 orders 中 id 的記錄 --> DELETE FROM orders WHERE id = #{id}; </delete>
2) 使用數據庫的 CASCADE 規則
在定義外鍵約束時,可以指定 on delete cascade,當父記錄被刪除時,數據庫會自動刪除所有關聯的子記錄。
這種方法是數據庫層面的一種自動化處理方式,無需手動編寫多個刪除語句。
創建表 和 外鍵關系:(orders-父表 和 order_items-子表;從表中的每條數據與父表的單條數據關聯)。
-- 創建父表 orders CREATE TABLE orders ( id SERIAL PRIMARY KEY, -- 自增主鍵 order_date DATE NOT NULL, customer_name VARCHAR(255) NOT NULL ); -- 創建子表 order_items,并定義外鍵,指定 on delete cascade CREATE TABLE order_items ( id SERIAL PRIMARY KEY, -- 自增主鍵 order_id INT NOT NULL, -- 外鍵,引用 orders 表 product_name VARCHAR(255) NOT NULL, quantity INT NOT NULL, FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE -- 定義外鍵約束,啟用級聯刪除 );
order_items-子表 外鍵 order_id 引用 orders-父表 id。
SQL是:
-- 刪除 orders 表中 id = 1 的記錄 DELETE FROM orders WHERE id = 1;
mxl文件語法:
<!-- 刪除 orders 表中 id = ... 的記錄 --> <delete id="deleteOrderById"> delete from orders where id = #{id}; </delete>
定義了外鍵時使用了 'ON DELETE CASCADE',數據庫會自動刪除 '從表' 對應的 'order_id' 的數據。
4. ON DELETE外鍵
外鍵(Froreign Key)是一種數據庫約束,用于在兩個表之間建立關系。外鍵通常用于與另一個表的主鍵(Primark Key),并確保引用完整性,保證外鍵列中的值必須在被引用的表中存在。
外鍵約束多種類型的規則和選項,可以控制在發生數據變更時的行為。
| CASCADE |
當主表的一條記錄被刪除時,所有引用該記錄的子表中的記錄也會被自動刪除。 場景:當刪除某條記錄時,必須同時刪除與該記錄關聯的所有的子記錄(如訂單與訂單項)。 |
| SET NULL |
當主表的一條記錄被刪除時,子表中引用該記錄的外鍵字段會被設置為 NULL。 場景:當刪除主記錄時,子記錄可以保留,但需要設置外鍵為 NULL(如文章和作者,刪除作者但文章繼續顯示但不顯示作者)。 |
| RESTRICT |
機制刪除主表中的記錄,如果該記錄被子表引用,則無法刪除。 場景:嚴格禁止刪除有依賴關系的主記錄,確保所有關聯的子記錄先被處理。 |
| NO ACTION |
類似于 'RESTRICT',但在某些數據庫系統中,它的行為取決于其他觸發器或約束。 場景:用于不想執行任何級聯操作的場合。 |
| SET DEFAULT |
當主表的一條記錄被刪除時,子表引用該記錄的外鍵字段會被設置為預定義的默認值。 場景:當刪除主記錄時,子記錄保留,但外鍵字段設置為默認值(如產品分類,刪除分類時,產品的分類字段這是為默認分類)。 |
5. 注意事項
性能影響:在大量數據刪除時,級聯刪除可能會影響性能,尤其在子表記錄很多的情況下。
數據丟失風險:級聯刪除會自動刪除與其相關的子表記錄,因此慎重使用,防止意外丟失重要的數據。
外鍵約束:需要注意數據庫引擎是否支持外鍵約束(如MySQL的MyISAM引擎不支持)。

浙公網安備 33010602011771號