mysql 每个单表中对索引长度是有限制的,且根据不同的数据引擎会有所不同。
下面以mysql 5.5.47 版本为例做相应的说明。
MYISAM表
1、创建一个字符编码为utf8的表 test
create table test(id int,name1 varchar(300),name2 varchar(300),name3 varchar(500)) CHARSET=utf8 engine=myisam;
然后创建组合索引
create index list on test(name1,name2,name3);
这个时候会报
[Err] 1071 - Specified key was too long; max key length is 1000 bytes
索引没有创建成功,因为三列长度总和300+300+500超过了1000字节,所以报错。
在name2上创建索引
create index name2 on test(name2)
创建成功
CREATE TABLE `test` (
`id` int(11) DEFAULT NULL,
`name1` varchar(300) DEFAULT NULL,
`name2` varchar(300) DEFAULT NULL,
`name3` varchar(500) DEFAULT NULL,
KEY `name2` (`name2`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
在name3上 创建索引
create index name3 on test(name3)
CREATE TABLE `test` (
`id` int(11) NOT NULL,
`name1` varchar(1) DEFAULT NULL,
`name2` varchar(300) DEFAULT NULL,
`name3` varchar(500) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `name3` (`name3`(333)),
KEY `name2` (`name2`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
创建索引成功但长度被截取为name3
(333)。
2、创建一个字符编码为latin1 的表 test1
create table test1(id int,name1 varchar(300),name2 varchar(300),name3 varchar(500)) CHARSET=latin1 engine=myisam;
然后创建组合索引
create index list on test1(name1,name2,name3);
报错:[SQL]create index list on test1(name1,name2,name3);
[Err] 1071 - Specified key was too long; max key length is 1000 bytes
创建索引失败
在name2 创建索引
create index name2 on test1(name2)
CREATE TABLE `test1` (
`id` int(11) DEFAULT NULL,
`name1` varchar(300) DEFAULT NULL,
`name2` varchar(300) DEFAULT NULL,
`name3` varchar(500) DEFAULT NULL,
KEY `name2` (`name2`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
创建成功
在name3上 创建索引
create index name3 on test1(name3)
CREATE TABLE `test1` (
`id` int(11) DEFAULT NULL,
`name1` varchar(300) DEFAULT NULL,
`name2` varchar(300) DEFAULT NULL,
`name3` varchar(500) DEFAULT NULL,
KEY `name3` (`name3`),
KEY `name2` (`name2`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
删除name3索引
drop index name3 on test1;
增加name2 宽度为1500
ALTER TABLE test1 MODIFY name3 VARCHAR(1500);
在name3上 创建索引
create index name3 on test1(name3)
CREATE TABLE `test1` (
`id` int(11) DEFAULT NULL,
`name1` varchar(300) DEFAULT NULL,
`name2` varchar(300) DEFAULT NULL,
`name3` varchar(1500) DEFAULT NULL,
KEY `name2` (`name2`),
KEY `name3` (`name3`(1000))
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
创建索引成功但长度被截取为name3
(1000)。
InnoDB表
1、创建一个字符编码为utf8的表 test 3
create table test3(id int,name1 varchar(300),name2 varchar(300),name3 varchar(500)) CHARSET=utf8 engine=InnoDB;
然后创建组合索引
create index list on test3(name1,name2,name3);
CREATE TABLE `test3` (
`id` int(11) DEFAULT NULL,
`name1` varchar(300) DEFAULT NULL,
`name2` varchar(300) DEFAULT NULL,
`name3` varchar(500) DEFAULT NULL,
KEY `list` (`name1`(255),`name2`(255),`name3`(255))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
创建成功,索引为 KEY list
(name1
(255),name2
(255),name3
(255))
在name2 创建索引
create index name2 on test3(name2)
CREATE TABLE `test3` (
`id` int(11) DEFAULT NULL,
`name1` varchar(300) DEFAULT NULL,
`name2` varchar(300) DEFAULT NULL,
`name3` varchar(500) DEFAULT NULL,
KEY `list` (`name1`(255),`name2`(255),`name3`(255)),
KEY `name2` (`name2`(255))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
索引为 KEY name2
(name2
(255))
在name3上 创建索引
create index name3 on test3(name3)
CREATE TABLE `test3` (
`id` int(11) DEFAULT NULL,
`name1` varchar(300) DEFAULT NULL,
`name2` varchar(300) DEFAULT NULL,
`name3` varchar(500) DEFAULT NULL,
KEY `list` (`name1`(255),`name2`(255),`name3`(255)),
KEY `name2` (`name2`(255)),
KEY `name3` (`name3`(255))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
索引为KEY name3
(name3
(255))
2、创建一个字符编码为latin1 的表 test4
create table test4(id int,name1 varchar(300),name2 varchar(300),name3 varchar(500)) CHARSET=latin1 engine=InnoDB;
然后创建组合索引
create index list on test4(name1,name2,name3);
创建成功
CREATE TABLE `test4` (
`id` int(11) DEFAULT NULL,
`name1` varchar(300) DEFAULT NULL,
`name2` varchar(300) DEFAULT NULL,
`name3` varchar(500) DEFAULT NULL,
KEY `list` (`name1`,`name2`,`name3`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
在name2 创建索引
create index name2 on test4(name2)
CREATE TABLE `test4` (
`id` int(11) DEFAULT NULL,
`name1` varchar(300) DEFAULT NULL,
`name2` varchar(300) DEFAULT NULL,
`name3` varchar(500) DEFAULT NULL,
KEY `list` (`name1`,`name2`,`name3`),
KEY `name2` (`name2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
索引为 KEY name2
(name2
)
在name3 创建索引
create index name3 on test4(name3)
CREATE TABLE `test4` (
`id` int(11) DEFAULT NULL,
`name1` varchar(300) DEFAULT NULL,
`name2` varchar(300) DEFAULT NULL,
`name3` varchar(500) DEFAULT NULL,
KEY `list` (`name1`,`name2`,`name3`),
KEY `name2` (`name2`),
KEY `name3` (`name3`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
修改name3的宽度为1000
ALTER TABLE test4 MODIFY name3 VARCHAR(1000);
在查看表的信息
CREATE TABLE `test4` (
`id` int(11) DEFAULT NULL,
`name1` varchar(300) DEFAULT NULL,
`name2` varchar(300) DEFAULT NULL,
`name3` varchar(1000) DEFAULT NULL,
KEY `list` (`name1`,`name2`,`name3`(767)),
KEY `name2` (`name2`),
KEY `name3` (`name3`(767))
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
索引变为 KEY list
(name1
,name2
,name3
(767)),
KEY name2
(name2
),
KEY name3
(name3
(767))
总结
1、对于myisam表,组合索引的长度跟各个列总和长度有关。
字符编码为utf8,组合索引长度和不能超333,超过则创建失败。单列索引不能超过333,如果字段超过333,则最终创建的是前缀索引(即取前333个字节)。
字符编码为latin1,组合索引长度和不能超1000,超过则创建失败。单列索引不能超过1000,超过则最终创建的是前缀索引(即取前1000个字节)。
2、对于Innodb表,组合索引的长度跟各列的长度和无关,跟单列的长度有关,且能创建成功。
字符编码为utf8,组合索引长度最大为:列数*255( name1
(255),name2
(255),name3
(255)),单列索引长度最大为255。
字符编码为latin1,组合索引长度最大为:列数*767(例如:name1
,name2
,name3
(767)),单列索引最大为767。
3、索引的长度跟数据引擎有关,还和字符编码有关。
参考:https://dev.mysql.com/doc/refman/5.7/en/create-index.html