专注系统运维、网络架构,研究技术凯发app官方网站的解决方案,记录我的思想轨迹、工作学习、生活和关注的领域
分类: mysql/postgresql
2013-01-31 16:54:23
在修改表结构时出现了错误:specified key was too long;max key length is 1000 bytes.
mysql版本为server version: 5.1.36, 执行sql为:
alter table pre_common_diy_data modify column targettplname varchar(255);
如果是按一个字符占两个字节计算 2*255=510 并没有超过1000字符,怎么会报错呢?
在查询相关资料后发现,mysql myisam 存储引擎在创建索引的时候,索引键长度是有一个较为严格的长度限制的,所有索引键最大长度总和不能超过1000,而且不是实际数据长度的总和,而是索引键字段定义长度的总和。
主要字符集的计算方式如下:
latin1 = 1 byte = 1 character
uft8 = 3 byte = 1 character
gbk = 2 byte = 1 character
1、查看mysql存储引擎,默认存储引擎为myisam。
mysql> show engines;
------------ --------- ----------------------------------------------------------- -------------- ------ ------------
| engine | support | comment | transactions | xa | savepoints |
------------ --------- ----------------------------------------------------------- -------------- ------ ------------
| mrg_myisam | yes | collection of identical myisam tables | no | no | no |
| csv | yes | csv storage engine | no | no | no |
| memory | yes | hash based, stored in memory, useful for temporary tables | no | no | no |
| myisam | default | default engine as of mysql 3.23 with great performance | no | no | no |
------------ --------- ----------------------------------------------------------- -------------- ------ ------------
4 rows in set (0.00 sec)
2、我们查看mysql表结构,总索引长度为:(100 80)=180
mysql> desc pre_common_diy_data;
--------------- ----------------------- ------ ----- --------- -------
| field | type | null | key | default | extra |
--------------- ----------------------- ------ ----- --------- -------
| targettplname | varchar(100) | no | pri | | |
| tpldirectory | varchar(80) | no | pri | | |
| primaltplname | varchar(255) | no | | | |
| diycontent | mediumtext | no | | null | |
| name | varchar(255) | no | | | |
| uid | mediumint(8) unsigned | no | | 0 | |
| username | varchar(15) | no | | | |
| dateline | int(10) unsigned | no | | 0 | |
--------------- ----------------------- ------ ----- --------- -------
8 rows in set (0.00 sec)
3、查看表的字符集,为utf8字符,那么索引总长度为:180*3=480
mysql> show create table pre_common_diy_data;
--------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| table | create table |
--------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| pre_common_diy_data | create table `pre_common_diy_data` (
`targettplname` varchar(240) not null default '',
`tpldirectory` varchar(80) not null default '',
`primaltplname` varchar(255) not null default '',
`diycontent` mediumtext not null,
`name` varchar(255) not null default '',
`uid` mediumint(8) unsigned not null default '0',
`username` varchar(15) not null default '',
`dateline` int(10) unsigned not null default '0',
primary key (`targettplname`,`tpldirectory`)
) engine=myisam default charset=utf8 |
--------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1 row in set (0.00 sec)
再查看我们的执行报错sql:
alter table pre_common_diy_data modify column targettplname varchar(255);
计算总长度:(80 255)*3=1005,已经超过了1000,所以出错。
解决的方法是减少字段的长度:
alter table pre_common_diy_data modify column targettplname varchar(240);
执行成功。
另外对于创建innodb的组合索引,也是有索引键长度长度限制的。