為什麼現在大家都不用外來鍵了(二)?

KunlunDB發表於2022-01-21
前言


MySQL外來鍵(FOREIGNKEY)是表的一個特殊欄位,用來建立主表與從表的關聯關係,為兩個表的資料建立連線,約束兩個表中資料的一致性和完整性。

之前的第一篇文章相關文章( 「技術討論」為什麼大家很少使用外來鍵了? ),總結了一些不使用外來鍵的場景以及使用外來鍵的優勢之處。

本篇文章會基於例項來說明外來鍵約束雖會保證表間資料的關係“始終完整一致”,但在實際操作中,每次做DELETE 或者UPDATE都必須考慮外來鍵約束,會導致開發的時候很痛苦。

保持資料的一致性和完整性 ,主要體現在下面兩個方面:

阻止執行

  • 從表插入新行,其外來鍵值不是主表的主鍵值便阻止插入;


  • 從表修改外來鍵值,新值不是主表的主鍵值便阻止修改;


  • 主表刪除行,其主鍵值在從表裡存在便阻止刪除(要想刪除,必須先刪除從表的相關行);


  • 主表修改主鍵值,舊值在從表裡存在便阻止修改(要想修改,必須先刪除從表的相關行)。


級聯執行

  • 主表刪除行,連帶從表的相關行一起刪除;


  • 主表修改主鍵值,連帶從表相關行的外來鍵值一起修改。

 
下面我們舉個例子來說明一下:
 
1. 建立兩個table,“教練”和“學員”,table“學員”帶有外來鍵約束。
    
    
    
    CREATE 
    
    TABLE jiaolian(
    
       
    
    `jiaolian_id` 
    INT AUTO_INCREMENT,
    
       
    
    `jiaolian_name` 
    VARCHAR(
    
    30),
    
       
    PRIMARY 
    
    KEY (
    
    `jiaolian_id`));
    
    
    
    CREATE TABLE xueyuan(   `xueyuan_id` INT AUTO_INCREMENT,   `jiaolian_id` INT,   `xueyuan_name` VARCHAR( 30),   FOREIGN KEY ( `jiaolian_id`) REFERENCES ` jiaolian` ( `jiaolian_id`),     PRIMARY  KEY ( `xueyuan_id`));
     
    2.  增加兩個“教練”,兩個“學員”。
      insert into jiaolian(jiaolian_name) values("司機老李");insert into jiaolian(jiaolian_name) values("司機老林");insert into xueyuan(jiaolian_id,xueyuan_name) values(1,"徒弟張三");insert into xueyuan(jiaolian_id,xueyuan_name) values(2,"徒弟李四");

      3. 再增加一個“學員”,不存在的 jiaolian_id,執行失敗了。
        insert into xueyuan(jiaolian_id,xueyuan_name) values(3,"徒弟王五");  #error

        4.  刪除一個“教練”,“教練”有關聯的“學員”,執行失敗。
          delete from jiaolian where jiaolian_name="司機老李";  #error

          5.  先刪除 “教練 關聯的 “學員 ,再刪除 “教練 ,執行成功。
            delete from xueyuan where xueyuan_name="徒弟張三";delete from jiaolian where jiaolian_name="司機老李";
             
            結論

            透過這個例子,我們可以看到,外來鍵約束會保證表間資料的關係“始終完整一致”。


            雖然將資料的一致性和完整性判斷託付給了資料庫完成,減少了程式的程式碼量。但在實際操作中,每次做DELETE 或者UPDATE都必須考慮外來鍵約束,會導致開發的時候很痛苦,測試資料極為不方便。


            在使用外來鍵的情況下,每次修改資料都需要去另外一個表檢查資料,需要獲取額外的鎖。

            在高併發大流量事務場景,使用外來鍵可能容易造成死鎖,以及資料庫資源出現瓶頸,所以一般網際網路行業高頻率高併發不建議使用。


            一般來說,在業務程式碼中實現的時候,只要在應用層按照設計之初的這種固有關聯邏輯,來處理資料即可,並不需要在資料庫層面進行外來鍵約束。

            END


            來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70011764/viewspace-2853168/,如需轉載,請註明出處,否則將追究法律責任。

            相關文章