MariaDB數據庫的外鍵約束實例代碼介紹詳解
文章主要給大家介紹了關于MariaDB數據庫的外鍵約束的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧...
文章主要給大家介紹了關于MariaDB數據庫的外鍵約束的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧
外鍵
外鍵的用途是確保數據的完整性。它通常包括以下幾種:
1 實體完整性,確保每個實體是唯一的(通過主鍵來實施)
2 域完整性,確保屬性值只從一套特定可選的集合里選擇
3 關聯完整性,確保每個外鍵或是NULL(如果允許的話)或含有與相關主鍵值相配的值
1.什么是外鍵約束
與主鍵約束不同,創建外鍵約束不會自動創建對應的索引。 但是由于以下原因,對外鍵手動創建索引通常是有用的:
當在查詢中組合相關表中的數據時,經常在聯接條件中使用外鍵列,方法是將一個表的外鍵約束中的一列或多列與另一個表中的主鍵列或唯一鍵列匹配。 索引使 數據庫引擎 可以在外鍵表中快速查找相關數據。 但是,創建此索引并不是必需的。 即使沒有對兩個相關表定義主鍵或外鍵約束,也可以對來自這兩個表中的數據進行組合,但兩個表間的外鍵關系說明已用其鍵作為條件對其進行了優化,以便組合到查詢中。
對主鍵約束的更改可由相關表中的外鍵約束檢查。
外鍵約束(foreign key)就是表與表之間的某種約定的關系,由于這種關系的存在,我們能夠讓表與表之間的數據,更加的完整,關連性更強。
關于數據表的完整性和關連性,可以舉個例子
有二張表,一張是用戶表,一張是訂單表:
1.如果我刪除了用戶表里的用戶,那么訂單表里面跟這個用戶有關的數據,就成了無頭數據了,不完整了。
2.如果我在訂單表里面,隨便插入了一條數據,這個訂單在用戶表里面,沒有與之對應的用戶。這樣數據也不完整了。
如果有外鍵的話,就方便多了,可以不讓用戶刪除數據,或者刪除用戶的話,通過外鍵同樣刪除訂單表里面的數據,這樣也能讓數據完整。
通過外鍵約束,每次插入或更新數據表時,都會檢查數據的完整性。
2.創建外鍵約束
2.1 方法一:通過create table創建外鍵
語法:
createtable數據表名稱(...,[CONSTRAINT[約束名稱]]FOREIGNKEY[外鍵字段]REFERENCES[外鍵表名](外鍵字段,外鍵字段2…..)[ONDELETECASCADE][ONUPDATECASCADE])
參數的解釋:
RESTRICT: 拒絕對父表的刪除或更新操作。
CASCADE: 從父表刪除或更新且自動刪除或更新子表中匹配的行。ON DELETE CASCADE和ON UPDATE CASCADE都可用
注意:on update cascade是級聯更新的意思,on delete cascade是級聯刪除的意思,意思就是說當你更新或刪除主鍵表,那外鍵表也會跟隨一起更新或刪除。
精簡化后的語法:
foreignkey當前表的字段references外部表名 (關聯的字段) type=innodb
2.1.1 插入測試數據
例子:我們創建一個數據庫,包含用戶信息表和訂單表
MariaDB [book]>createdatabasemarket; # 創建market數據庫Query OK, 1 row affected (0.00 sec)MariaDB [book]> use market; # 使用market數據庫DatabasechangedMariaDB [market]>createtableuserprofile(idint(11)notnullauto_increment,namevarchar(50)notnulldefault'', sexint(1)notnulldefault'0',primarykey(id))ENGINE=innodb; # 創建userprofile數據表,指定使用innodb引擎Query OK, 0rowsaffected (0.07 sec)MariaDB [market]>createtableuser_order(o_idint(11) auto_increment, u_idint(11)default'0', usernamevarchar(50), moneyint(11),primarykey(o_id),index(u_id),foreignkeyorder_f_key(u_id)referencesuserprofile(id)ondeletecascadeonupdatecascade); # 創建user_order數據表,同時為user_order表的u_id字段做外鍵約束,綁定userprofile表的id字段Query OK, 0rowsaffected (0.04 sec)MariaDB [market]>insertintouserprofile(name,sex)values('HA',1),('LB',2),('HPC',1); # 向userprofile數據表插入三條記錄Query OK, 3rowsaffected (0.01 sec)Records: 3 Duplicates: 0 Warnings: 0MariaDB [market]>select*fromuserprofile; # 查詢userprofile數據表的所有記錄+----+------+-----+| id |name| sex |+----+------+-----+| 1 | HA | 1 || 2 | LB | 2 || 3 | HPC | 1 |+----+------+-----+3rowsinset(0.00 sec)MariaDB [market]>insertintouser_order(u_id,username,money)values(1,'HA',234),(2,'LB',146),(3,'HPC',256); # 向user_order數據表插入三條記錄Query OK, 3rowsaffected (0.02 sec)Records: 3 Duplicates: 0 Warnings: 0MariaDB [market]>select*fromuser_order; # 查詢user_order數據表的所有記錄+------+------+----------+-------+| o_id | u_id | username | money |+------+------+----------+-------+| 1 | 1 | HA | 234 || 2 | 2 | LB | 146 || 3 | 3 | HPC | 256 |+------+------+----------+-------+3rowsinset(0.00 sec)MariaDB [market]>selectid,name,sex,money,o_idfromuserprofile,user_orderwhereid=u_id; # 聯表查詢+----+------+-----+-------+------+| id |name| sex | money | o_id |+----+------+-----+-------+------+| 1 | HA | 1 | 234 | 1 || 2 | LB | 2 | 146 | 2 || 3 | HPC | 1 | 256 | 3 |+----+------+-----+-------+------+3rowsinset(0.03 sec)
2.1.2 測試級聯刪除
MariaDB [market]>deletefromuserprofilewhereid=1; # 刪除user表中id為1的數據Query OK, 1 row affected (0.01 sec)MariaDB [market]>selectid,name,sex,money,o_idfromuserprofile,user_orderwhereid=u_id;+----+------+-----+-------+------+| id |name| sex | money | o_id |+----+------+-----+-------+------+| 2 | LB | 2 | 146 | 2 || 3 | HPC | 1 | 256 | 3 |+----+------+-----+-------+------+2rowsinset(0.00 sec)MariaDB [market]>select*fromuser_order; # 查看order表的數據+------+------+----------+-------+| o_id | u_id | username | money |+------+------+----------+-------+| 2 | 2 | LB | 146 || 3 | 3 | HPC | 256 |+------+------+----------+-------+3rowsinset(0.00 sec)
2.1.3 測試級聯更新
更新數據之前的狀態
MariaDB [market]>select*fromuserprofile; # 查看userprofile表的數據+----+------+-----+| id |name| sex |+----+------+-----+| 2 | LB | 2 || 3 | HPC | 1 |+----+------+-----+3rowsinset(0.00 sec)MariaDB [market]>select*fromuser_order; # 查看order表的數據+------+------+----------+-------+| o_id | u_id | username | money |+------+------+----------+-------+| 2 | 2 | LB | 146 || 3 | 3 | HPC | 256 |+------+------+----------+-------+3rowsinset(0.00 sec)
更新數據?
MariaDB [market]>updateuserprofilesetid=6whereid=2; # 把userprofile數據表中id為2的用戶改為id為6Query OK, 1 row affected (0.02 sec)Rowsmatched: 1 Changed: 1 Warnings: 0
更新數據后的狀態?
MariaDB [market]>selectid,name,sex,money,o_idfromuserprofile,user_orderwhereid=u_id; # 聯表查詢,可以看出表中已經沒有id為2的用戶了+----+------+-----+-------+------+| id |name| sex | money | o_id |+----+------+-----+-------+------+| 6 | LB | 2 | 146 | 2 || 3 | HPC | 1 | 256 | 3 |+----+------+-----+-------+------+2rowsinset(0.00 sec)MariaDB [market]>select*fromuserprofile; # 查看userprofile表的數據,id只剩下3和6+----+------+-----+| id |name| sex |+----+------+-----+| 3 | HPC | 1 || 6 | LB | 2 |+----+------+-----+2rowsinset(0.00 sec)MariaDB [market]>select*fromuser_order; # 查看user_order表的數據,u_id也改為6+------+------+----------+-------+| o_id | u_id | username | money |+------+------+----------+-------+| 2 | 6 | LB | 146 || 3 | 3 | HPC | 256 |+------+------+----------+-------+2rowsinset(0.00 sec)
2.1.4 測試數據完整性
MariaDB [market]>insertintouser_order(u_id,username,money)values(5,"XJ",345); # 單獨向user_order數據表中插入數據,插入數據失敗ERROR 1452 (23000): Cannotaddorupdatea child row: aforeignkeyconstraintfails (`market`.`user_order`,CONSTRAINT`user_order_ibfk_1`FOREIGNKEY(`u_id`)REFERENCES`userprofile` (`id`)ONDELETECASCADEONUPDATECASCADE)
在上面的例子中,user_order表的外鍵約束,user_order表受userprofile表的約束
在user_order里面插入一條數據u_id為5用戶,在userprofile表里面根本沒有,所以插入數據失敗
先向userprofile表中插入記錄,再向user_order表中插入記錄就可以了
MariaDB [market]>insertintouserprofilevalues(5,"XJ",1); # 先向userprofile數據表中插入id為5的記錄,插入數據成功Query OK, 1 row affected (0.01 sec)MariaDB [market]>insertintouser_order(u_id,username,money)values(5,"XJ",345); # 再向user_order數據表中插入數據,成功Query OK, 1 row affected (0.00 sec)MariaDB [market]>select*fromuserprofile; # 查詢userprofile數據表中的所有記錄+----+------+-----+| id |name| sex |+----+------+-----+| 3 | HPC | 1 || 5 | XJ | 1 || 6 | LB | 2 |+----+------+-----+3rowsinset(0.00 sec)MariaDB [market]>select*fromuser_order; # 查詢user_order數據表中的所有記錄+------+------+----------+-------+| o_id | u_id | username | money |+------+------+----------+-------+| 2 | 6 | LB | 146 || 3 | 3 | HPC | 256 || 5 | 5 | XJ | 345 |+------+------+----------+-------+3rowsinset(0.01 sec)
2.2 方法二:通過alter table創建外鍵和級聯更新,級聯刪除
語法:
altertable數據表名稱add[constraint[約束名稱] ]foreignkey(外鍵字段,..)references數據表(參照字段,...)[onupdatecascade|setnull|noaction][ondeletecascade|setnull|noaction])
例子:
MariaDB [market]>createtableuser_order1(o_idint(11) auto_increment,u_idint(11)default"0",usernamevarchar(50),moneyint(11),primarykey(o_id),index(u_id)); # 創建user_order1數據表,創建表時不使用外鍵約束Query OK, 0rowsaffected (0.11 sec)MariaDB [market]> showcreatetableuser_order1; # 查看user_order1數據表的創建信息,沒有外鍵約束+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|Table|CreateTable|+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| user_order1 |CREATETABLE`user_order1` (`o_id`int(11)NOTNULLAUTO_INCREMENT,`u_id`int(11)DEFAULT'0',`username`varchar(50)COLLATEutf8_unicode_ciDEFAULTNULL,`money`int(11)DEFAULTNULL,PRIMARYKEY(`o_id`),KEY`u_id` (`u_id`)) ENGINE=InnoDBDEFAULTCHARSET=utf8COLLATE=utf8_unicode_ci |+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+1 rowinset(0.01 sec)MariaDB [market]>altertableuser_order1addforeignkey(u_id)referencesuserprofile(id)ondeletecascadeonupdatecascade; # 使用alter修改user_order1數據表,為user_order1數據表添加外鍵約束Query OK, 0rowsaffected (0.05 sec)Records: 0 Duplicates: 0 Warnings: 0MariaDB [market]> showcreatetableuser_order1; # 查看user_order1數據表的創建信息,已經添加了外鍵約束+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|Table|CreateTable|+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| user_order1 |CREATETABLE`user_order1` (`o_id`int(11)NOTNULLAUTO_INCREMENT,`u_id`int(11)DEFAULT'0',`username`varchar(50)COLLATEutf8_unicode_ciDEFAULTNULL,`money`int(11)DEFAULTNULL,PRIMARYKEY(`o_id`),KEY`u_id` (`u_id`),CONSTRAINT`user_order1_ibfk_1`FOREIGNKEY(`u_id`)REFERENCES`userprofile` (`id`)ONDELETECASCADEONUPDATECASCADE) ENGINE=InnoDBDEFAULTCHARSET=utf8COLLATE=utf8_unicode_ci |+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+1 rowinset(0.00 sec)
3.刪除外鍵
語法
altertable數據表名稱dropforeignkey約束(外鍵)名稱
例子:
MariaDB [market]> showcreatetableuser_order1; # 查看user_order1數據表的創建信息,包含外鍵約束+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|Table|CreateTable|+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| user_order1 |CREATETABLE`user_order1` (`o_id`int(11)NOTNULLAUTO_INCREMENT,`u_id`int(11)DEFAULT'0',`username`varchar(50)COLLATEutf8_unicode_ciDEFAULTNULL,`money`int(11)DEFAULTNULL,PRIMARYKEY(`o_id`),KEY`u_id` (`u_id`),CONSTRAINT`user_order1_ibfk_1`FOREIGNKEY(`u_id`)REFERENCES`userprofile` (`id`)ONDELETECASCADEONUPDATECASCADE) ENGINE=InnoDBDEFAULTCHARSET=utf8COLLATE=utf8_unicode_ci |+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+1 rowinset(0.00 sec)MariaDB [market]>altertableuser_order1dropforeignkeyuser_order1_ibfk_1; # 為user_order1數據表刪除外鍵約束,外鍵名稱必須與從`showcreatetableuser_order1`語句中查到的相同Query OK, 0rowsaffected (0.05 sec)Records: 0 Duplicates: 0 Warnings: 0MariaDB [market]> showcreatetableuser_order1; # 查看user_order1數據表的創建信息,外鍵約束已經被刪除了+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+|Table|CreateTable|+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| user_order1 |CREATETABLE`user_order1` (`o_id`int(11)NOTNULLAUTO_INCREMENT,`u_id`int(11)DEFAULT'0',`username`varchar(50)COLLATEutf8_unicode_ciDEFAULTNULL,`money`int(11)DEFAULTNULL,PRIMARYKEY(`o_id`),KEY`u_id` (`u_id`)) ENGINE=InnoDBDEFAULTCHARSET=utf8COLLATE=utf8_unicode_ci |+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+1 rowinset(0.00 sec)
4.使用外鍵約束的條件
要想外鍵創建成功,必須滿足以下4個條件:
1、確保參照的表和字段存在。
2、組成外鍵的字段被索引。
3、必須使用type指定存儲引擎為:innodb.
4、外鍵字段和關聯字段,數據類型必須一致。
5.使用外鍵約束需要的注意事項
1.on delete cascade on update cascade 添加級聯刪除和更新:
2.確保參照的表userprofile中id字段存在。
3.確保組成外鍵的字段u_id被索引
4.必須使用type指定存儲引擎為:innodb。
5.外鍵字段和關聯字段,數據類型必須一致。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值。
Windows10系統下MariaDB數據庫安裝教程圖解
文章給大家介紹Windows10系統下安裝MariaDB 的教程圖解,感興趣的朋友一起看看吧,MariaDB由MySQL的創始人麥克爾·維德紐斯主導開發,...
Mysql數據庫大表優化方案和Mysql大表優化步驟
當MySQL單表記錄數過大時,增刪改查性能都會急劇下降,可以參考以下步驟來優化。單表優化 除非單表數據未來會一直不斷上漲,否則不要一開始就考慮拆分,拆分會帶來邏輯、部...
Mysql數據庫創建存儲過程實現往數據表中新增字段的方法
本文實例講述了mysql創建存儲過程實現往數據表中新增字段的方法,結合實例形式對比分析了通過存儲過程新增字段相關操作技巧,需要的朋友可以參考下。...
Mysql數據庫自定義函數的定義、使用方法及操作注意事項
文章主要介紹了MySQL自定義函數簡單用法,結合實例形式分析了mysql自定義函數的基本定義、使用方法及操作注意事項,需要的朋友可以參考下。...
Mysql數據庫的max_allowed_packet設定方法
小編為大家分享一篇關于Mysql的max_allowed_packet設定,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...
Mysql數據庫亂碼出現的各個階段以及對應方法
MySQL中數據庫亂碼一般進行字符集的設定即可,但是亂碼可以出現在各個階段,所以這篇文章整理一下亂碼出現的各個階段以及對應方法。...
MySQL數據庫的事務處理用法與實例代碼詳解
文章主要介紹了mysql事務處理用法與實例代碼詳解,詳細的介紹了事物的特性和用法并實現php和mysql事務處理例子,非常具有實用價值,需要的朋友可以參考下...
Mysql數據庫使用from與join兩表查詢的方法區別總結
文章主要給大家介紹了關于mysql使用from與join兩表查詢的區別的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面...
Sql Server數據庫類似正則表達式的字符處理問題
SQL Serve提供了簡單的字符模糊匹配功能,比如:like, patindex,不過對于某些字符處理場景還顯得并不足夠,日常碰到的幾個問題有:...
SQL Server數據庫中表和索引結構存儲的原理及如何加快搜索速度分析
本文詳細分析了SQL Server中表和索引結構存儲的原理以及對于如何加快搜索速度和提高效率等方面做了詳細的分析,以下是主要內容。...

