關於Mysql資料儲存,你瞭解多少?
前言
InnoDB簡介
InnoDB行格式
-- 建立資料表時,顯示指定行格式CREATE TABLE 表名 (列的資訊) ROW_FORMAT=行格式名稱;-- 建立資料表時,修改行格式ALTER TABLE 表名 ROW_FORMAT=行格式名稱;-- 檢視資料表的行格式show table status like '<資料表名>';
compact格式
變長欄位長度列表中只儲存值為 非NULL 的列內容佔用的長度,值為 NULL 的列的長度是不儲存的 。
並不是所有記錄都有這個 變長欄位長度列表 部分,比方說表中所有的列都不是變長的資料型別的話,這一部分就不需要有
首先統計表中允許儲存NULL的列有哪些。
根據列的實際值,用0或者1填充NULL值列表,1代表該列的值為空,0代表該列的值不為空。
如果表中沒有允許儲存 NULL 的列,則 NULL值列表 也不存在了。
redundant 格式
dynamic 格式
compressed 格式
InnoDB資料頁結構
先建立一個表: CREATE TABLE test( a1 INT, a2 INT, a3 VARCHAR(100), PRIMARY KEY (a1) ) CHARSET=ascii ROW_FORMAT=Compact; test表中插入幾條記錄:INSERT INTO test VALUES(1, 10, 'aaa'); INSERT INTO test VALUES(2, 20, 'bbb'); INSERT INTO test VALUES(3, 30, 'ccc'); INSERT INTO test VALUES(4, 40, 'ddd');
delete_mask這個屬性標記著當前記錄是否被刪除。這些被刪除的記錄之所以不立即從磁碟上移除,是因為移除它們之後把其他的記錄在磁碟上重新排列需要效能消耗,所以只是打一個刪除標記而已。所有被刪除掉的記錄都會組成一個所謂的垃圾連結串列,在這個連結串列中的記錄佔用的空間稱之為所謂的可重用空間,之後如果有新記錄插入到表中的話,可能把這些被刪除的記錄佔用的儲存空間覆蓋掉。
min_rec_maskB+樹的每層非葉子節點中的最小記錄都會新增該標記,min_rec_mask值都是0,意味著它們都不是B+樹的非葉子節點中的最小記錄。
n_owned在頁目錄分組時使用,每個組的最後一條記錄(也就是組內最大的那條記錄)的頭資訊中的n_owned屬性表示該記錄擁有多少條記錄,也就是該組內共有幾條記錄。
heap_no這個屬性表示當前記錄在本頁中的位置,從圖中可以看出來,我們插入的4條記錄在本頁中的位置分別是:2、3、4、5。heap_no值為0和1的記錄,稱為偽記錄或者虛擬記錄。這兩個偽記錄一個代表最小記錄,一個代表最大記錄。
record_type這個屬性表示當前記錄的型別,一共有4種型別的記錄,0表示普通記錄,1表示B+樹非葉節點記錄,2表示最小記錄,3表示最大記錄。
next_record它表示從當前記錄的真實資料到下一條記錄的真實資料的地址偏移量。比方說第一條記錄的next_record值為32,意味著從第一條記錄的真實資料的地址處向後找32個位元組便是下一條記錄的真實資料。下一條記錄指得並不是按照我們插入順序的下一條記錄,而是按照主鍵值由小到大的順序的下一條記錄。而且規定Infimum記錄(也就是最小記錄) 的下一條記錄就是本頁中主鍵值最小的使用者記錄,而本頁中主鍵值最大的使用者記錄的下一條記錄就是 Supremum記錄(也就是最大記錄)。
Page Directory(頁目錄)
初始情況下一個資料頁裡只有最小記錄和最大記錄兩條記錄,它們分屬於兩個分組。
之後每插入一條記錄,都會從頁目錄中找到主鍵值比本記錄的主鍵值大並且差值最小的槽,然後把該槽對應的記錄的n_owned值加1,表示本組內又新增了一條記錄,直到該組中的記錄數等於8個。
在一個組中的記錄數等於8個後再插入一條記錄時,會將組中的記錄拆分成兩個組,一個組中4條記錄,另一個5條記錄。這個過程會在頁目錄中新增一個槽來記錄這個新增分組中最大的那條記錄的偏移量。
INSERT INTO test VALUES(5, 50, 'eee'); INSERT INTO test VALUES(6, 60, 'fff'); INSERT INTO test VALUES(7, 70, 'ggg'); INSERT INTO test VALUES(8, 80, 'hhh'); INSERT INTO test VALUES(9, 90, 'iii');INSERT INTO test VALUES(10, 100, 'jjj');INSERT INTO test VALUES(11, 110, 'kkk');INSERT INTO test VALUES(12, 120, 'lll');
這裡為了便於理解,圖中只保留了使用者記錄頭資訊中的n_owned和next_record屬性。
因為各個槽代表的記錄的主鍵值都是從小到大排序的,所以我們可以使用二分法來進行快速查詢。
所以在一個資料頁中查詢指定主鍵值的記錄的過程分為兩步:
2.透過記錄的next_record屬性遍歷該槽所在的組中的各個記錄。
比方說我們查詢主鍵值為x的記錄,計算中間槽的位置(min+max)/2 =mid,檢視mid槽對應的主鍵值y,若x<y,則min不變,max=mid,若x>y,則max不變,min=mid。依此類推。
舉例:我們想找主鍵值為6的記錄,過程是這樣的計算中間槽的位置:(0+3)/2=1,所以檢視槽1對應記錄的主鍵值為4,因為4 < 6,所以設定low=1,high保持不變。因為high - low的值為1,所以確定主鍵值為6的記錄在槽2對應的組中。我們可以很輕易的拿到槽1對應的記錄(主鍵值為4),該條記錄的下一條記錄就是槽2中主鍵值最小的記錄,該記錄的主鍵值為5。所以我們可以從這條主鍵值為5的記錄出發,遍歷槽2中的各條記錄找到主鍵為6 的資料。
注意:若查到資料在槽2的分組中,由於槽2是指向最後一個記錄,所以需要向上找一個槽位,定位到上一個槽位最後一行,然後再向下找。
File Header(檔案頭部)
B+樹索引
以主鍵為搜尋條件這個查詢過程我們已經很熟悉了,可以在頁目錄中使用二分法快速定位到對應的槽,然後再遍歷該槽對應分組中的記錄即可快速找到指定的記錄。
以其他列作為搜尋條件對非主鍵列的查詢的過程可就不這麼幸運了,因為在資料頁中並沒有對非主鍵列建立所謂的頁目錄,所以我們無法透過二分法快速定位相應的槽。這種情況下只能從最小記錄開始依次遍歷單連結串列中的每條記錄,然後對比每條記錄是不是符合搜尋條件。
1:定位到記錄所在的頁。
索引
test表中插入幾條記錄:INSERT INTO test VALUES(1, 10, 'aa'); INSERT INTO test VALUES(2, 20, 'bb'); INSERT INTO test VALUES(4, 40, 'dd');
INSERT INTO test VALUES(3, 30, 'cc');
1:先從目錄項中根據二分法快速確定出主鍵值為5的記錄在目錄2中(因為 4 < 5 < 7),它對應的資料頁是頁23。
InnoDB中的索引方案
聚簇索引
1:使用記錄主鍵值的大小進行記錄和頁的排序
二級索引
使用記錄a2列的大小進行記錄和頁的排序
頁內的記錄是按照a2列的大小順序排成一個單向連結串列。
各個存放使用者記錄的頁也是根據頁中記錄的a2列大小順序排成一個雙向連結串列。
存放目錄項記錄的頁分為不同的層次,在同一層次中的頁也是根據頁中目錄項記錄的a2列大小順序排成一個雙向連結串列。
B+樹的葉子節點儲存的並不是完整的使用者記錄,而只是a2列+主鍵這兩個列的值。
目錄項記錄中不再是主鍵+頁號的搭配,而變成了a2列+頁號的搭配。
索引的代價
1:空間上的代價每建立一個索引都要為它建立一棵B+樹,每一棵B+樹的每一個節點都是一個資料頁,一個頁預設會佔用16KB的儲存空間。
總結
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024922/viewspace-2934573/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 關於Synchronized你瞭解多少?synchronized
- 關於繼承,你瞭解多少?繼承
- 關於區塊鏈你瞭解多少區塊鏈
- 面試-關於Http協議你瞭解多少,有多少說多少面試HTTP協議
- 關於Linux知識你瞭解多少呢?Linux
- 關於Linux你瞭解多少?Linux由來!Linux
- 關於Linux你瞭解多少?Linux由來Linux
- 關於資料中心方面的專業名詞,你瞭解多少?
- 關於新媒體運營崗位,你瞭解多少?
- 你真的瞭解Innodb儲存引擎?儲存引擎
- 你真的瞭解資料在堆疊中的儲存方式嗎?
- 關於Linux系統和Windows系統你瞭解多少?LinuxWindows
- 關於Apache Flink的那些子專案,你瞭解多少?Apache
- 一鍵帶你瞭解Yotta企業雲盤大資料儲存大資料
- 軟體測試知識儲備:關於「登入安全」的基礎知識,你瞭解多少?
- 關於 NoSQL 資料庫你應該瞭解的 10 件事SQL資料庫
- 【前端幫幫忙】第5期 關於CSS權重,你瞭解多少?前端CSS
- 直播系統開發中關於開發環境你瞭解多少?開發環境
- 關於相親原始碼的監控系統搭建,你瞭解多少?原始碼
- 關於資料儲存的一個故事
- 關於InnoDB表資料和索引資料的儲存索引
- 能窺見未來的大資料+AI,你瞭解多少?大資料AI
- 機器學習 | 資料歸一化的重要性你瞭解多少?機器學習
- 當紅“Serverless”,你瞭解多少?Server
- java異常你瞭解多少Java
- 對於網校系統原始碼,你瞭解多少?原始碼
- 關於MongoDB複製,你瞭解多少(附副本集常見任務教程)MongoDB
- 網站總被劫持?關於DNS快取中毒你究竟瞭解多少網站DNS快取
- 【乾貨】MySQL底層架構設計,你瞭解多少?MySql架構
- 重新學習Mysql資料庫3:Mysql儲存引擎與資料儲存原理MySql資料庫儲存引擎
- 一文帶你瞭解 「圖資料庫」Nebula 的儲存設計和思考資料庫
- MySQL資料分析儲存引擎示例講解HKEAMySql儲存引擎
- 【入門知識】關於Linux系統和Windows系統你瞭解多少?LinuxWindows
- MySQL 資料庫儲存引擎MySql資料庫儲存引擎
- 關於大資料你應該瞭解的五件事兒大資料
- 【Spring註解驅動開發】關於BeanPostProcessor後置處理器,你瞭解多少?SpringBean
- Java String 物件,你瞭解多少?Java物件
- 抽象類和介面,你瞭解多少?抽象