mysql索引過長Specialed key was too long的解決方法
在創建要給表的時候遇到一個有意思的問題,提示Specified key was too long; max key length is 767 bytes,從描述上來看,是Key太長,超過瞭指定的 767字節限制
下面是產生問題的表結構
CREATE TABLE `test_table` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(1000) NOT NULL DEFAULT '', `link` varchar(1000) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `name` (`name`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
我們可以看到,對於name,我們設置長度為1000可變字符,因為采用utf8mb4編碼, 所以它的大小就變成瞭 1000 * 4 > 767
所以再不修改其他配置的前提下,varchar的長度大小應該是 767 / 4 = 191
有興趣的同學可以測試下,分別指定name大小為191, 192時,是不是前面的可以創建表成功,後面的創建表失敗,並提示錯誤Specified key was too long; max key length is 767 bytes
解決辦法一
- 使用innodb引擎
- 啟用innodb_large_prefix選項,修改約束擴展至3072字節
- 重新創建數據庫
my.cnf配置
set global innodb_large_prefix=on; set global innodb_file_per_table=on; set global innodb_file_format=BARRACUDA; set global innodb_file_format_max=BARRACUDA;
上面這個3072字節的得出原因如下
我們知道InnoDB一個page的默認大小是16k。由於是Btree組織,要求葉子節點上一個page至少要包含兩條記錄(否則就退化鏈表瞭)。
所以一個記錄最多不能超過8k。又由於InnoDB的聚簇索引結構,一個二級索引要包含主鍵索引,因此每個單個索引不能超過4k (極端情況,pk和某個二級索引都達到這個限制)。
由於需要預留和輔助空間,扣掉後不能超過3500,取個“整數”就是(1024*3)。
解決辦法二
在創建表的時候,加上 row_format=DYNAMIC
CREATE TABLE `test_table` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL DEFAULT '', `link` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 row_format=DYNAMIC;
這個參數的作用如下
MySQL 索引隻支持767個字節,utf8mb4 每個字符占用4個字節,所以索引最大長度隻能為191個字符,即varchar(191),若想要使用更大的字段,mysql需要設置成支持數據壓縮,並且修改表屬性 row_format ={DYNAMIC|COMPRESSED}
到此這篇關於mysql索引過長Specialed key was too long的解決方法的文章就介紹到這瞭,更多相關mysql索引過長內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- MySQL 字段默認值該如何設置
- Mysql通過ibd文件恢復數據的詳細步驟
- 詳解MySQL自增主鍵的實現
- mysql中int(3)和int(10)的數值范圍是否相同
- MySQL 利用frm文件和ibd文件恢復表數據