MySql外键学习总结
生活随笔
收集整理的這篇文章主要介紹了
MySql外键学习总结
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
mysql添加外鍵
為已經添加好的數據表添加外鍵:
語法:alter table 表名 add constraint FK_ID foreign key(你的外鍵字段名) REFERENCES 外表表名(
對應的表的主鍵字段名);
例: alter table tb_active add constraint FK_ID foreign key(user_id) REFERENCES tb_user(id)
//FK_ID是外鍵的名稱
/*
CREATE TABLE `tb_active` (
?`id` int(11) NOT NULL AUTO_INCREMENT,
?`title` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
?`content` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
?`user_id` int(11) NOT NULL,
?PRIMARY KEY (`id`),
?KEY `user_id` (`user_id`),
?KEY `user_id_2` (`user_id`),
?CONSTRAINT `FK_ID` FOREIGN KEY (`user_id`) REFERENCES `tb_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
*/
?
刪除外鍵
語法: ALTER TABLE table-name DROP FOREIGN KEY key-id;
例: ? ALTER TABLE `tb_active` DROP FOREIGN KEY `FK_ID`
?
自動鍵更新和刪除:
外鍵可以保證新插入的記錄的完整性,但是,如果在REFERENCES從句中已命名的表刪除記錄會怎么樣?
在使用同樣的值作為外鍵的輔助表中會發生什么?
??
?很明顯,那些記錄也應該被刪除,否則在數據庫中就會有很多無意義的孤立記錄,MYSQL可以通過向
FOREIGN KEY...REFERENCES修飾符添加一個ON DELETE 或ON UPDATE子句簡化任務,它告訴了數據庫在這
種情況如何處理孤立任務
?
?關鍵字 ? ? 含義
?CASCADE ? ?刪除包含與已刪除鍵值有參照關系的所有記錄
?SET NULL ? 修改包含與已刪除鍵值有參照關系的所有記錄,使用NULL值替換(只能用于已標記為NOT?
NULL的字段)
?RESTRICT ? 拒絕刪除要求,直到使用刪除鍵值的輔助表被手工刪除,并且沒有參照時(這是默認設置,
也是最安全的設置)
?NO ACTION ?啥也不做
?
?請注意,通過ON UPDATE 和 ON DELETE規則,設置MYSQL能夠實現自動操作時,如果鍵的關系沒有設置
好,可能會導致嚴重的數據破壞,
?例如:如果一系列的表通過外鍵關系和ON DELETE CASCADE 規則連接時,任意一個主表的變化都會導致
甚至只和原始刪除有一些將要聯系的記錄在沒有警告的情況被刪除,所以,我們在操作之前還要檢查這
些規則的,操作之后還要再次檢查.
?
添加外鍵
alter table locstock add foreign key locstock_ibfk2(stockid) references product(stockid)
locstock 為表名, locstock_ibfk2 為外鍵名 第一個括號里填寫外鍵列名, product為表名,第二個括號
里是寫外鍵關聯的列名
?
刪除外鍵?
alter table locstock drop foreign key locstock_ibfk2
?
查看表有哪些外鍵
show create table locstock
?
[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...) ?
? ? REFERENCES tbl_name (index_col_name, ...) ?
? ? [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}] ?
? ? [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}] ?
?
? ? ? ? ?所有tables必須是InnoDB型 ,它們不能是臨時表。
· ? ? ? ? 在引用表中,必須有一個索引,外鍵列以同樣的順序被列在其中作為第一列。這樣一個索引
如果不存在,它必須在引用表里被自動創建。
· ? ? ? ? 在引用表中,必須有一個索引,被引用的列以同樣的順序被列在其中作為第一列。
· ? ? ? ? 不支持對外鍵列的索引前綴。這樣的后果之一是BLOB和TEXT列不被包括在一個外鍵中, 這
是因為對這些列的索引必須總是包含一個前綴長度。
· ? ? ? ? 如果CONSTRAINTsymbol 被給出,它在數據庫里必須是唯一的。如果它沒有被給出,InnoDB
自動創建這個名字。
========
MySQL中的外鍵是什么、有什么作用
我的疑問是 "使用外鍵約束" ,然后我對 "外鍵" 這個詞不是很理解,查詢相關資料都是講一些術語,
說外鍵的主要作用是:保持數據的一致性、完整性。聽得我是一頭霧水。
關于外鍵,我有自己的一些理解,但是不曉得是否正確,舉個例子來表達我的看法:假如現在需要建立
一個表,一個什么樣的表呢?一個班級的學生個人信息表:
所以在設計的時候,就給表1添加一個外鍵,這個外鍵就是表2中的學號字段,那么這樣表1就是主表,表
2就是子表。所以結合2張表就能保持數據的一致性、完整性(估計就是還原成原來的那張大表吧)。
借著這個例子再談談外鍵的一些事項:
1、表1可以有一個或者多個外鍵,也可以沒有。(如果表1有多個外鍵可不可以是這樣的情況,表2中的
多個字段是表1的外鍵;或者說表1的多個外鍵是在多個表中)
2、這個外鍵可以不是表1的主鍵,但必須是子表的主鍵。(簡單的說就是,如果一個字段是某個表的外
鍵時,那么該字段必須是主鍵)
以上就是我個人對外鍵的理解。
----------------------------------------解---答---糾---
正-----------------------------------------
什么是外鍵
+-------+ ref +-------+
| sub | ------> | main |
+-------+ +-------+
從表(sub)的某列引用(ref)主表(main)的某列的值。比如學生表有個學生編號(sid),分數表中
的學生列(stu)引用學生表的學 生編號,此時對于分數表的 stu 來說,學生表的 sid 就是外鍵。從
表也叫外鍵表,主表也叫主鍵表、外表,列也叫字段。
所以在設計的時候,就給表1添加一個外鍵,這個外鍵就是表2中的學號字段,那么這樣表1就是主表,表
2就是子表。
你的主從關系理解顛倒了。你的圖中,表1的確是主表,表2是子表,但不是叫做給表1添加一個外鍵,而
是給表2添加一個外鍵,表2中的學號 字段就叫外鍵,它是表1學號字段的主鍵。你可以這樣說:表1的學
號字段是表2的外鍵。
外鍵用來干什么
你貼的圖片已經解釋了。為了一張表記錄的數據不要太過冗余。這和軟件工程的模塊化思想差不多類似
,只不過在數據庫中是對表關系進行解耦,盡量讓表 記錄的數據單一化。就如你貼的圖片中,把成績和
學生信息放在一張表中就太冗余了,成績完全可以以學生的id作為區分標識。
為什么說外鍵能保持數據的一致性、完整性
你想想,你的圖中的第一章表分割成了表1和表2,表2的學號引用了表1的學號字段作為外鍵,如果不建
立外鍵,只是和表1一樣單純性 地設立一個學號字段,那么和建立外鍵有什么區別呢?
比如表1中張三的學號為20140900001,那么我在表2中插數據的時候在學號字段插20140900001來記錄張
三的成績不也是做到了表 的解耦了嗎?
這里存在的問題是,在不設置外鍵的情況下,表2的學號字段和表1的學號字段是沒有關聯的。只是你自
己認為他們有關系而已,數據庫并 不認為它倆有關系。也就是說,你在表2的學號字段插了一個值(比
如20140999999),但是這個值在表1中并沒有,這個時候,數據庫還是允 許你插入的,它并不會對插入
的數據做關系檢查。然而在設置外鍵的情況下,你插入表2學號字段的值必須要求在表1的學號字段能找
到。 同時,如果你要刪除表1的某個學號字段,必須保證表2中沒有引用該字段值的列,否則就沒法刪除
。這就是所謂的保持數據的一致性和完整性。你想,如 果表2還引用表1的某個學號,你卻把表1中的這
個學號刪了,表2就不知道這個學號對應的學生是哪個學生。數據的一致性還包括數據類型的一致性(這?
個見下面就知道了)。
外鍵的使用規則
從表的字段必須與外鍵類型相同(如上,分數表 stu 的類型必須和學生表 sid 的類型相同,比如都是?
int(10) 類型)外鍵必須是主表的唯一鍵(如上,學生表 sid 是主鍵,而主鍵是唯一的,所以可以作為
分數表 stu 的外鍵)有關聯的字段(如上,分數表之所以使用學生表的 sid 是因為兩者有關聯,分數
表記錄的是學生的分數,而學生可以用 sid 來唯 一標識)避免使用復合鍵(也就是說從表可以同時引
用多個外表的字段作為一個外鍵,一般不推薦這種做法)
你的問題
如果表1有多個外鍵可不可以是這樣的情況,表2中的多個字段是表1的外鍵;或者說表1的多個外鍵是在
多個表中。
都可以。因為表1的外鍵不一定是表2的主鍵,也可以是唯一鍵(UNIQUE)。比如表2有個主鍵 A,有個唯
一鍵 B,表1兩個字段 A' 和 B’ 分別引用表2的 A 和 B,這就是多對多的關系了。再或者表2主鍵 A,
表3主鍵 B,表1的兩個字段 A' 和 B' 分別引用表2的 A 和表3 的 B。
這個外鍵可以不是表1的主鍵,但必須是子表的主鍵。(簡單的說就是,如果一個字段是某個表的外鍵時
,那么該字段必須是主鍵)
因為你前面就理解錯了,所以這句話本身就是錯的。對于從表來說,外鍵不一定需要作為從表的主鍵,
外鍵也不一定是外表的主鍵,外表的唯一鍵就可以作 為從表的外鍵。
再給一張圖以幫助理解
========
mysql外鍵(FOREIGN KEY)的簡單使用
一、基本概念1、MySQL中“鍵”和“索引”的定義相同,所以外鍵和主鍵一樣也是索引的一種。不同的是MySQL會自動
為所有表的主鍵進行索引,但是外鍵字段必須由用戶進行明確的索引。用于外鍵關系的字段必須在所有
的參照表中進行明確地索引,InnoDB不能自動地創建索引。
2、外鍵可以是一對一的,一個表的記錄只能與另一個表的一條記錄連接,或者是一對多的,一個表的記
錄與另一個表的多條記錄連接。
3、如果需要更好的性能,并且不需要完整性檢查,可以選擇使用MyISAM表類型,如果想要在MySQL中根
據參照完整性來建立表并且希望在此基礎上保持良好的性能,最好選擇表結構為innoDB類型。
4、外鍵的使用條件
① 兩個表必須是InnoDB表,MyISAM表暫時不支持外鍵
② 外鍵列必須建立了索引,MySQL 4.1.2以后的版本在建立外鍵時會自動創建索引,但如果在較早的版
本則需要顯式建立;
③ 外鍵關系的兩個表的列必須是數據類型相似,也就是可以相互轉換類型的列,比如int和tinyint可以
,而int和char則不可以;
5、外鍵的好處:可以使得兩張表關聯,保證數據的一致性和實現一些級聯操作。
二、使用方法
1、創建外鍵的語法:
外鍵的定義語法:
[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(跟隨外鍵改動)
③ SET NULL(設空值)
④ SET DEFAULT(設默認值)
⑤ NO ACTION(無動作,默認的)
2、示例
1)創建表1
create table repo_table(
repo_id char(13) not null primary key,
repo_name char(14) not null)
type=innodb;
創建表2
mysql> create table busi_table(
? ? -> busi_id char(13) not null primary key,
? ? -> busi_name char(13) not null,
? ? -> repo_id char(13) not null,
? ? -> foreign key(repo_id) references repo_table(repo_id))
-> type=innodb;
2)插入數據
insert into repo_table values("12","sz"); //success
insert into repo_table values("13","cd"); //success
insert into busi_table values("1003","cd", "13"); //success
insert into busi_table values("1002","sz", "12"); //success
insert into busi_table values("1001","gx", "11"); //failed,提示:
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails?
(`smb_man`.`busi_table`, CONSTRAINT `busi_table_ibfk_1` FOREIGN KEY (`repo_id`) REFERENCES?
`repo_table` (`repo_id`))
3)增加級聯操作
mysql> alter table busi_table
? ? -> add constraint id_check
? ? -> foreign key(repo_id)
? ? -> references repo_table(repo_id)
? ? -> on delete cascade
? ? -> on update cascade;
-----
ENGINE=InnoDB DEFAULT CHARSET=gb2312; //另一種方法,可以替換type=innodb;
3、相關操作
外鍵約束(表2)對父表(表1)的含義:
? ? 在父表上進行update/delete以更新或刪除在子表中有一條或多條對應匹配行的候選鍵時,父表的行
為取決于:在定義子表的外鍵時指定的on update/on delete子句。
關鍵字
含義
CASCADE
刪除包含與已刪除鍵值有參照關系的所有記錄
SET NULL
修改包含與已刪除鍵值有參照關系的所有記錄,使用NULL值替換(只能用于已標記為NOT NULL的字段)
RESTRICT
拒絕刪除要求,直到使用刪除鍵值的輔助表被手工刪除,并且沒有參照時(這是默認設置,也是最安全的
設置)
NO ACTION
啥也不做
4、其他
在外鍵上建立索引:
index repo_id (repo_id),
foreign key(repo_id) references repo_table(repo_id))
========
鏈接
【1】 w3school關于mysql的專題講解http://www.w3school.com.cn/sql/sql_foreignkey.asp
【2】 MySQL C API programming tutorial
http://zetcode.com/tutorials/mysqlcapitutorial/
【3】 對外鍵的使用示例,很不錯
http://hi.baidu.com/wangzhiqing999/blog/item/08761705954e18c4267fb523.html
http://www.cppblog.com/wolf/articles/69089.html
【4】 mysql官網英文網站
http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
中文網站
http://dev.mysql.com/doc/refman/5.1/zh/sql-syntax.html
【5】 對外鍵講解的比較全面,可以一讀
http://www.xiaoxiaozi.com/2009/07/12/1158/
http://feidaodalian.iteye.com/blog/550179
總結
以上是生活随笔為你收集整理的MySql外键学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ecshop
- 下一篇: oracle存储过程模板