外鍵
數據庫中的表必須符合規範,才能杜絕數據冗餘、插入異常、刪除異常等現象。規範的過程是分解表的過程。經過分解,同一事物的代表屬性出現在不同的表中。顯然,它們應該保持一致。外鍵的值或者是另外一個表的主鍵值或者為空值*。例如:學號在學生表裏是主鍵,在成績表裏是外鍵。成績表裏的學號一定要是學生表裏的學號。於是,學生表裏的學號和成績表裏的學號就一致了*。可以直觀地理解,外鍵的功能是實現同一事物在不同表中的標誌一致性。功能的實現由外鍵聯繫的兩個表,在單獨操作時,外鍵功能由兩種方法實現
物理外鍵
指的是使用foreign key 作為外鍵關聯另一張的字段的連接方法,而且限定了引擎為InnoDB,而邏輯外鍵,又叫做事實外鍵,是因為存在語法上的邏輯關聯而產生的外鍵,需要有連接關鍵詞inner join 或者left join 等等和連接部分,也就是on後面的部分,如果需要對應的設置,也可以加上set等語句。
另外,物理外鍵也相應的出現許多問題
1.數據庫需要維護外鍵的內部管理;
2.外鍵等於把數據的一致性事務實現,全部交給數據庫服務器完成;
3.有了外鍵,當做一些涉及外鍵字段的增,刪,更新操作之後,需要觸發相關操作去檢查,消耗資源;
4.外鍵還會因為需要請求對其他表內部加鎖而容易出現死鎖情況
因此,所有tables必須是InnoDB型,它們不能是臨時表。在引用表中,必須有一個索引,外鍵列以同樣的順序被列在其中作為第一列。這樣一個索引如果不存在,它必須在引用表裏被自動創建。不支持對外鍵列的索引前綴。這樣的後果之一是BLOB和TEXT列不被包括在一個外鍵中,這是因為對這些列的索引必須總是包含一個前綴長度 InnoDB不對那些外鍵或包含NULL列的被引用鍵值檢查外鍵約束。
外鍵的主從關係是定的,然後你會遵守這個規矩去幹活。但是計劃趕不上變化,萬一哪天主鍵所在表需要拆分了呢?需要重構了呢?萬一哪天你突然發現外鍵表不是非得跟主表的主鍵掛上關係呢?就我經歷過的來看,這種情況並不少見,尤其是數據庫設計者水平不夠高的情況下。另一方面,數據庫幫你保證級聯關係,你平時寫程序的時候就真的思路清晰嗎?因為某些原因(比如你想要的關係數據庫不支持,mysql經常),有些地方你就不能設計外鍵了,當有級聯更新的需要時,一部分靠物理外鍵,一部分還得靠自己,我覺得還不如全靠代碼邏輯去保證。
外鍵保持數據一致性,完整性,主要目的是控制存儲在外鍵表中的數據。 使兩張表形成關聯,外鍵只能引用外表中的列的值或使用空值
使用原則:
1、 為關聯字段創建外鍵。
2、 所有的鍵都必須唯一。
3、避免使用複合鍵。
4、外鍵總是關聯唯一的鍵字段。
注:具體使用物理外鍵和邏輯外鍵需以具體情況而定