首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL InnoDB 索引組織表底層結構:B+Tree 葉子節點存全行、自增主鍵設計藝術

     編輯:MySQL 綜合教學

MySQL InnoDB 索引組織表與 B+Tree 底層結構

一、什麼是索引組織表(IOT)?

InnoDB 表按主鍵順序存儲,**主鍵即聚簇索引**,葉子節點直接包含**完整行數據**(非主鍵列)。這與 Heap 表(數據與索引分離)截然不同。

二、B+Tree 結構示意

B+Tree 結構圖

  • 非葉子節點:僅存儲索引鍵值 + 指向子頁的指針
  • 葉子節點:存儲**完整行數據**,並通過雙向鏈表串聯(支援範圍掃描)
  • 藍色方塊:指針(子頁指針 / 葉子鏈表指針)
圖中葉子節點應為雙向鏈表,單向箭頭為簡化繪製。

三、為什麼強烈建議「業務無關的自增整數主鍵」?

主鍵類型插入行為頁分裂/碎片二級索引體積建議
自增 INT/BIGINT永遠追加到最右葉子頁幾乎無分裂,填充率高二級索引存主鍵值,4/8 字節極小✅ 首選
UUID/CHAR(36)隨機插入,導致頻繁頁分裂嚴重碎片,填充率低至 50%~二級索引存 36 字節,體積膨脹 4~9 倍❌ 避免
業務自然鍵(如身份證)可能有序、可能隨機視業務規律而定二級索引存業務鍵,可能較長⚠️ 謹慎

四、頁大小與行存儲估算

  • 預設頁大小 16 KB
  • 每頁可存行數 ≈ 16KB / (行長度 + 記錄頭開銷 ~27B)
  • 典型行長 200B → 單頁約 70~80 行

五、插入 / 刪除 / 更新對 B+Tree 的影響

  • 插入:自增主鍵 → 右側追加;隨機主鍵 → 定位頁 → 若頁滿則分裂(50/50 或 90/10)
  • 刪除:標記刪除位 → 頁合併(低於 50% 填充率時嘗試合併相鄰頁)
  • 更新主鍵:等同 Delete + Insert,**極度不建議**
  • 更新非主鍵:原地修改(若長度不變)或 頁分裂/溢出頁(長度增大)

六、最佳實踐清單

  1. **主鍵:BIGINT UNSIGNED NOT NULL AUTO_INCREMENT**
  2. **避免業務字段做主鍵**,避免 UUID、MD5、雪花算法 ID(除非分庫分表強制需全局唯一,即便如此也建議 64 位整數)
  3. **二級索引盡量覆蓋查詢**,減少回表
  4. **大字段(TEXT/BLOB)單獨表**,避免聚簇索引頁膨脹
  5. **定期 OPTIMIZE TABLE** 整理碎片(或 ALTER TABLE ... ENGINE=InnoDB 重建)
理解 B+Tree 與聚簇索引,是 MySQL 效能調優、表結構設計的基石。自增主鍵不是「習慣」,而是**基於存儲引擎底層機制的理性選擇**。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved