今天正好有空,來講個之前粉絲經常問的一個知識,就是mysql的Innodb最大支持的索引長度是多少?以及索引長度怎么計算?
一、mysql的innodb引擎,創建索引最大支持的長度是多少字節?
不墨跡,直接說答案:
在mysql8之前,索引最大長度為 767字節
在mysql8之后,索引最大長度為 3072字節
然后再建個簡單的表,來驗證一下
我使用的mysql 8的版本
建一張簡單的student表,表結構如下圖
?
然后,我創建一個長度大于3072字節的索引
比如我給 address 這個字段上添加索引,它會提示以下錯誤信息
提示?key was too long; max key length is 3072 bytes
意思是 你創建的索引超出長度,并且告訴你,最大支持的長度是?3072 bytes。
那我剛才想要創建的?address 這個索引,它具體的長度是多少呢?
只有知道它的長度是多少,才能確定它是不是真的超過 3072字節
想要知道?varchar(1500)? 長度是多少個字節,需要知道下面這個經常被問到的問題:
varchar(255),里的這個255是255個字節?還是255個字符???
二、varchar(255),里的這個255是255個字節?還是255個字符?
這個255是代表255個字節?還是255個字符?
不墨跡,直接說答案:
mysql5.0之前是255個字節
mysql5.0之后是255個字符
所以上邊那個問題就可以知道答案了:
因為,我使用的mysql版本是8,是屬于5.0之后的版本,所以?varchar(1500) 就表示1500個字符
又因為創建這個字段的時候,使用的是?utf8mb4 表示一個字符4個字節
所以 1500 x 4 = 6000 字節,6000字節 > 3072字節,所以上邊創建這個?address 索引時,就報長度過長的錯誤。?
下面再改一下?address 這個字段的長度,把它的長度改到小于3072,然后再來創建這個索引,試一下,看是否可以成功
好,把address 改成?varchar(768)? 了
再試下,創建索引
看到沒,創建成功了,因為 768 x 4 = 3072
可以再給它加1,改成769,再試一下,又報錯了。
?
還有個小知識點需要知道,就是 mysql建表的時候,經常使用的字符串類型是varchar
創建varchar 這種數據類型時,常用的字符集有?utf8mb4 和 utf8
看到沒,就上圖這倆,utf8mb4 和 utf8
utf8mb4剛才說了,它的每個字符是占4個字節
那utf8呢?它的每個字符占幾個字節?
其實?utf8 就是 utf8mb3,從名字也能知道,它的每個字符是占3個字節
uft8,在 V8.0 還是指代的utf8mb3,據說未來的會變為uft8mb4,不過只是據說,還暫未確定
三、你創建的索引,這個索引的長度怎么計算?
既然都說到這了,那下面繼續把mysql中 索引長度的計算一起說一下吧
mysql中普通索引的長度,非常好計算,普通索引的長度就是創建這個字段時,這個字段類型的長度,下面列出了常見的數據類型的長度
-
數值類型
-
tinyint:1字節
-
small int:2字節
-
medium int:3字節
-
int:4字節
-
bigint:8字節
-
-
時間類型
-
date:3字節
-
timestamp:4字節
-
datetime:8字節
-
除了上邊常用的幾種類型外,char和varchar也很常用
-
char(n):括號里的n是幾,就代表幾個字節
-
varchar(n):如果你用的是utf8也就是utf8mb3,那長度是3n+2;如果你用的是utf8mb4,那長度是4n+2;加2是因為 需要2字節存儲字符串長度。
-
還有就是,如果建表的時候 字段允許是null,需要1個字節記錄是否可以為null,如果允許為null,則需要 加 1 個字節存儲;如果不允許null,則不需要加1個字節
知道了這些之后,就可以計算索引的長度了。
普通單列索引的長度就是,你添加索引的這個字段列的數據類型的字節長度
聯合索引的長度就是,你聯合的這幾個字段列的數據類型的字節長度相加。
下面,可以使用mysql中的?explain 執行計劃,來驗證一下
1、普通單列索引長度的驗證
首先,先給 age這個字段加個普通單列索引
并且,如下圖,我在建表的時候,這個age用的是int類型的,int類型的長度大小是4字節
并且 允許為null,所以驗證期望的結果長度應該是? 4 + 1 = 5 字節
查詢驗證一下
上圖可以看到,查詢的走了 idx_age這個索引,而且explain中顯示 的key_len為5
我把那個允許null,改成不允許null,再試一下
看到沒,改成不允許null后,key_len變成4了
2、多列聯合索引長度的驗證
首先,先給這個表添加一個聯合索引,idx_name_age 聯合的是name和age這2列
然后再確認一下 name和age這兩列的數據類型
上圖,可以看到,name是varchar類型的,為了計算方便,我把它的varchar長度給的是100
age使用的是int類型并且這兩列都不允許null
具體的計算過程:
name用的是varchar(100)? ?utf8mb4,而且不允許null,所以 name的索引長度 (4x100) +2 = 402
age 用的是int,int的長度是4字節,所以 age的索引長度是4
所以,咱們的預期是,最后idx_name_age 這個聯合索引的長度是兩者相加,402 + 4 = 406
好,下面 使用?explain 查詢驗證一下
可以看到結果跟咱們預期的一樣:走了?idx_name_age 這個聯合索引,并且idx_name_age聯合索引的長度是406,和咱們預期的結果一樣。
ok,今天就寫這么多吧
純手敲 原創不易,如果覺得對你有幫助,可以關注一下,打賞一下,感謝
?
?