Mysql之索引長度限制方式
Mysql索引長度限制
在設(shè)置 utf8mb4 字段的字符長度時,可能會拋出一個異常:
"Specified key was too long; max key length is 1000 bytes"
也就是在給表的索引字段添加字符長度時,超過了最大索引長度 1000 字節(jié)。
一、原因分析
關(guān)于索引長度的限制,最主要的因素就是存儲引擎和字符集。
字符集的影響在于,不同的字符集,單個字符包含的最大字節(jié)數(shù)有所不同。
比如 utf8 字符集,一個字符最多包含 3 個字節(jié)。而 utf8mb4 一個字符最多包含 4 個字節(jié)。
對于 InnoDB 引擎來說:
1) Mysql 版本 <=5.7.6
- 如果是單字段索引,則字段長度不應(yīng)超過 767 字節(jié)。
- 如果是聯(lián)合索引,則每個字段長度都不應(yīng)超過 767 字節(jié),且所有字段長度合計不應(yīng)超過 3072 字節(jié)。
這種情況下,常見字符集和引擎組合后的字符長度限制如下:
InnoDB | 最大字節(jié)數(shù) | 單字段索引最大字符數(shù) | 聯(lián)合索引合計最大字符數(shù) |
---|---|---|---|
lantin1 | 1 | 767 | 3072 |
gbk | 2 | 383 | 1536 |
utf8 | 3 | 255 | 1024 |
utf8mb4 | 4 | 191 | 768 |
2) Mysql 版本 >=5.7.7
在該版本情況下,由于 InnoDB 引擎的 innodb_large_prefix 等選項默認值改變,單字段索引長度限制增大。
- 如果是單字段索引,則字段長度不應(yīng)超過 3072 字節(jié)。
- 如果是聯(lián)合索引,則每個字段長度都不應(yīng)超過 3072 字節(jié),且所有字段長度合計不應(yīng)超過 3072 字節(jié)。
這種情況下,常見字符集和引擎組合后的字符長度限制如下:
InnoDB | 最大字節(jié)數(shù) | 單字段索引最大字符數(shù) | 聯(lián)合索引合計最大字符數(shù) |
---|---|---|---|
lantin1 | 1 | 3072 | 3072 |
gbk | 2 | 1536 | 1536 |
utf8 | 3 | 1024 | 1024 |
utf8mb4 | 4 | 768 | 768 |
對于 MyISAN 引擎來說:
如果 Mysql 版本 <=5.5.4 則其默認存儲引擎為 MyISAN。
- 如果是單字段索引,則字段長度不應(yīng)超過 1000 字節(jié)。
- 如果是聯(lián)合索引,則每個字段長度都不應(yīng)超過 1000 字節(jié),且所有字段長度合計不應(yīng)超過 1000 字節(jié)。
這種情況下,常見字符集和引擎組合后的字符長度限制如下:
MyISAM | 最大字節(jié)數(shù) | 單字段索引最大字符數(shù) | 多字段索引合計最大字符數(shù) |
---|---|---|---|
lantin1 | 1 | 1000 | 1000 |
gbk | 2 | 500 | 500 |
utf8 | 3 | 333 | 333 |
utf8mb4 | 4 | 250 | 250 |
二、解決方法
(1)修改存儲引擎
(2)修改字符集
(3)修改索引字段的字符長度
在 Mysql 版本 <=5.7.6 且字符集為 utf8mb4 的情況下,設(shè)置需要添加索引的字段長度為 191。
(4)在 Mysql<=5.7.6 的情況,修改 InnoDB 選項,將單字段索引長度限制由 767 字節(jié)(bytes)提高到 3072 字節(jié)。
先查看當前默認選項值:
SHOW VARIABLES LIKE 'innodb_large_prefix'; SHOW VARIABLES LIKE 'innodb_file_per_table'; SHOW VARIABLES LIKE 'innodb_file_format';
確認選項值是否是:
innodb_large_prefix=ON innodb_file_per_table=ON innodb_file_format=Barracuda
如果不是,進行相應(yīng)的修改:
SET GLOBAL innodb_large_prefix = 1; SET GLOBAL innodb_file_per_table = 1; SET GLOBAL innodb_file_format = barracuda;
上面兩項的值設(shè)置為 1 而不是 ON,是因為在 Mysql5.6 之前,布爾值的變量還無法識別 ON 或者 OFF,只能是數(shù)字 1 或者 0。
并且,在創(chuàng)建新表時還要指定 ROW_FORMAT=DYNAMIC 或 ROW_FORMAT=COMPRESSED。
如:
CREATE TABLE `test` ( `a` varchar(767), `b` varchar(1), `c` varchar(200), `d` varchar(168), `e` varchar(5), KEY `a_index` (`a`,`b`) )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;
或修改當前表:
ALTER TABLE [...], ROW_FORMAT=DYNAMIC;
(5)在創(chuàng)建索引時限制字段上的前綴索引長度:
CREATE TABLE `test` ( `a` varchar(767), `b` varchar(1), `c` varchar(200), `d` varchar(168), `e` varchar(5), KEY `a_index` (`a`(191),`b`) )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
mysql?自增長約束(auto_increment)的使用
MySQL中的自增長約束(auto_increment)用于自動為表的主鍵字段生成唯一的遞增值,通過設(shè)置該屬性,可以簡化主鍵的管理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-11-11使用Canal和Kafka解決MySQL與緩存的數(shù)據(jù)一致性問題
這篇文章主要介紹了使用Canal和Kafka解決MySQL與緩存的數(shù)據(jù)一致性問題,文中通過圖文結(jié)合的方式給大家介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2024-07-07