MySQL索引篇
index
- 存儲引擎
- 索引
- InnoDB中的索引
- MyISAM索引
存儲引擎
以前一直認為關系型數據庫中的索引不重要,知道最近學了MySQL高級篇,才發現,對MySQL一知半解。都是聽人泛泛而談。
首先MySQL服務器是怎么存數據的,怎么取到的,內存怎么跟磁盤交付的?
可以確定的是,MySQL5.7以后默認使用了InnoDB作為存儲引擎。
使用存儲引擎來拿到硬盤上的數據,然后放到內存,內存再跟緩沖池交互。
緩沖池是主內存中的一部分空間,用來緩存已使用的表和索引數據。緩沖池使得經常被使用的數據能夠直接在內存中獲得,從而提高速度。
我們用程序做的持久化操作,都是先把數據放到緩沖池,然后經過一定時間,數據會進行刷盤操作,然后持久化到硬盤上。
那么表的中的數據和索引又是怎么回事呢?
在MySQL8.0中,表的在硬盤的表示形式是.ibd文件存儲。這個文件即存儲了索引,又保存了數據。
索引
上面所里索引,這個玩意到底是什么。
索引是一種數據結構,是樹,是數據。
InnoDB中的索引
-
InnoDB
- InnoDB中的索引使用了B+樹作為數據結構保存。
- 每個表都有聚簇索引,如果有主鍵,主鍵默認是聚簇索引;如果沒有主鍵,unique聲明的列就是聚簇索引;每個沒pk,uk,那么MySQL會默認指定一個索引,這個索引是隱藏的。
- 聚簇索引,保存了主鍵,也保存了數據。以主鍵作為檢索條件。
- 非聚簇索引,保存了索引的列,還保存了列對應的主鍵索引值,以列的值作為檢索條件。查這種索引時,會找到這個列,然后找到主鍵。根據主鍵查聚簇索引,再拿到完整數據。這種就稱為回表。
- 除此之外,還有聯合索引,即多個列構成的索引。
-
索引的基本結構,怎么演變來的
真是站在巨人的肩膀呀,別說我樹還沒玩明白。🤣
創建下面的表,有三個列,指明了行格式。
mysql> CREATE TABLE index_demo( -> c1 INT, -> c2 INT, -> c3 CHAR(1), -> PRIMARY KEY(c1) -> ) ROW_FORMAT = Compact;假定下圖是index_demo表某一行數據的結構。
c1, c2, c3是列,里面存放了數據。
record_type :記錄頭信息的一項屬性,表示記錄的類型, 0 表示普通記錄、 2 表示最小記錄、 3 表示最大記錄、 1是非葉子節點。
next_record :記錄頭信息的一項屬性,表示下一條地址相對于本條記錄的地址偏移量,我們用箭頭來表明下一條記錄是誰。
各個列的值 :這里只記錄在 index_demo 表中的三個列,分別是 c1 、 c2 和 c3 。
其他信息 :除了上述3種信息以外的所有信息,包括其他隱藏列的值以及記錄的> 額外信息。
補充:
數據存儲的最小基本單位是頁,每一頁里面存儲了許多行,就像上面的結構一樣,邏輯上多條數據是在一個頁中的。
多個頁構成了區,表示連續的頁,方便查找。
多個區構成了段,表示數據區和頁目錄區。
還有一個零散區,可以放數據。
哥幾個都屬于表空間的。
這個是一頁數據。
既然是B+樹,不止一個葉子節點的,也不知3條數據的。這時頁分裂了,我愿稱之為細胞分裂 。
所有的主鍵是按從小到大排列的!橙色的背景。
多頁數據來了,這個是雙向鏈表,由頁頭里面的信息確認的。每個頁不是連續的,所以頁碼是亂的,但是邏輯上是雙向鏈表。
這時候,我知道了頁面,也知道了每頁的最小主鍵值,抽取頁目錄。
頁目錄就是看到的索引。使用二分法,可以快速找到數據。
最終結構,將頁目錄抽取。
這就是B+樹。
MyISAM索引
數據和索引是分開存儲的,底層也是B+樹,葉子節點存儲的是磁盤上的地址。
MyISAM引擎都是非聚簇索引。
MyISAM的索引方式都是“非聚簇”的,與InnoDB包含1個聚簇索引是不同的。小結兩種引擎中索引的區別:
① 在InnoDB存儲引擎中,我們只需要根據主鍵值對 聚簇索引 進行一次查找就能找到對應的記錄,而在
MyISAM 中卻需要進行一次 回表 操作,意味著MyISAM中建立的索引相當于全部都是 二級索引 。
② InnoDB的數據文件本身就是索引文件,而MyISAM索引文件和數據文件是 分離的 ,索引文件僅保存數
據記錄的地址。
③ InnoDB的非聚簇索引data域存儲相應記錄 主鍵的值 ,而MyISAM索引記錄的是 地址 。換句話說,
InnoDB的所有非聚簇索引都引用主鍵作為data域。
④ MyISAM的回表操作是十分 快速 的,因為是拿著地址偏移量直接到文件中取數據的,反觀InnoDB是通
過獲取主鍵之后再去聚簇索引里找記錄,雖然說也不慢,但還是比不上直接用地址去訪問。
⑤ InnoDB要求表 必須有主鍵 ( MyISAM可以沒有 )。如果沒有顯式指定,則MySQL系統會自動選擇一個
可以非空且唯一標識數據記錄的列作為主鍵。如果不存在這種列,則MySQL自動為InnoDB表生成一個隱
含字段作為主鍵,這個字段長度為6個字節,類型為長整型。
總結
- 上一篇: 测试日报模板
- 下一篇: mysql 字符串类型 小数_在Mysq