MySQL級聯刪除的問題


 1 一、FOREIGN KEY 的定義分為兩種:列級約束和表級約束
 2 1、列及約束的話,可以在列定義的同時,定義外鍵約束。比如
 3 如果有2張表,主表:T1(A1 int primary key ,A2 varchar(10))
 4 要在從表T2中定義外鍵列這可以:
 5 Create table T2(
 6 B1 int,
 7 B2 char(10) [FOREIGN KEY] references T1(A1)
 8 ) 
 9 /*這里的“[FOREIGN KEY] references T1(A1)”就是外鍵定義了,[]是可
10 選項,就是可以省略*/
11 2、如果是表級約束的話,則可以
12 CREATE TABLE T2(
13 B1 INT,
14 B2 CHAR(10),
15 [Constraint(約束名)] FOREIGN KEY(B1) references T1(A1)
16 17 /*這里是在所有列定義之后,在進行約束定義,這里要注意,表定義一定要在約束后面帶上你所定義的列名,如:FOREIGN KEY(B1)
18 還要注意的是,[Constraint(約束名)]是可選項,每個約束都是有名字的,如果你不添加,系統是會自動為你添加約束名的,作為一個合格DBA的話,建議還是自己添加約束名,有助於以后的操作(比如修改約束,刪除約束等)*/
19 
20 二、如果之前表已經存在,要給其中一個列添加約束的話,就屬於alter操作了
21 ALTER TABLE T2
22 ADD [CONSTRAINT(約束名)] FOREIGN KEY(B1) references T1(A1)
23 /*相信不用我多解釋了*/
24 
25 但是還有一點需要注意,如果在你添加之前,B1已經有了外鍵約束,那么就要先刪除之前的約束,再添加,否則是不成功的。

 

首先得理解概念,什么叫級聯刪除?

外鍵的級聯刪除:如果父表中的記錄被刪除,則子表中對應的記錄自動被刪除
父表——被外鍵引用的表
子表——引用父表中的健作為外健的表

on updata 參數 、 on delete 參數
這是數據庫外鍵定義的一個可選項,用來設置當主鍵表中的被參考列的數據發生變化時,外鍵表中響應字段的變換規則的。

update 則是主鍵表中被參考字段的值更新,delete是指在主鍵表中刪除一條記錄: on updateon delete 后面可以跟的詞語有四個 no actionset nullset defaultcascade no action 表示 不做任何操作, set null 表示在外鍵表中將相應字段設置為null set default 表示設置為默認值 cascade 表示級聯操作,就是說,如果主鍵表中被參考字段更新,外鍵表中也更新,主鍵表中的記錄被刪除,外鍵表中改行也相應刪除

重點:

一個表只能有一個主鍵,一個主鍵又可以分為保存單個字段(單字段鍵)多字段(叫聯合主鍵)

單字段代碼:

1 create table  表名(
2 user_id int(11) auto_increment,     //user_id int(11) auto_increment primary key,還有這種寫法不知可不可以,有興趣自行嘗試
3 username varchar(24),
4 password char(32),
5 primary key(user_id)
6 );

多字段代碼:

1 create table  表名(
2 username varchar(24),
3 password char(32),
4 email varchar(40),
5 primary key(username,email)
6 );

外鍵:

好處:可以使得兩張表關聯,保證數據的一致性和實現一些級聯操作

作用:保持數據一致性,完整性,主要目的是控制存儲在外鍵表中的數據。 使兩張表形成關聯,外鍵只能引用外表中的列的值!

1 在子表中聲明 一個外鍵的代碼:
2 //數據類型一定要匹配
3 格式:foreign key(子表的字段) references  父表的表名(父表的主鍵字段) on delete cascade on update cascade
4 // on update cascade on delete cascade 的意思是 父表的主鍵改變時,子表外鍵也跟着改變,父表的主鍵的值刪除時,子表的外鍵的值也刪除。這就是級聯。

 如果沒有on update cascade 這句的,如果想更新父表或者子表都會報錯,除非刪除子表的引用再修改父表。有時候也可以省略foreign key 這個關鍵字,如:

 

舉個例子:

我們創建一個父表   :工程職工工時表       子表:haha          ----聲明顯然名稱沒有必然聯系,僅做測試用的,勿噴!

父表代碼:

1  create table 工程職工工時表(
2      工程ID integer,
3      姓名 varchar(20) not null,
4      primary key(工程ID)
5      );

子表代碼:

1  create table haha(
2      工程ID integer,
3     foreign key(工程ID) references 工程職工工時表(工程ID) on delete cascade on update cascade);

給父表賦值:  insert into 工程職工工時表 values(23,'haohao'); 

此時子表還是空的,為什么?按我的理解是,所謂的外鍵約束是,給定的父表的主鍵值后,子表的外鍵就必須與父表的主鍵值相同,不然就會報錯(拋出異常),這可不是瞎說的,本文后面會獻上完整的效果圖以供參考。

如果想刪除父表的話就會出錯:

1 mysql> drop table 工程職工工時表;
2 ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails

 錯誤的大概意思是父表與子表有着級聯的關系,不能刪除父表。只能刪除父表字段的值,子表的字段的值也會跟着刪除。要想刪除父表,得先刪除子表或子表的約束再刪除父表。

代碼:

1 mysql> delete from 工程職工工時表 where 工程ID=23;
2 Query OK, 1 row affected (0.12 sec)
格式:delete from 表名 where 字段=條件

終端測試的全部代碼:

 1 mysql> create database mysql;
 2 Query OK, 1 row affected (0.00 sec)
 3 
 4 mysql> use mysql;
 5 Database changed
 6 mysql> create table 工程職工工時表(
 7     -> 工程ID integer,
 8     -> 姓名 varchar(20) not null,
 9     -> primary key(工程ID)
10     -> );
11 Query OK, 0 rows affected (0.07 sec)
12 
13 mysql> create table haha(
14     -> 工程ID integer,
15     -> foreign key(工程ID) references 工程職工工時表(工程ID) on delete cascade on update cascade);
16 Query OK, 0 rows affected (0.15 sec)
17 
18 mysql> insert into 工程職工工時表 values(23,'haohao');
19 Query OK, 1 row affected (0.04 sec)
20 
21 mysql> desc haha;
22 +----------+---------+------+-----+---------+-------+
23 | Field    | Type    | Null | Key | Default | Extra |
24 +----------+---------+------+-----+---------+-------+
25 | 工程ID   | int(11) | YES  | MUL | NULL    |       |
26 +----------+---------+------+-----+---------+-------+
27 1 row in set (0.01 sec)
28 
29 mysql> select*from haha;
30 Empty set (0.00 sec)
31 
32 mysql> select*from 工程職工工時表;
33 +----------+--------+
34 | 工程ID   | 姓名   |
35 +----------+--------+
36 |       23 | haohao |
37 +----------+--------+
38 1 row in set (0.00 sec)
39 
40 mysql> select*from haha;
41 Empty set (0.00 sec)
42 mysql> insert into haha values(3434);
43 ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`mysql`.`haha`, CONSTRAINT `haha_ibfk_1` FOREIGN KEY (`工程ID`) REFERENCES `工程職工工時表` (`工程ID`) ON DELETE CASCADE ON UPDATE CASCADE)
44 
45 
46 mysql> alter table 工程職工工時表 engine=InnoDB;
47 Query OK, 0 rows affected (0.21 sec)
48 Records: 0  Duplicates: 0  Warnings: 0
49 
50 mysql> alter table haha engine=InnoDB;
51 Query OK, 0 rows affected (0.10 sec)
52 Records: 0  Duplicates: 0  Warnings: 0
53 
54 mysql> insert into haha values(23)
55     -> ;
56 Query OK, 1 row affected (0.01 sec)
57 
58 mysql> select*from haha;
59 +----------+
60 | 工程ID   |
61 +----------+
62 |       23 |
63 +----------+
64 
65 mysql> drop table 工程職工工時表;
66 ERROR 1217 (23000): Cannot delete or update a parent row: a foreign key constraint fails
67 
68 1 row in set (0.00 sec)
69 
70 mysql> delete from 工程職工工時表 where 工程ID=23;
71 Query OK, 1 row affected (0.12 sec)
72 mysql> select*from 工程職工工時表;
73 Empty set (0.03 sec)
74 
75 mysql> select*from haha;
76 Empty set (0.00 sec)
77 
78 mysql> insert into 工程職工工時表 values(33,'yuan');
79 Query OK, 1 row affected (0.00 sec)
80 
81 mysql> select*from 工程職工工時表;
82 +----------+--------+
83 | 工程ID   | 姓名   |
84 +----------+--------+
85 |       33 | yuan   |
86 +----------+--------+
87 1 row in set (0.00 sec)
88 
89 mysql> select*from haha;
90 Empty set (0.00 sec)

 


 

 
        


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM