前言
為什麼 Navicate
預設 varchar
型別是 255
,突然想到了這個問題,並帶著疑問去看了一下為什麼
Mysql5.6.x
在 Mysql5.6
版本下,單列索引的長度不能超過 767bytes
,聯合索引的長度不能超過 3072bytes
CREATE TABLE `test` (
`a` varchar(255) DEFAULT NULL,
`b` varchar(255) DEFAULT NULL,
`c` varchar(255) DEFAULT NULL,
`d` varchar(255) DEFAULT NULL,
`e` varchar(255) DEFAULT NULL,
KEY `a` (`a`,`b`,`c`,`d`,`e`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
> 1071 - Specified key was too long; max key length is 3072 bytes
可以看到,每個欄位 255*3*5=3825
,大於了 3072
,則報錯了
為什麼經常性的設定 varchar 長度為 255
utf8
上面說到單列索引長度為 767
,在 utf8
編碼下,一個字元為 3bytes
,那麼 255*3=765
,剛好為能夠建立索引長度的最大值,如果超出了這個值,如果使用的是 navicat
那麼 mysql
會自動將這一列的索引變為字首索引,擷取 255
utf8mb4
在 utf8mb4
下,一個字元為 4bytes
, 那麼 767÷4=191.75
,取整為 191
,所以在 utf8mb4
編碼下,如果你的 varchar
超出 191
,如果使用的是 navicat
那麼 mysql
會自動將這一列的索引變為字首索引,擷取 191
Mysql5.7.x
在 Mysql5.7
版本下,單列索引的長度不能超過 3072bytes
,聯合索引的長度不能超過 3072bytes
為什麼聯合索引長度是 3072
我們知道 InnoDB
一個 page
的預設大小是 16k
。由於是 Btree
組織,要求葉子節點上一個 page
至少要包含兩條記錄(否則就退化連結串列了)。
所以一個記錄最多不能超過 8k
。
又由於 InnoDB
的聚簇索引結構,一個二級索引要包含主鍵索引,因此每個單個索引不能超過 4k
(極端情況,pk和某個二級索引都達到這個限制)。
由於需要預留和輔助空間,扣掉後不能超過 3500
,取個 整數
就是 1024*3=3072
。
本作品採用《CC 協議》,轉載必須註明作者和本文連結