前言:以下內容均為MySQL5.7版本為准,在MySQL5.7版本中innodb是默認的存儲引擎。
innodb結構
事務性表和非事務性表(Innodb,MyISAM )。 MyISAM 沒有commit 和rollback。
創建表的時候指定存儲引擎
CREATE TABLE `user` ( `id` int(64) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8
innodb有頁為單位存儲數據。一頁的大小為16KB,除了修改源碼,不能修改。
查詢MySQL也大小 show GLOBAL STATUS like 'Innodb_page_size'; --顯示Innodb頁大小。
特點:innodb創建哈希索引會自動轉換成Btree索引,也就是說,Innodb其實沒有哈希索引。
然后由N頁存放一個表的數據,並且這些頁之間關聯,主鍵索引,最終組成N個B+樹。
MySQL 中一頁是16KB, 一個主鍵bigint字段暫用空間(8+6)個字節,8是bigint的大小,6是指針大小,假設每一行數據大小為1K。公式如下:
可以存儲的數據 = (16*1024/(8+6)) * (16*1024/(8+6)) * 16K/1K = 21902400。 兩千多萬條數據。
B+樹結構的好處:降低I/O 操作(B樹一般三次I/O 即可),減少內存使用(不需要讀取全部索引到內存)。
B+樹的原理和使用Java實現了一顆B+樹,詳細說明:https://www.cnblogs.com/jssj/p/12897709.html。
B+樹的普通索引:建立方式一致:有一點區別,先通過字段上的普通索引獲取主鍵索引,然后再根據主鍵索引獲取該列的全部數據,並且為最左優先。
B+樹的葉子節點中存在了每一張的數據,這些數據如何存儲的呢?
行格式
create table test1( name VARCHAR(65535) ) charset = ASCII Row_format=Compact
上面錯誤創建表會報錯:提示:MySQL一列的除了BLOB 以外最多只能有65535個字節。為什么還報錯呢,應該MySQL還有3個字節用於記錄字段是否可以為空,是否可變長度。故實際最大只能65532個字節。
Mysql 目前有4種行格式:Redundant、Compact、Dynamic、Compressed
1. Compact
變長字段:采用1-2個字節來表示一個字段的長度,逆序,字段最大長度<= 255字節用1個字節表示;大於255字節,但是實際使用字節<=127,也使用1個字節來表示;其他情況使用2個字節來表示。
NULL標記:逆序,存儲每條記錄中允許為NULL的字段,將實際為NULL的字段用1表示,實際不為NULL的字段用0表示;每一列不是用一個字節來表示,而是用一個位來表示。
記錄頭信息:使用5個字節來表示;主要包含:該記錄是否被刪除,記錄類型,下一條記錄的相對偏移量。
列信息:就是你存放數據的信息。
2. Dynamic
與Compact行格式很像,差異在於頁面溢出的處理上。 數據溢出,則新開一頁存放每一行的溢出數據和指向之前行的信息。
3. Compressed
在於Dynamic使用了壓縮算法。
4. Redundant (沒有NULL標記)
字段長度偏移列表,用來記錄每列的結束位置;真實數據(整條記錄)<=127B 用1個字節記錄,其他使用2個字節;
是使用1個字節還是2個字節來存儲,該信息放在記錄頭的(1byte_offs_flag屬性上),每個列記錄的第一個bit 使用來表示該列是否位NULL。
總結
show table status like 'ic_base'; -- 查詢表ic_base的創建信息
紅框是我們熟悉的信息。 表名, 存儲引擎,行格式。
MySQL的Innodb存儲最終是為了查詢效率服務的。