日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL - MySQL不同存储引擎下索引的实现

發布時間:2025/3/21 数据库 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL - MySQL不同存储引擎下索引的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 生猛干貨
  • Pre
  • MyISAM索引實現
    • 非聚簇(非聚集)索引
    • 索引原理圖
  • InnoDB索引實現
    • 聚簇(聚集)索引
    • 索引原理圖
    • 常見面試題
      • 為什么建議InnoDB表必須建主鍵,并且推薦使用整型的自增主鍵?
        • 為什么非主鍵索引結構葉子節點存儲的是主鍵值?(一致性和節省存儲空間)
  • 搞定MySQL

生猛干貨

帶你搞定MySQL實戰,輕松對應海量業務處理及高并發需求,從容應對大場面試


Pre

MySQL中,索引屬于存儲引擎級別的概念,不同存儲引擎對索引的實現方式是不同的,我們這里主要討論MyISAM和InnoDB兩個存儲引擎的索引實現方式。


MyISAM索引實現

非聚簇(非聚集)索引

我們建立一個myIsam存儲引擎的表,看磁盤上的文件存儲如下

我這個是8.0的MYSQL, 5.7版本 不是sdi結尾的文件,而是frm (framework)

可以看到MyISAM存儲引擎的索引文件 MYI 和數據文件 MYD 是分離的(非聚集)

這就是非聚簇索引的含義, MYI 和 MYD 分開存儲 ,同樣的 InnoDB都存在.idb文件中,所以InnoDB存儲引擎的索引就是聚簇索引。


索引原理圖

MyISAM引擎使用B+Tree作為索引結構,葉節點的data域存放的是數據記錄的地址。

上圖就是 MyISAM索引的原理圖。

上圖一共有三列,假設我們以Col1為主鍵,則上圖是一個MyISAM表的主索引(Primary key)示意??梢钥闯?strong>MyISAM的索引文件僅僅保存數據記錄的地址

在MyISAM中,主索引和輔助索引(Secondary key)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重復。

如果我們在Col2上建立一個輔助索引,則此索引的結構如下圖所示:

同樣也是一顆B+Tree,data域保存數據記錄的地址。

因此,MyISAM中索引檢索的算法為首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,則取出其data域的值,然后以data域的值為地址,去另外一個文件中MYD讀取相應數據記錄。

MyISAM的索引方式也叫做“非聚集”的,之所以這么稱呼是為了與InnoDB的聚集索引區分。


InnoDB索引實現

聚簇(聚集)索引

建立一個innodb存儲引擎的表,看磁盤上的數據文件如下

這個ibd就是 數據和索引,這兩個存儲在一個文件中

第一個重大區別是InnoDB的數據文件本身就是索引文件 ,因為就只有一個ibd文件啊。

  • MyISAM索引文件和數據文件是分離的,索引文件僅保存數據記錄的地址。

  • InnoDB中,表數據文件本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,因此InnoDB表數據文件本身就是主索引。

InnoDB也使用B+Tree作為索引結構,但具體實現方式卻與MyISAM 不同。


索引原理圖

上圖就是InnoDB主索引(同時也是數據文件)的示意圖,可以看到葉節點包含了完整的數據記錄。這種索引叫做聚集索引。


第二個與MyISAM索引的不同是InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。換句話說,InnoDB的所有輔助索引都引用主鍵作為data域

上圖為 定義在Col3上的一個輔助索引 觀察葉子節點 : data域存儲相應記錄主鍵的值而不是地址

Col3字段上的索引,以英文字符的ASCII碼作為比較準則。

聚集索引這種實現方式使得按主鍵的搜索十分高效,但是輔助索引搜索需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然后用主鍵到主索引中檢索獲得記錄。


常見面試題

為什么建議InnoDB表必須建主鍵,并且推薦使用整型的自增主鍵?

因為InnoDB的數據文件本身要按主鍵聚集,所以InnoDB要求表必須有主鍵(MyISAM可以沒有),如果沒有顯式指定,則MySQL系統會自動選擇一個可以唯一標識數據記錄的列作為主鍵,如果不存在這種列,則MySQL自動為InnoDB表生成一個隱含字段作為主鍵,這個字段長度為6個字節,類型為長整形。

至于是整型,主要是構建B+Tree的時候,從左到右遞增的屬性,你如果用過UUID,不僅占用空間,還要轉換成assic碼進行比較,效率自然不行。


為什么非主鍵索引結構葉子節點存儲的是主鍵值?(一致性和節省存儲空間)

知道了InnoDB的索引實現后,就很容易明白為什么不建議使用過長的字段作為主鍵,因為所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大,占用空間。

再比如用非單調(可重復)的字段作為主鍵在InnoDB中是不推薦的,因為InnoDB數據文件本身是一顆B+Tree,可重復的主鍵會造成在插入新記錄時數據文件為了維持B+Tree的特性而頻繁的分裂調整,十分低效,所以推薦使用自增主鍵。


參考 : http://blog.codinglabs.org/articles/theory-of-mysql-index.html


搞定MySQL

總結

以上是生活随笔為你收集整理的MySQL - MySQL不同存储引擎下索引的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。