MySQL中外鍵約束

2021-08-30 20:32:56 字數 3816 閱讀 2198

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

如果在父表中找不到候選鍵,則不允許在子表上進行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則不可以 ...