MySQL varchar 最大长度,text 类型占用空间剖析

摘要:
char和varchar可以有默认值,text不能指定默认值。

MySQL 表中行的最大大小为 65,534(实际行存储从第二个字节开始)字节。每个 BLOB 和 TEXT 列只占其中的 5 至 9 个字节。

那么来验证下 varchar 类型的实际最大长度:
测试环境:MySQL版本 5.7.19

//首先要设置下 mysql 为严格执行模式,不然 varchar 超出最大长度为自动转为 text 类型
set sql_mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";
[SQL]
CREATE TABLE test(
    va VARCHAR(21845)
)DEFAULT CHARSET=utf8;
1118 - 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

这里看到 21,845 个字符,utf-8 下刚好为 65,535 个字节,但是 varchar 保存时用一个字节或两个字节长的前缀+数据。如果 varchar 列声明的长度大于 255,长度前缀是两个字节,所以 varchar 的最大长度应为:

65532=65535-1-2(字节)
utf-8 下为 21844=65532/3(字符)

看示例:

[SQL]
CREATE TABLE test(
    va VARCHAR(21844)
)DEFAULT CHARSET=utf8;
Query OK, 0 rows affected

那么看下 text 类型在实际行中占用的字节数:

[SQL]
CREATE TABLE test1(
    va VARCHAR(21841),
    tx text
)DEFAULT CHARSET=utf8;
1118 - 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

可以看出错误提示,行长已经超过最大长度。在上文看到,

每个 BLOB 和 TEXT 列只占其中的 5 至 9 个字节。

但是 va 字段已经给 tx 字段腾出了 9 字节的空间了啊,为什么还是不行呢。
从官方文档看到

BLOB 和 TEXT 类型需要 1、2、3 或者 4 个字节来记录列值的长度,取决于该类型的最大可能的长度。

那么就是至少需要 10 字节(9+1)的空间了,再试一下:

[SQL]
CREATE TABLE test1(
    va VARCHAR(21840),
    tx text
)DEFAULT CHARSET=utf8;
Query OK, 0 rows affected

这里看到,当 va 字段腾出 12 字节的空间时,表可以创建成功。

varchar 最长是 64k,但是注意 这里的 64k 是整个 row 的长度,要考虑到其它的 column,还有如果存在 not null 的时候也会占用一位,对不同的字符集,有效长度还不一样,比如 utf8,最多 21,845,还要除去别的 column,但是 varchar 在一般情况下存储都够用了。

如果遇到了大文本,考虑使用 text,最大能到 4G。效率来说基本是 char>varchar>text,但是如果使用的是 Innodb 引擎的话,推荐使用 varchar 代替 char。char 和 varchar 可以有默认值,text 不能指定默认值。

免责声明:文章转载自《MySQL varchar 最大长度,text 类型占用空间剖析》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【C#】unsigned char类型使用ganymed工具调用ssh2下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

CMD下查询Mysql中文乱码的解决方法

我的MySQL是默认utf8编码的,所建数据库也是设置utf8编码,使用程序可以新增中文数据,在cmd中使用SQL语句新增数据则报类似Incorrect string value: 'xB2xE2xCAxD4' for column 'title' at row 1错误,而使用SQL语句查询出之前程序所新增中文数据都是乱码的。 如下图 右击在cmd界面上面...

MySQL 用 binlog 及备份进行回滚/恢复

MySQL 运用 binlog 及备份进行回滚/恢复 引言 如果碰到数据错误,需要进行回滚/恢复,可以利用 binlog 文件及备份进行操作。但是请注意,没有提前备份文件,或者没有开启 binlog 日志文件,不适用此方法。 如果数据库建立在云端,可以向相关服务提供商要求恢复;如果自建,建议找找其他办法,或者咨询专业的数据恢复服务。 回滚/恢复 1...

MySQL配置主主及主从备份

MySQL主从备份配置实例 场景: 1、主服务器192.168.0.225、从服务器192.168.0.226。其中,主服务器上已有数据。 2、主从服务器上的mysql版本及安装配置相同。 一、主从备份的原理: 主服务器数据库的每次操作都会记录在二进制日志文件mysql-bin.xxx中。从服务器的I/O线程使用专用帐号登陆到主服务器中读取该二进制文件,并...

debezium关于cdc的使用(上)

博文原址:debezium关于cdc的使用(上) 简介 debezium是一个为了捕获数据变更(cdc)的开源的分布式平台。启动并指向数据库,当其他应用对此数据库执行inserts、updates、delete操作时,此应用快速得到响应。debezium是持久化和快速响应的,因此你的应用可以快速响应且不会丢失任意一条事件。debezium记录是数据库表的行...

SQL 分页实现

--通用分页 ALTER PROCEDURE [dbo].[Sys_Pagination_1] @tblName VARCHAR(2000) , -- 表名 @strGetFields VARCHAR(1000) = '*' , -- 需要返回的列 @fldName VARCHAR(255) = '' , -- 排序的字段名 @PageSize...

hive权威安装出现的不解错误!(完美解决)两种方法都可以

   以下两种方法都可以,推荐用方法一! 如果有误,请见博客 MySQL用户权限(Host,User,Password)管理(mysql.user)   可以自己去增加和删除用户。别怕,zhouls! 方法一:   步骤一: yum -y install mysql-server   步骤二:service mysqld start   步骤三:my...