外來鍵的好處:可以使得兩張表關聯,保證資料的一致性和實現一些級聯操作;
如果在父表中找不到候選鍵,則不允許在子表上進行insert/update
外來鍵定義服從下列情況:
· 所有tables必須是innodb型,它們不能是臨時表。
· 在引用表中,必須有乙個索引,外來鍵列以同樣的順序被列在其中作為第一列。這樣乙個索引如果不存在,它必須在引用表裡被自動建立。
· 在引用表中,必須有乙個索引,被引用的列以同樣的順序被列在其中作為第一列。
· 不支援對外鍵列的索引字首。這樣的後果之一是blob和text列不被包括在乙個外來鍵中,這是因為對這些列的索引必須總是包含乙個字首長度。
· 如果constraintsymbol被給出,它在資料庫裡必須是唯一的。如果它沒有被給出,innodb自動建立這個名字。
外來鍵的定義語法:
[constraint symbol] foreign key [id] (index_col_name, ...)
references tbl_name (index_col_name, ...)
[on delete ]
[on update ]
該語法可以在 create table 和 alter table 時使用,如果不指定constraint symbol,mysql會自動生成乙個名字。
on delete、on update表示事件觸發限制,可設引數:
restrict(限制外表中的外來鍵改動)
cascade(在父表上update/delete記錄時,同步update/delete掉子表的匹配記錄)
set null(在父表上update/delete記錄時,將子表上匹配記錄的列設為null
要注意子表的外來鍵列不能為not null )
set default(設預設值)
no action(無動作,預設的,如果子表中有匹配的記錄,則不允許對父表對應候選鍵進行update/delete操作)
注意:trigger不會受外來鍵cascade行為的影響,即不會解發trigger
簡單演示一下使用,做dage和xiaodi兩個表,大哥表是主鍵,小弟表是外來鍵:
建表:
create table `dage` (
`id` int(11) not null auto_increment,
`name` varchar(32) default '',
primary key (`id`)
) engine=innodb default charset=latin1;
create table `xiaodi` (
`id` int(11) not null auto_increment,
`dage_id` int(11) default null,
`name` varchar(32) default '',
primary key (`id`),
key `dage_id` (`dage_id`),
constraint `xiaodi_ibfk_1` foreign key (`dage_id`) references `dage` (`id`)
) engine=innodb default charset=latin1
插入個大哥:
mysql> insert into dage(name) values('銅鑼灣');
query ok, 1 row affected (0.01 sec)
mysql> select * from dage;
+----+--------+
| id | name |
+----+--------+
| 1 | 銅鑼灣 |
+----+--------+
1 row in set (0.00 sec)
插入個小弟:
mysql> insert into xiaodi(dage_id,name) values(1,'銅鑼灣_小弟a');
query ok, 1 row affected (0.02 sec)
mysql> select * from xiaodi;
+----+---------+--------------+
| id | dage_id | name |
+----+---------+--------------+
| 1 | 1 | 銅鑼灣_小弟a |
+----+---------+--------------+
把大哥刪除:
mysql> delete from dage where id=1;
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`))
插入乙個新的小弟:
mysql> insert into xiaodi(dage_id,name) values(2,'旺角_小弟a');
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`))
把外來鍵約束增加事件觸發限制:
mysql> show create table xiaodi;
constraint `xiaodi_ibfk_1` foreign key (`dage_id`) references `dage` (`id`)
mysql> alter table xiaodi drop foreign key xiaodi_ibfk_1;
query ok, 1 row affected (0.04 sec)
records: 1 duplicates: 0 warnings:
mysql> alter table xiaodi add foreign key(dage_id) references dage(id) on delete cascade on update cascade;
query ok, 1 row affected (0.04 sec)
records: 1 duplicates: 0 warnings: 0
再次試著把大哥刪了:
mysql> delete from dage where id=1;
query ok, 1 row affected (0.01 sec)
mysql> select * from dage;
empty set (0.01 sec)
mysql> select * from xiaodi;
empty set (0.00 sec)
得,這回對應的小弟也沒了,沒辦法,誰讓你跟我on delete cascade了呢!
例子參考:
MySQL中 外來鍵約束
alter table yourtablename add constraint 外鍵名 foreign key id index col name,references tbl name index col name,on delete on update 說明 on delete on upda...
Oracle中外鍵約束問題
關於資料結構的外來鍵約束,一般來說,在開發系統的過程中,外來鍵約束遇到的問題較少,但是在移植程式,公升級程式的過程中,外來鍵約束對程式設計師的困擾尤其嚴重,如果子表a中的乙個欄位同主表b的字段有外來鍵關係,如果b表沒有新增對應的資料,那麼在操作a表的過程中就容易出現外來鍵約束錯誤提示,這樣的情況他一...
Mysql的5中外鍵約束方式
何為外來鍵?如果表a的主關鍵字是表b中的字段,則該字段稱為表b的外來鍵,表a稱為主表,表b稱為子表 從表 注 兩個表必須是innodb表,myisam表暫時不支援外來鍵 外來鍵關係的兩個表的列必須是資料型別相似,也就是可以相互轉換型別的列,比如int和tinyint可以,而int和char則不可以 ...