我有两个MySQL数据库实例,比如说:TST和DEV。
TST:
mysql --version
mysql Ver 14.14 Distrib 5.6.40, for Linux (x86_64) using EditLine wrapper
DEV:
mysql --version
mysql Ver 14.14 Distrib 5.6.41, for Linux (x86_64) using EditLine wrapper
两种环境下的版本几乎相同。
两个实例上的数据库具有相同的架构和相同的数据。
问题表的结构如下:
CREATE TABLE `searchItem` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`dataType` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
`value` varchar(1024) COLLATE utf8_unicode_ci NOT NULL,
`creationTime` datetime NOT NULL,
`modificationTime` datetime NOT NULL,
`contentId` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `IDX_36F9E76573A18A3B` (`contentId`),
KEY `content_type` (`contentId`,`type`),
CONSTRAINT `FK_36F9E76573A18A3B` FOREIGN KEY (`contentId`) REFERENCES `content` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23518 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
现在我想在列值(1024)上添加索引。我知道在我的情况下,索引大小限制为255。
在DEV上:
CREATE INDEX value_type ON searchItem (value, type);
Query OK, 0 rows affected, 1 warning (0.30 sec)
现在我有:
CREATE TABLE `searchItem` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`dataType` varchar(4) COLLATE utf8_unicode_ci NOT NULL,
`value` varchar(1024) COLLATE utf8_unicode_ci NOT NULL,
`creationTime` datetime NOT NULL,
`modificationTime` datetime NOT NULL,
`contentId` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `IDX_36F9E76573A18A3B` (`contentId`),
KEY `content_type` (`contentId`,`type`),
KEY `value_type` (`value`(255),`type`),
CONSTRAINT `FK_36F9E76573A18A3B` FOREIGN KEY (`contentId`) REFERENCES `content` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23518 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
因此它会自动将索引切为最大大小(255),这对我来说是预期的行为。
但在TST上
CREATE INDEX value_type ON searchItem (value, type);
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
在my.cnf文件中没有发现任何差异。
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[isamchk]
key_buffer_size = 16M
[mysqld]
basedir = /usr
bind-address = 0.0.0.0
character-set-server = utf8
datadir = /var/lib/mysql
default_storage_engine = InnoDB
expire_logs_days = 10
init-connect = SET NAMES utf8
innodb_file_per_table = 1
key_buffer_size = 16M
log-error = /var/log/mysql/error.log
max_allowed_packet = 128M
max_binlog_size = 100M
max_connections = 151
myisam_recover = BACKUP
pid-file = /var/run/mysqld/mysqld.pid
port = 3306
query_cache_limit = 1M
query_cache_size = 16M
skip-external-locking
socket = /var/run/mysqld/mysqld.sock
ssl = false
ssl-ca = /etc/mysql/cacert.pem
ssl-cert = /etc/mysql/server-cert.pem
ssl-key = /etc/mysql/server-key.pem
thread_cache_size = 8
thread_stack = 256K
tmpdir = /tmp
user = mysql
[mysqld_safe]
log-error = /var/log/mysql/error.log
nice = 0
socket = /var/run/mysqld/mysqld.sock
[mysqldump]
max_allowed_packet = 128M
quick
quote-names
编辑:
问题的实质:
在DEV上:
CREATE INDEX value_type ON searchItem (value, type);
Query OK, 0 rows affected, 1 warning (0.30 sec)
但在TST上
CREATE INDEX value_type ON searchItem (value, type);
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
问题是为什么它在每种环境下的行为都不同?是否有任何配置参数可以对此负责?
答案 0 :(得分:0)
您使用哪种类型的引擎?在MySQL版本5.6(及更低版本)中,InnoDB表的前缀限制为767个字节。 MyISAM表的长度为999个字节(或1000,记不清了)
您可以切换引擎类型或升级到MySQL 5.7,这会限制到3K
答案 1 :(得分:0)
这是Strict SQL Mode的作用:
从MySQL 5.6.11开始,严格模式在尝试创建超出最大密钥长度的密钥时会产生错误。以前,这会导致警告并把密钥截断为最大密钥长度(与未启用严格模式时相同)。
在没有严格模式的情况下,允许MySQL调整值使其适合,然后将错误减少为警告;这是您在运行语句时收到的警告。
您可以使用select @@sql_mode
检查当前的sql模式(TST
服务器可能包含例如STRICT_TRANS_TABLES
,而DEV
不包含)。可以在运行时在全局和每个会话期间更改该设置,因此可能有人或某些更改了该设置。