1. 程式人生 > >MySQL外來鍵 Cannot add or update a child row錯誤的例項解釋

MySQL外來鍵 Cannot add or update a child row錯誤的例項解釋

在MySQL 3.23.44版本後,InnoDB引擎型別的表支援了外來鍵約束。
外來鍵的使用條件:
1.兩個表必須是 InnoDB表,MyISAM表暫時不支援外來鍵(據說以後的版本有可能支援,但至少目前不支援);
2.外來鍵列必須建立了索引,MySQL  4.1.2以後的版本在建立外來鍵時會自動建立索引,但如果在較早的版本則需要顯示建立;
3.外來鍵關係的兩個表的列必須是資料型別相似,也就是可 以相互轉換型別的列,比如int和tinyint可以,而int和char則不可以;

外來鍵的好處:可以使得兩張表關聯,保證資料的一致性和實現一些級聯操作;

外來鍵的定義語法:
[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name,  ...)
    REFERENCES tbl_name (index_col_name, ...)
    [ON DELETE  {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
    [ON  UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
該語法 可以在 CREATE TABLE 和 ALTER TABLE 時使用,如果不指定CONSTRAINT  symbol,MYSQL會自動生成一個名字。
ON DELETE、ON UPDATE表示事件觸發限制,可設引數:
RESTRICT(限 制外表中的外來鍵改動)
CASCADE(跟隨外來鍵改動)c
SET NULL(設空值)
SET DEFAULT(設預設值)
NO ACTION(無動作,預設的)

搞個例子,簡單演示一下使用,做dage和xiaodi兩個表,大哥表是主鍵,小弟表是外來鍵:
建表:

 1 CREATE TABLE  `dage` (
 2
  `id`  int ( 11 NOT NULL  auto_increment,
 3
  `name`  varchar ( 32 default '' ,
 4
PRIMARY KEY   (`id`)
 5
) ENGINE = InnoDB  DEFAULT  CHARSET = latin1;
 6
 7 CREATE TABLE  `xiaodi` (
 8
  `id`  int ( 11
NOT
NULL
 auto_increment,
 9
  `dage_id`  int ( 11 default NULL ,
10
  `name`  varchar ( 32 default '' ,
11
PRIMARY KEY   (`id`),
12
KEY  `dage_id` (`dage_id`),
13
CONSTRAINT  `xiaodi_ibfk_1`  FOREIGN KEY  (`dage_id`)  REFERENCES  `dage` (`id`)
14
) ENGINE = InnoDB  DEFAULT  CHARSET = latin1;

插入個大哥:
1 mysql > insert into  dage(name)  values ( ' 銅鑼灣 ' );
2
Query OK,  1  row affected ( 0.01  sec)
3
mysql > select * from  dage;
4
+ -- --+--------+ 5 |  id  |  name    | 6 + -- --+--------+ 7 | 1 |  銅鑼灣  | 8 + -- --+--------+ 9 1  row  in set  ( 0.00  sec)
插入個小弟:
1 mysql > insert into  xiaodi(dage_id,name)  values ( 1 , ' 銅鑼灣_小弟A ' );
2
Query OK,  1  row affected ( 0.02  sec)
3
4 mysql > select * from  xiaodi;
5
+ -- --+---------+--------------+ 6 |  id  |  dage_id  |  name          | 7 + -- --+---------+--------------+ 8 | 1 | 1 |  銅鑼灣_小弟A  | 9 + -- --+---------+--------------+
把大哥刪除:
1 mysql > delete from  dage  where  id = 1 ;
2
ERROR  1451  ( 23000 ): Cannot  delete or update  a parent row: a  foreign key constraint  fails (`bstar / xiaodi`,  CONSTRAINT  `xiaodi_ibfk_1`  FOREIGN KEY  (`dage_id`)  REFERENCES  `dage` (`id`))


提示:不行呀,有約束的,大哥下面還有小弟,可不能扔下我們不管呀!

插入一個新的小弟:

1 mysql > insert into  xiaodi(dage_id,name)  values ( 2 , ' 旺角_小弟A ' );              
2
ERROR  1452  ( 23000 ): Cannot  add or update  a child row: a  foreign key constraint  fails (`bstar / xiaodi`,  CONSTRAINT  `xiaodi_ibfk_1`  FOREIGN KEY  (`dage_id`)  REFERENCES  `dage` (`id`))
3


提示:小子,想造反呀!你還沒大哥呢!

把外來鍵約束增加事件觸發限制:

 1 mysql >  show  create table  xiaodi;
 2

 3 CONSTRAINT  `xiaodi_ibfk_1`  FOREIGN KEY  (`dage_id`)  REFERENCES  `dage` (`id`)
 4

 5 mysql > alter table  xiaodi  drop foreign key  xiaodi_ibfk_1; 
 6
Query OK,  1  row affected ( 0.04  sec)
 7
Records:  1   Duplicates:  0   Warnings: 
 8
mysql > alter table  xiaodi  add foreign key (dage_id)  references  dage(id)  on delete cascade on update cascade ;
 9
Query OK,  1  row affected ( 0.04  sec)
10
Records:  1   Duplicates:  0   Warnings:  0
再次試著把大哥刪了:
1 mysql > delete from  dage  where  id = 1 ;
2
Query OK,  1  row affected ( 0.01  sec)
3
4 mysql > select * from  dage;
5
Empty  set  ( 0.01  sec)
6
7 mysql > select * from  xiaodi;
8
Empty  set  ( 0.00  sec)



得,這回對應的小弟也沒了,沒辦法,誰讓你跟我on delete cascade了呢!

例子說明的應該蠻清楚了吧,其他功能對應手冊自己實踐吧!:-)

轉自: http://www.cppblog.com/wolf/articles/69089.html