Mysql之索引長(zhǎng)度限制方式
Mysql索引長(zhǎng)度限制
在設(shè)置 utf8mb4 字段的字符長(zhǎng)度時(shí),可能會(huì)拋出一個(gè)異常:
"Specified key was too long; max key length is 1000 bytes"
也就是在給表的索引字段添加字符長(zhǎng)度時(shí),超過(guò)了最大索引長(zhǎng)度 1000 字節(jié)。
一、原因分析
關(guān)于索引長(zhǎng)度的限制,最主要的因素就是存儲(chǔ)引擎和字符集。
字符集的影響在于,不同的字符集,單個(gè)字符包含的最大字節(jié)數(shù)有所不同。
比如 utf8 字符集,一個(gè)字符最多包含 3 個(gè)字節(jié)。而 utf8mb4 一個(gè)字符最多包含 4 個(gè)字節(jié)。
對(duì)于 InnoDB 引擎來(lái)說(shuō):
1) Mysql 版本 <=5.7.6
- 如果是單字段索引,則字段長(zhǎng)度不應(yīng)超過(guò) 767 字節(jié)。
- 如果是聯(lián)合索引,則每個(gè)字段長(zhǎng)度都不應(yīng)超過(guò) 767 字節(jié),且所有字段長(zhǎng)度合計(jì)不應(yīng)超過(guò) 3072 字節(jié)。
這種情況下,常見(jiàn)字符集和引擎組合后的字符長(zhǎng)度限制如下:
InnoDB | 最大字節(jié)數(shù) | 單字段索引最大字符數(shù) | 聯(lián)合索引合計(jì)最大字符數(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 等選項(xiàng)默認(rèn)值改變,單字段索引長(zhǎng)度限制增大。
- 如果是單字段索引,則字段長(zhǎng)度不應(yīng)超過(guò) 3072 字節(jié)。
- 如果是聯(lián)合索引,則每個(gè)字段長(zhǎng)度都不應(yīng)超過(guò) 3072 字節(jié),且所有字段長(zhǎng)度合計(jì)不應(yīng)超過(guò) 3072 字節(jié)。
這種情況下,常見(jiàn)字符集和引擎組合后的字符長(zhǎng)度限制如下:
InnoDB | 最大字節(jié)數(shù) | 單字段索引最大字符數(shù) | 聯(lián)合索引合計(jì)最大字符數(shù) |
---|---|---|---|
lantin1 | 1 | 3072 | 3072 |
gbk | 2 | 1536 | 1536 |
utf8 | 3 | 1024 | 1024 |
utf8mb4 | 4 | 768 | 768 |
對(duì)于 MyISAN 引擎來(lái)說(shuō):
如果 Mysql 版本 <=5.5.4 則其默認(rèn)存儲(chǔ)引擎為 MyISAN。
- 如果是單字段索引,則字段長(zhǎng)度不應(yīng)超過(guò) 1000 字節(jié)。
- 如果是聯(lián)合索引,則每個(gè)字段長(zhǎng)度都不應(yīng)超過(guò) 1000 字節(jié),且所有字段長(zhǎng)度合計(jì)不應(yīng)超過(guò) 1000 字節(jié)。
這種情況下,常見(jiàn)字符集和引擎組合后的字符長(zhǎng)度限制如下:
MyISAM | 最大字節(jié)數(shù) | 單字段索引最大字符數(shù) | 多字段索引合計(jì)最大字符數(shù) |
---|---|---|---|
lantin1 | 1 | 1000 | 1000 |
gbk | 2 | 500 | 500 |
utf8 | 3 | 333 | 333 |
utf8mb4 | 4 | 250 | 250 |
二、解決方法
(1)修改存儲(chǔ)引擎
(2)修改字符集
(3)修改索引字段的字符長(zhǎng)度
在 Mysql 版本 <=5.7.6 且字符集為 utf8mb4 的情況下,設(shè)置需要添加索引的字段長(zhǎng)度為 191。
(4)在 Mysql<=5.7.6 的情況,修改 InnoDB 選項(xiàng),將單字段索引長(zhǎng)度限制由 767 字節(jié)(bytes)提高到 3072 字節(jié)。
先查看當(dāng)前默認(rèn)選項(xiàng)值:
SHOW VARIABLES LIKE 'innodb_large_prefix'; SHOW VARIABLES LIKE 'innodb_file_per_table'; SHOW VARIABLES LIKE 'innodb_file_format';
確認(rèn)選項(xiàng)值是否是:
innodb_large_prefix=ON innodb_file_per_table=ON innodb_file_format=Barracuda
如果不是,進(jìn)行相應(yīng)的修改:
SET GLOBAL innodb_large_prefix = 1; SET GLOBAL innodb_file_per_table = 1; SET GLOBAL innodb_file_format = barracuda;
上面兩項(xiàng)的值設(shè)置為 1 而不是 ON,是因?yàn)樵?Mysql5.6 之前,布爾值的變量還無(wú)法識(shí)別 ON 或者 OFF,只能是數(shù)字 1 或者 0。
并且,在創(chuàng)建新表時(shí)還要指定 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;
或修改當(dāng)前表:
ALTER TABLE [...], ROW_FORMAT=DYNAMIC;
(5)在創(chuàng)建索引時(shí)限制字段上的前綴索引長(zhǎ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é)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
mysql?自增長(zhǎng)約束(auto_increment)的使用
MySQL中的自增長(zhǎng)約束(auto_increment)用于自動(dòng)為表的主鍵字段生成唯一的遞增值,通過(guò)設(shè)置該屬性,可以簡(jiǎn)化主鍵的管理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-11-11mysql通過(guò)查看跟蹤日志跟蹤執(zhí)行的sql語(yǔ)句
在SQL SERVER下跟蹤sql采用事件探查器,而在mysql下如何跟蹤sql呢,下面有個(gè)不錯(cuò)的方法,大家可以參考下2014-01-01MySQL無(wú)法存儲(chǔ)emoji表情解決方案分析
這篇文章主要介紹了MySQL無(wú)法存儲(chǔ)emoji表情解決方案,結(jié)合實(shí)例形式分析了Python爬蟲(chóng)爬取文章中emoji表情存入數(shù)據(jù)庫(kù)的實(shí)現(xiàn)方法,涉及mysql utf8mb4編碼的修改相關(guān)操作技巧,需要的朋友可以參考下2018-07-07使用Canal和Kafka解決MySQL與緩存的數(shù)據(jù)一致性問(wèn)題
這篇文章主要介紹了使用Canal和Kafka解決MySQL與緩存的數(shù)據(jù)一致性問(wèn)題,文中通過(guò)圖文結(jié)合的方式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-07-07