mysql foreign key(外鍵) 說明與實例

mysql foreign key(外鍵) 說明與實例

一,什麼是foreign key,及其完整性html

我的以爲,foreign key就是表與表之間的某種約定的關係,因爲這種關係的存在,咱們可以讓表與表之間的數據,更加的完整,關連性更強。關於完整性,關連性我舉個例子,你們就會明白了。mysql

有二張表,一張是用戶表,一張是訂單表:sql

1,若是我刪除了用戶表裏的用戶,那麼訂單表裏面根這個用戶有關的數據,就成了無頭數據了,不完整了。數據庫

2,若是我在訂單表裏面,隨便插入了一條數據,這個訂單在用戶表裏面,沒有與之對應的用戶。這樣數據也不完整了。post

若是有外鍵的話,就方便多了,能夠不讓用戶刪除數據,或者刪除用戶的話,經過外鍵一樣刪除訂單表裏面的數據,這樣也能讓數據完整。spa

二,使用foreign key,遵照如下幾點規則code

1,有外鍵約束的表,必須是innodb型htm

2,外鍵約束的二個表,原本就相關係的表,而且要有索引關係,若是沒有,建立外鍵時也能夠建立索引。blog

3,不支持對外鍵列的索引前綴。這樣的後果之一是BLOB和TEXT列不被包括在一個外鍵中,這是由於對這些列的索引必須老是包含一個前綴長度。索引

4,mysql外鍵的名子在數據庫內要是惟一的

三,建立foreign key的語法規則

[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}]

四,外鍵維護數據完整性的5種方式

1,CASCADE: 從父表刪除或更新且自動刪除或更新子表中匹配的行。ON DELETE CASCADE和ON UPDATE CASCADE均可用。在兩個表之間,你不該定義若干在父表或子表中的同一列採起動做的ON UPDATE CASCADE子句。

2,SET NULL: 從父表刪除或更新行,並設置子表中的外鍵列爲NULL。若是外鍵列沒有指定NOT NULL限定詞,這就是惟一合法的。ON DELETE SET NULL和ON UPDATE SET NULL子句被支持。

3,NO ACTION: 在ANSI SQL-92標準中,NO ACTION意味這不採起動做,就是若是有一個相關的外鍵值在被參考的表裏,刪除或更新主要鍵值的企圖不被容許進行(Gruber, 掌握SQL, 2000:181)。 InnoDB拒絕對父表的刪除或更新操做。

4,RESTRICT: 拒絕對父表的刪除或更新操做。NO ACTION和RESTRICT都同樣,刪除ON DELETE或ON UPDATE子句。(一些數據庫系統有延期檢查,而且NO ACTION是一個延期檢查。在MySQL中,外鍵約束是被當即檢查的,因此NO ACTION和RESTRICT是一樣的)。

5,SET DEFAULT: 這個動做被解析程序識別,但InnoDB拒絕包含ON DELETE SET DEFAULT或ON UPDATE SET DEFAULT子句的表定義。

五,實例說明foreign key的用法

  1. mysql> CREATE TABLE `user` (                   //建立用戶表  
  2.  ->   `id` int(11) NOT NULL auto_increment COMMENT '用戶ID',  
  3.  ->   `name` varchar(50) NOT NULL default '' COMMENT '名稱',  
  4.  ->   `sex` int(1) NOT NULL default '0' COMMENT '0爲男,1爲女',  
  5.  ->   PRIMARY KEY  (`id`)  
  6.  -> ) ENGINE=innodb  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;   //innodb引擎  
  7. Query OK, 0 rows affected, 1 warning (0.11 sec)  
  8.   
  9. mysql> insert into user (name,sex)values("tank",1),("zhang",2);   //插入二條數據  
  10. Query OK, 2 rows affected (0.00 sec)  
  11. Records: 2  Duplicates: 0  Warnings: 0  
  12.   
  13. mysql> create table `order` (              //建立訂單表  
  14.  ->  `order_id` int(11) not null auto_increment comment '訂單ID',  
  15.  ->  `u_id` int(11) not null default '0' comment '用戶ID',  
  16.  ->  `username` varchar(50) not null default '' comment '用戶名',  
  17.  ->  `money` int(11) not null default '0' comment '錢數',  
  18.  ->  `datetime` timestamp not null default current_timestamp comment '生成時 
  19. 間',  
  20.  ->  primary key(`order_id`),  
  21.  ->  index (`u_id`),  
  22.  ->  FOREIGN KEY order_f_key (u_id) REFERENCES user(id)     //建立外鍵  
  23.  -> )ENGINE=innodb  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;    //innodb引擎  
  24. Query OK, 0 rows affected, 1 warning (0.06 sec)  
  25.   
  26. mysql> INSERT INTO `order` (`u_id`, `username`, `money`, `datetime`) VALUES ('1''tank','2222',  
  27.  CURRENT_TIMESTAMP);      //插入一條訂單  
  28. Query OK, 1 row affected (0.00 sec)  
  29.   
  30. mysql> delete from user where id =1;    //刪除用戶1,不給刪除,由於order表裏面有和這條數據有關連的數據  
  31. ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`test/order`, CONSTRAINT `order_ibfk_1` FOREIGN KEY (`u_id`) REFERENCES `user` (`id`))  
  32.   
  33. //下面在order裏面插入一條數據u_id爲5用戶,在user表裏面根本沒有,因此插入不進去。  
  34. mysql> INSERT INTO `order` (`u_id`, `username`, `money`, `datetime`) VALUES ('5''good','123',  CURRENT_TIMESTAMP);  
  35. ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test/order`, CONSTRAINT `order_ibfk_1` FOREIGN KEY (`u_id`) REFERENCES `user` (`id`))  
  36.   
  37. //把u_id改爲2就能夠插進去了,由於user表裏面有id=2的用戶  
  38. mysql> INSERT INTO `order` (`u_id`, `username`, `money`, `datetime`) VALUES ('2''zhang','3452',  CURRENT_TIMESTAMP);  
  39. Query OK, 1 row affected (0.00 sec)  
  40.   
  41. mysql> show create table `order`\G;     //查看建立表的數據,爲的是查看foreign key的名子,還有order二邊要有`這個符號  
  42. *************************** 1. row ***************************  
  43.  Table: order  
  44. Create Table: CREATE TABLE `order` (  
  45.  `order_id` int(11) NOT NULL auto_increment COMMENT '訂單ID',  
  46.  `u_id` int(11) NOT NULL default '0' COMMENT '用戶ID',  
  47.  `username` varchar(50) NOT NULL default '' COMMENT '用戶名',  
  48.  `money` int(11) NOT NULL default '0' COMMENT '錢數',  
  49.  `datetime` timestamp NOT NULL default CURRENT_TIMESTAMP COMMENT '生成時間',  
  50.  PRIMARY KEY  (`order_id`),  
  51.  KEY `u_id` (`u_id`),  
  52.  CONSTRAINT `order_ibfk_1` FOREIGN KEY (`u_id`) REFERENCES `user` (`id`)  
  53. ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8  
  54. 1 row in set (0.00 sec)  
  55.   
  56. ERROR:  
  57. No query specified  
  58.   
  59. mysql> alter table `order` drop foreign key order_ibfk_1;   //刪除foreign key,mysql裏面沒有修改foreign key的命令  
  60. Query OK, 2 rows affected (0.10 sec)  
  61. Records: 2  Duplicates: 0  Warnings: 0  
  62.   
  63. //刪除後在新增  
  64. mysql> alter table `order` add foreign key(u_id) references user(id) on delete cascade on update cascade;  
  65. Query OK, 2 rows affected (0.00 sec)  
  66. Records: 2  Duplicates: 0  Warnings: 0  
  67.   
  68. mysql> update user set id=6 where id=1;     //更新user表裏面的id  
  69. Query OK, 1 row affected (0.05 sec)  
  70. Rows matched: 1  Changed: 1  Warnings: 0  
  71.   
  72. mysql> select * from `order` where u_id=6;   //order表裏面的數據,也根着改變了。  
  73. +----------+------+----------+-------+---------------------+  
  74. | order_id | u_id | username | money | datetime            |  
  75. +----------+------+----------+-------+---------------------+  
  76. |        2 |    6 | tank     |  2222 | 2010-11-25 22:18:57 |  
  77. +----------+------+----------+-------+---------------------+  
  78. 1 row in set (0.00 sec)  

foreign key只能用於innodb,而且對數據進行操做時,會對外鍵關聯的表進行檢索,會影響效率的。因此對外鍵的使用,要根據我的的實際狀況。

做者:海底蒼鷹
地址:http://blog.51yip.com/mysql/1136.html
相關文章
相關標籤/搜索