MySQL爲何須要一個主鍵

主鍵

表中每一行都應該有能夠惟一標識本身的一列(或一組列)。mysql

一個顧客可使用顧客編號列,而訂單可使用訂單ID,僱員可使用僱員ID 或 僱員社會保險號。sql

主鍵(primary key) 一列(或一組列),其值可以惟一區分表中的每一個行。
惟一標識表中每行的這個列(或這組列)稱爲主鍵。沒有主鍵,更新或刪除表中特定行很困難,由於沒有安全的方法保證只設計相關的行。數據庫

雖然並不老是都須要主鍵,但大多數數據庫設計人員都應保證他們建立的每一個表有一個主鍵,以便於之後數據操縱和管理緩存

表中的任何列均可以做爲主鍵,只要它知足一下條件:安全

一、任何兩行都不具備相同的主鍵值 二、每一個行都必須具備一個主鍵值(主鍵列不容許NULL值)

主鍵值規範:這裏列出的規則是MySQL自己強制實施的。數據庫設計

主鍵的最好習慣:
除MySQL強制實施的規則外,應該堅持的幾個廣泛認爲的最好習慣爲:oop

一、不更新主鍵列的值 二、不重用主鍵列的值 三、不在主鍵列中使用可能會更改的值(例如,若是使用一個名字做爲主鍵以標識某個供應商,應該供應商合併和更改其名字時,必須更改這個主鍵)

總之:不該該使用一個具備意義的column(id 自己並不保存表 有意義信息) 做爲主鍵,而且一個表必需要有一個主鍵,爲方便擴展、鬆耦合,高可用的系統作鋪墊。優化


很是感謝 @pathbox、 @est、@hooooopo 同窗的提醒。主鍵的做用,在於索引。spa

無特殊需求下Innodb建議使用與業務無關的自增ID做爲主鍵設計

InnoDB引擎使用匯集索引,數據記錄自己被存於主索引(一顆B+Tree)的葉子節點上。這就要求同一個葉子節點內(大小爲一個內存頁或磁盤頁)的各條數據記錄按主鍵順序存放,所以每當有一條新的記錄插入時,MySQL會根據其主鍵將其插入適當的節點和位置,若是頁面達到裝載因子(InnoDB默認爲15/16),則開闢一個新的頁(節點)

一、若是表使用自增主鍵,那麼每次插入新的記錄,記錄就會順序添加到當前索引節點的後續位置,當一頁寫滿,就會自動開闢一個新的頁。以下圖所示:

這樣就會造成一個緊湊的索引結構,近似順序填滿。因爲每次插入時也不須要移動已有數據,所以效率很高,也不會增長不少開銷在維護索引上。

二、 若是使用非自增主鍵(若是身份證號或學號等),因爲每次插入主鍵的值近似於隨機,所以每次新紀錄都要被插到現有索引頁得中間某個位置:

 

 

 

 
 

此時MySQL不得不爲了將新記錄插到合適位置而移動數據,甚至目標頁面可能已經被回寫到磁盤上而從緩存中清掉,此時又要從磁盤上讀回來,這增長了不少開銷,同時頻繁的移動、分頁操做形成了大量的碎片,獲得了不夠緊湊的索引結構,後續不得不經過OPTIMIZE TABLE來重建表並優化填充頁面。

在使用InnoDB存儲引擎時,若是沒有特別的須要,請永遠使用一個與業務無關的自增字段做爲主鍵。

mysql 在頻繁的更新、刪除操做,會產生碎片。而含碎片比較大的表,查詢效率會下降。此時需對錶進行優化,這樣纔會使查詢變得更有效率。

相關文章
相關標籤/搜索