国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

MySQL表為什么必須有主鍵 -- 聚集索引的簡單介紹

2024-07-24 13:00:28
字體:
來源:轉載
供稿:網友

注意:下面討論的都是MySQL5.6版本中的innodb引擎。

比較規范的數據庫表設計(包括我們公司)都會有一條不成文的規定,那就是給每張表一個自增主鍵。那么自增主鍵除了有數據的唯一性外,還有什么所用呢?為什么要有自增主鍵?

之前我轉發的《58到家數據庫30條軍規解讀》中解釋道:

主鍵遞增,數據行寫入可以提高插入性能,可以避免page分裂,減少表碎片提升空間和內存的使用主鍵要選擇較短的數據類型, Innodb引擎普通索引都會保存主鍵的值,較短的數據類型可以有效的減少索引的磁盤空間,提高索引的緩存效率無主鍵的表刪除,在row模式的主從架構,會導致備庫夯住

第三條先不必關注,我們來看看前兩條。 為什么能提高插入性能呢,避免page分頁又是怎么回事?

這里就不得不說一下聚集索引了。


聚集索引(Clustered Index)

一個聚集索引定義了表中數據的物理存儲順序。如何理解聚集索引呢,好比一個電話本,比如一個電話本是按照姓氏排序,并且電話號碼緊跟著后面。因為聚集索引決定了表中數據的物理存儲順序,那么一個表則有且只有一個聚集索引。一個聚集索引可以包含多個列。好比一個電話本是基于名字,姓氏同時排序。

Innodb的聚集索引

Innodb的存儲索引是基于B+tree,理所當然,聚集索引也是基于B+tree。與非聚集索引的區別則是,聚集索引既存儲了索引,也存儲了行值。當一個表有一個聚集索引,它的數據是存儲在索引的葉子頁(leaf pages)。因此innodb也能理解為基于索引的表。

那么innodb如何決定那個索引作為聚集索引呢?

innodb如何選擇一個聚集索引

對于innodb,主鍵毫無疑問是一個聚集索引。但是當一個表沒有主鍵,或者沒有一個索引,innodb會如何處理呢。請看如下規則

如果一個主鍵被定義了,那么這個主鍵就是作為聚集索引

如果沒有主鍵被定義,那么該表的第一個唯一非空索引被作為聚集索引

如果沒有主鍵也沒有合適的唯一索引,那么innodb內部會生成一個隱藏的主鍵作為聚集索引,這個隱藏的主鍵是一個6個字節的列,改列的值會隨著數據的插入自增。

還有一個需要注意的是:

次級索引的葉子節點并不存儲行數據的物理地址。而是存儲的該行的主鍵值。

所以:一次級索引包含了兩次查找。一次是查找次級索引自身。然后查找主鍵(聚集索引)


現在應該明白了吧,建立自增主鍵的原因是:innodb中的每張表都會有一個聚集索引,而聚集索引又是以物理磁盤順序來存儲的,自增主鍵會把數據自動向后插入,避免了插入過程中的聚集索引排序問題。聚集索引的排序,必然會帶來大范圍的數據的物理移動,這里面帶來的磁盤IO性能損耗是非常大的。 而如果聚集索引上的值可以改動的話,那么也會觸發物理磁盤上的移動,于是就可能出現page分裂,表碎片橫生。

解讀中的第二點相信看了上面關于聚集索引的解釋后就很清楚了。

雖然遵循上面的原則也沒錯,但某些特殊的情況也是可以自己指定一些非自增主鍵為聚集索引的。如: 當數據量大,但長時間不會被更新的; 新生成的數據的索引本來就是按照自增的順序增加的等等。

舉個栗子,(只是栗子啊,現實中不太可能): 有一家公司里的員工上百萬,有關員工的個人信息幾年都不會發生變化,那么以員工的user_id號來作為各個表的索引就很適合。因為一個員工的信息都按照物理順序呢排列在一起了,避免了磁盤移動查找數據的IO時間。比如說員工屬于幾個部門,一下子就查到了,不同分不同的地址去挨個進行磁盤掃描。

栗子從簡,哈哈哈哈,就這樣子吧,我也不太會寫,簡單的記錄下來了~


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 太康县| 察雅县| 神池县| 浦东新区| 锦屏县| 宁南县| 左权县| 延川县| 双辽市| 油尖旺区| 曲松县| 商城县| 油尖旺区| 正蓝旗| 沅陵县| 清苑县| 十堰市| 铜川市| 资中县| 河北省| 西平县| 玛沁县| 萍乡市| 宣威市| 杭锦旗| 黔江区| 疏勒县| 交城县| 陇川县| 汉沽区| 涞水县| 西乌| 长子县| 孙吴县| 抚宁县| 梁河县| 肇东市| 广西| 垣曲县| 辉南县| 老河口市|