我們通常有這樣的需求:刪除表Table 1中記錄,需要同時刪除其它表中與Table 1有關的若干記錄。
對於這種,我們有兩種解決方法:
一,使用innodb表的外鍵約束
ALTER TABLE `score`
ADD CONSTRAINT `student_ibfk1`
FOREIGN KEY `sid`(`sid`) REFERENCES `students` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE;
這里CASCADE作用就是在父表記錄更新或刪除時,子表更新或刪除相應的記錄
外鍵約束的動作除了CASCADE,還有RESTRICT(限制刪除)SET NULL(設為空值,字段如果允許為空的話)等
二,使用觸發器trigger進行操作
由於外鍵約束只能用於Innodb型表,因些對於MyIsam型表還得用trigger來進行更新
--以下觸發器在刪除students后同時刪除表score中相關記錄
DROP TRIGGER IF EXISTS `deleteScore`
CREATE TRIGGER `deleteScore` AFTER DELETE ON `students`
FOR EACH ROW BEGIN
DELETE FROM score WHERE sid=OLD.`id`;
END
觸發器比較好理解,其中AFTER是事件發生后,有的需求可能用BEFORE;事件類型有INSERT,REPLACE,UPDATE,DELETE等;
對於mysql外鍵約束,再說幾句:
外鍵約束分為三種:cascade,set null,restrict
舉例子來說明差異:
首先創建用戶組表:
創建用戶組表
create table t_group (
id int not null,
name varchar(30),
primary key (id)
);
並插入兩條記錄:
插入記錄
insert into t_group values (1, 'Group1');
insert into t_group values (2, 'Group2');
下面創建用戶表,分別以不同的約束方式創建外鍵引用關系:
1、級聯(cascade)方式
級聯方式
create table t_user (
id int not null,
name varchar(30),
groupid int,
primary key (id),
foreign key (groupid) references t_group(id) on delete cascade on update cascade
);
參照完整性測試
insert into t_user values (1, 'qianxin', 1); #可以插入
insert into t_user values (2, 'yiyu', 2); #可以插入
insert into t_user values (3, 'dai', 3); #錯誤,無法插入,用戶組3不存在,與參照完整性約束不符
約束方式測試
insert into t_user values (1, 'qianxin', 1);
insert into t_user values (2, 'yiyu', 2);
insert into t_user values (3, 'dai', 2);
delete from t_group where id=2; #導致t_user中的2、3記錄級聯刪除
update t_group set id=2 where id=1; #導致t_user中的1記錄的groupid級聯修改為2
2、置空(set null)方式
置空方式
create table t_user (
id int not null,
name varchar(30),
groupid int,
primary key (id),
foreign key (groupid) references t_group(id) on delete set null on update set null
);
參照完整性測試insert into t_user values (1, 'qianxin', 1); #可以插入
insert into t_user values (2, 'yiyu', 2); #可以插入
insert into t_user values (3, 'dai', 3); #錯誤,無法插入,用戶組3不存在,與參照完整性約束不符
約束方式測試
insert into t_user values (1, 'qianxin', 1);
insert into t_user values (2, 'yiyu', 2);
insert into t_user values (3, 'dai', 2);
delete from t_group where id=2; #導致t_user中的2、3記錄的groupid被設置為NULL
update t_group set id=2 where id=1; #導致t_user中的1記錄的groupid被設置為NULL
3、禁止(no action / restrict)方式
禁止方式
create table t_user (
id int not null,
name varchar(30),
groupid int,
primary key (id),
foreign key (groupid) references t_group(id) on delete no action on update no action
);
參照完整性測試
insert into t_user values (1, 'qianxin', 1); #可以插入
insert into t_user values (2, 'yiyu', 2); #可以插入
insert into t_user values (3, 'dai', 3); #錯誤,無法插入,用戶組3不存在,與參照完整性約束不符
約束方式測試
insert into t_user values (1, 'qianxin', 1);
insert into t_user values (2, 'yiyu', 2);
insert into t_user values (3, 'dai', 2);
delete from t_group where id=2; #錯誤,從表中有相關引用,因此主表中無法刪除
update t_group set id=2 where id=1; #錯誤,從表中有相關引用,因此主表中無法修改
由此可見,這三者都會插入操作進行相同的約束,不同反映在處理刪除和更新操作;
