Jika cascading Anda menghapus nuke suatu produk karena itu adalah anggota dari kategori yang terbunuh, maka Anda telah mengatur kunci asing Anda dengan tidak benar. Mengingat tabel contoh Anda, Anda harus memiliki pengaturan tabel berikut:
CREATE TABLE categories (
id int unsigned not null primary key,
name VARCHAR(255) default null
)Engine=InnoDB;
CREATE TABLE products (
id int unsigned not null primary key,
name VARCHAR(255) default null
)Engine=InnoDB;
CREATE TABLE categories_products (
category_id int unsigned not null,
product_id int unsigned not null,
PRIMARY KEY (category_id, product_id),
KEY pkey (product_id),
FOREIGN KEY (category_id) REFERENCES categories (id)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (product_id) REFERENCES products (id)
ON DELETE CASCADE
ON UPDATE CASCADE
)Engine=InnoDB;
Dengan cara ini, Anda dapat menghapus produk ATAU kategori, dan hanya catatan terkait di kategori_produk yang akan mati bersama. Kaskade tidak akan berjalan lebih jauh ke atas pohon dan menghapus tabel produk/kategori induk.
misalnya
products: boots, mittens, hats, coats
categories: red, green, blue, white, black
prod/cats: red boots, green mittens, red coats, black hats
Jika Anda menghapus kategori 'merah', maka hanya entri 'merah' dalam tabel kategori yang mati, serta dua entri prod/cats:'sepatu bot merah' dan 'mantel merah'.
Penghapusan tidak akan mengalir lebih jauh dan tidak akan menghilangkan kategori 'sepatu bot' dan 'mantel'.
tindak lanjut komentar:
Anda masih salah paham tentang cara kerja penghapusan berjenjang. Mereka hanya mempengaruhi tabel di mana "di hapus kaskade" didefinisikan. Dalam hal ini, kaskade diatur dalam tabel "kategori_produk". Jika Anda menghapus kategori 'merah', satu-satunya catatan yang akan dihapus secara kaskade dalam kategori_produk adalah yang category_id = red
. Itu tidak akan menyentuh catatan apa pun di mana 'category_id =blue', dan tidak akan melanjutkan ke tabel "produk", karena tidak ada kunci asing yang ditentukan dalam tabel itu.
Berikut ini contoh yang lebih konkret:
categories: products:
+----+------+ +----+---------+
| id | name | | id | name |
+----+------+ +----+---------+
| 1 | red | | 1 | mittens |
| 2 | blue | | 2 | boots |
+---++------+ +----+---------+
products_categories:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 1 | 2 | // blue mittens
| 2 | 1 | // red boots
| 2 | 2 | // blue boots
+------------+-------------+
Katakanlah Anda menghapus kategori #2 (biru):
DELETE FROM categories WHERE (id = 2);
DBMS akan melihat semua tabel yang memiliki kunci asing yang menunjuk ke tabel 'kategori', dan menghapus catatan di mana id yang cocok adalah 2. Karena kita hanya mendefinisikan hubungan kunci asing di products_categories
, Anda akan mendapatkan tabel ini setelah penghapusan selesai:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
Tidak ada kunci asing yang ditentukan dalam products
meja, jadi kaskade tidak akan berfungsi di sana, jadi Anda masih memiliki sepatu bot dan sarung tangan yang terdaftar. Tidak ada lagi 'sepatu bot biru' dan 'sarung tangan biru'.