varchar列的定义与索引创建在MySQL5.6和5.7下的限制

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 一、varchar(M)列的定义限制 其中M指的是可存储的字符长度(或字符数),而MySQL实际是按字节存储的,在不同的字符集下一个字符的字节长不同,因此这个M最大值在不同的字符集下值不同: 对于latin字符集下,因为一个字符占一个字节,所以M的最大值为65535(但实际只有65532);对于gbk字符集,因为一个字符占两个字节,所以M的最大值为32767;对于utf8字符集,因为一个字符占两到三个字节,所以M的最大值为21845。

一、varchar(M)列的定义限制

其中M指的是可存储的字符长度(或字符数),而MySQL实际是按字节存储的,在不同的字符集下一个字符的字节长不同,因此这个M最大值在不同的字符集下值不同:

对于latin字符集下,因为一个字符占一个字节,所以M的最大值为65535(但实际只有65532);对于gbk字符集,因为一个字符占两个字节,所以M的最大值为32767;对于utf8字符集,因为一个字符占两到三个字节,所以M的最大值为21845。

此外,mysql官方文档中定义的65535长度是指同一行的所有varchar列的长度总和。如果列的长度总和超出这个长度,依然无法创建。

1、MySQL5.6的限制方式:

在MySQL5.6版本中,当某个列的varchar长度定义超过相应字符集下的最大长度时,会自动将该列转存为mediumtext类型。例如,在utf8字符集下,定义ecs_payment表test2字段长度为21846:
_1
可以看到test2字段被存为mediumtext类型。

假如再存储一个字段test3,定义varchar长度为21845,这时没有超过最大长度限制,但在存储test3 varchar(21845)列时,发现该表上所有varchar行的总长度将会超过65535字节,因此会发生如下报错:

mysql> alter table ecs_payment add test3 varchar(21845);
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs

2、MySQL5.7的限制方式:

在MySQL5.7版本下,只要列的varchar长度超过相应字符集下的最大限制,或者表上所有varchar列总长度将会超过65535字节时,MySQL都会抛出错误提示:

mysql> alter table t1 add c1 varchar(21846);
ERROR 1074 (42000): Column length too big for column 'c1' (max = 21845); use BLOB or TEXT instead
mysql> alter table t1 add c1 varchar(21844);
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs

二、创建索引的限制

对于varchar列,当varchar长度过长时,会对索引的创建有限制,在MySQL5.6和5.7下的限制行为的表现形式不同。

1、MySQL5.6的限制

在MySQL5.6中,对ecs_payment表的test varchar(1024)列创建索引,并查看创建后的情况:

_1

可以看到test列上建立了一个前缀索引,前缀长度为255字节。在MySQL5.6下,varchar长度超过255字节时是不适合建立索引的,MySQL会自动只建立255字节长的前缀索引,而不是抛出错误。

2、MySQL5.7的限制

在MySQL5.7版本下,varchar列上可建索引的最大长度是3072字节,超过此长度在建索引时会报错:

mysql> alter table t1 add column c4 varchar(1025);
Query OK, 0 rows affected (0.04 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> create index i_2 on t1(c4);
ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes

表t1是utf8字符集。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
10天前
|
关系型数据库 MySQL 索引
mysql 分析5语句的优化--索引添加删除
mysql 分析5语句的优化--索引添加删除
11 0
|
16天前
|
存储 关系型数据库 MySQL
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
轻松入门MySQL:优化进销存管理,掌握MySQL索引,提升系统效率(11)
|
21天前
|
存储 自然语言处理 关系型数据库
ElasticSearch索引 和MySQL索引那个更高效实用那个更合适
ElasticSearch索引 和MySQL索引那个更高效实用那个更合适
35 0
|
22天前
|
SQL 存储 关系型数据库
MySQL not exists 真的不走索引么
MySQL not exists 真的不走索引么
24 0
|
25天前
|
SQL 存储 关系型数据库
对线面试官 - 如何理解MySQL的索引覆盖和索引下推
索引下推是MySQL 5.6引入的优化,允许部分WHERE条件在索引中处理,减少回表次数。例如,对于索引(zipcode, lastname, firstname),查询`WHERE zipcode='95054' AND lastname LIKE '%etrunia%'`时,索引下推先过滤zipcode,然后在索引中应用lastname条件,降低回表需求。索引下推可在EXPLAIN的`Using index condition`中看到。
对线面试官 - 如何理解MySQL的索引覆盖和索引下推
|
1月前
|
监控 关系型数据库 MySQL
MySQL创建索引的注意事项
在数据库设计和优化中,索引的合理使用是提高查询性能和加速数据检索的关键因素之一。通过选择适当的列、了解数据分布、定期维护和监控索引性能,我们能够最大程度地发挥索引的优势,提高数据库的效率和响应速度。
29 0
|
1月前
|
关系型数据库 MySQL 数据库
MySQL索引和查询优化
MySQL索引和查询优化
33 1
|
1月前
|
SQL 关系型数据库 MySQL
MySQL索引与事务
MySQL索引与事务
|
1月前
|
监控 关系型数据库 MySQL
MySQL创建索引的注意事项
在索引的世界中,权衡是关键。权衡读写性能,权衡索引的数量和类型,权衡查询的频率和数据分布。通过谨慎的设计、定期的维护和持续的监控,我们能够确保索引在数据库中的角色得到最大的发挥,为应用提供更加高效和可靠的数据访问服务。在数据库优化的旅途中,索引是我们的得力助手,正确使用它将使数据库系统更具竞争力和可维护性。
18 0
|
1月前
|
存储 关系型数据库 MySQL
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
162 0