Nếu tầng của bạn xóa nuke một sản phẩm vì nó là thành viên của danh mục bị giết, thì bạn đã thiết lập khóa ngoại của bạn không đúng cách. Với bảng ví dụ của bạn, bạn nên có các thiết lập bảng sau:
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;
Bằng cách này, bạn có thể xóa một sản phẩm hoặc một loại, và chỉ có các hồ sơ liên quan trong categories_products sẽ chết cùng. Các thác sẽ không đi xa hơn cây và xóa bảng sản phẩm/danh mục gốc.
ví dụ:
products: boots, mittens, hats, coats
categories: red, green, blue, white, black
prod/cats: red boots, green mittens, red coats, black hats
Nếu bạn xóa các loại 'đỏ', sau đó chỉ 'đỏ' entry trong bảng categories chết, cũng như hai mục sản/mèo: 'khởi động đỏ' và 'áo đỏ'.
Việc xóa sẽ không xếp hàng xa hơn và sẽ không loại bỏ danh mục 'khởi động' và 'áo khoác'.
nhận xét tiếp theo:
bạn vẫn hiểu lầm về cách xóa tầng hoạt động. Chúng chỉ ảnh hưởng đến các bảng trong đó "thác trên xóa" được xác định. Trong trường hợp này, tầng được đặt trong bảng "categories_products". Nếu bạn xóa danh mục 'màu đỏ', các bản ghi duy nhất sẽ xếp xóa trong danh mục_products là những mục có số category_id = red
. Nó sẽ không chạm vào bất kỳ bản ghi nào có 'category_id = blue' và nó sẽ không chuyển sang bảng "sản phẩm", bởi vì không có khóa ngoại được xác định trong bảng đó.
Dưới đây là một ví dụ cụ thể hơn:
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
+------------+-------------+
Hãy nói rằng bạn xóa danh mụC# 2 (màu xanh):
DELETE FROM categories WHERE (id = 2);
DBMS sẽ xem xét tất cả các bảng trong đó có một trỏ chính nước ngoài tại bảng 'danh mục' và xóa các bản ghi trong đó id phù hợp là 2. Vì chúng tôi chỉ xác định mối quan hệ khóa ngoài trong products_categories
, bạn kết thúc với bảng này khi xóa hoàn tất:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
Không có khóa ngoại được xác định trong bảng products
, do đó, thác sẽ không hoạt động ở đó, vì vậy bạn vẫn có khởi động và găng được liệt kê. Không chỉ có 'đôi bốt xanh' và không còn 'găng tay xanh' nữa.
Hi - bạn có thể muốn thay đổi tiêu đề câu hỏi, đó là khoảng cascade xóa thực sự, chứ không phải cụ thể bảng tổng hợp. – Paddyslacker