Sử dụng Khóa ngoài và Tài liệu tham khảo để BẬT XÓA CASCADE trong mysql


7

Tôi đã nghĩ rằng hai cách để tạo khóa ngoại là giống nhau

CREATE TABLE child1 (
id int(11) not null auto_increment,
parent_id int(11) REFERENCES parent_table(parent_id) ON DELETE CASCADE,
PRIMARY KEY(id)
);

CREATE TABLE child2 (
id int(11) not null auto_increment,
parent_id int(11),
PRIMARY KEY(id),
FOREIGN KEY(parent_id) REFERENCES parent_table(parent_id) ON DELETE CASCADE
);

nhưng khi xóa một bản ghi khỏi bảng cha, bản ghi tương ứng trong bảng child2sẽ bị xóa nhưng KHÔNG phải là bản ghi child1.

Tôi sai ở đâu REFERENCESlà không đủ và chúng ta cần phải viết FOREIGN KEYđể sử dụng ON DELETE CASCADE?

Câu trả lời:


7

Nó là một "gotcha" của MySQL . Cách đầu tiên KHÔNG hoạt động.

Từ tài liệu MySQL, các FOREIGN KEYràng buộc :

Quan trọng:

... 4 đoạn dưới đây ...

Hơn nữa, InnoDB không nhận ra hoặc hỗ trợ các thông số kỹ thuật TÀI LIỆU THAM KHẢO trực tuyến . InnoDB chỉ chấp nhận các điều khoản TÀI LIỆU THAM KHẢO khi được chỉ định là một phần của thông số FOREIGN KEY riêng biệt. Đối với các công cụ lưu trữ khác, Máy chủ MySQL phân tích cú pháp và bỏ qua các thông số kỹ thuật khóa ngoài.

Tạo 2 bảng (cách 1):

CREATE TABLE parent_table (
parent_id int(11) not null auto_increment,
PRIMARY KEY(parent_id)
);

CREATE TABLE child1 (
id int(11) not null auto_increment,
parent_id int(11) REFERENCES parent_table(parent_id) ON DELETE CASCADE,
PRIMARY KEY(id)
);

Hãy xem những gì là child1:

> SHOW CREATE TABLE child1 ;

delimiter $$

CREATE TABLE `child1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$

Đâu là FOREIGN KEY? ... Cuốn theo chiều gió (và không có cảnh báo)


Tạo bảng child2(cách 2) hoạt động tốt:

CREATE TABLE child2 (
id int(11) not null auto_increment,
parent_id int(11),
PRIMARY KEY(id),
FOREIGN KEY(parent_id) REFERENCES parent_table(parent_id) ON DELETE CASCADE
);

> SHOW CREATE TABLE child2 ;

delimiter $$

CREATE TABLE `child2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `parent_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `parent_id` (`parent_id`),
  CONSTRAINT `child2_ibfk_1` 
    FOREIGN KEY (`parent_id`) REFERENCES `parent_table` (`parent_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$

3

Hấp dẫn. Tôi không nghĩ cú pháp child1thậm chí sẽ vượt qua khi tôi lần đầu tiên nhìn vào nó.

Một lý do có thể child1thất bại là bạn không cung cấp một loại rõ ràng. Khóa ngoại cần khớp loại.

Các cột tương ứng trong khóa ngoại và khóa được tham chiếu phải có các kiểu dữ liệu nội bộ tương tự bên trong InnoDB để có thể so sánh chúng mà không cần chuyển đổi loại. Kích thước và dấu hiệu của các loại số nguyên phải giống nhau. Độ dài của các loại chuỗi không cần phải giống nhau. Đối với các cột chuỗi không phân biệt (ký tự), bộ ký tự và đối chiếu phải giống nhau. [src]

Tôi nghi ngờ đó là lý do vì DDL của bạn là tối giản và parent_idtrong bảng cha có thể được xác định tương tự.

Nhưng bất chấp mọi thứ khác về câu hỏi này, bạn nên sử dụng cú pháp child2đơn giản vì nó rõ ràng hơn và dễ bảo trì hơn.


1
Loại thiếu là lỗi đánh máy bằng văn bản ở đây. Các loại đều giống nhau ở cha, con1 và con2. Có, tôi cũng nghĩ rằng tôi phải sử dụng cú pháp bảo mật của child2; nhưng vẫn tò mò muốn biết cái gì đầu tiên không hoạt động;)
Googlebot
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.