MySQL中需要注意的字段长度问题
在MySQL的表结构设计中,突然想起来几个地方碰到的问题比较多,大体来说一个就是字符集,一个就是数据类型。
而字符集和数据类型结合起来,就有一个蛮有意思的细节,那就是行长度的问题。
比如我们创建一个表使用了varchar的类型,如果指定为gbk,表里含有一个字段,可以指定为32766字节,如果再长一些就不行了。
其中的计算方式就需要理解了,因为varhcar类型长度大于255,所以需要2个字节存储值的长度,而MySQL里面的页的单位是16k,使用了IOT的方式来存储。所以如果超过了这个长度,那就会有溢出的情况,和Oracle的overflow很类似。
所以对于gbk类型,行长度最大为65535,则varchar列的最大长度算法就是 (65535-2)/2 =32766.5,所以此处就是32766了。
> create table test_char(v varchar(32766)) charset=gbk;
Query OK, 0 rows affected (0.00 sec)
> create table test_char1(v varchar(32767)) charset=gbk;
ERROR
1118 (42000): Row size too large. The maximum row size for the used
table type, not counting BLOBs, is 65535. You have to change some
columns to TEXT or BLOBs而另外一种字符集,也是默认的字符集latin1,有些系统支持火星文的还是会喜欢用这种字符集。
它的长度就不一样了,对应是1字节,所以varchar(32767)是没有任何问题的,而最大长度就是65532了。
> create table test_char1(v varchar(32767)) charset=latin1;
Query OK, 0 rows affected (0.01 sec)
> create table test_char2(v varchar(65535)) charset=latin1;
ERROR
1118 (42000): Row size too large. The maximum row size for the used
table type, not counting BLOBs, is 65535. You have to change some
columns to TEXT or BLOBs而对于utf8还是有很大的差别,对应的是3个字节,所以需要除以3,按照(65535-2)/3,最大值就是21844了。
> create table test_char2(v varchar(21844)) charset=utf8;
Query OK, 0 rows affected (0.00 sec)
> create table test_char3(v varchar(21845)) charset=utf8;
ERROR
1118 (42000): Row size too large. The maximum row size for the used
table type, not counting BLOBs, is 65535. You have to change some
columns to TEXT or BLOBs上面的场景相对来说会有一些局限性,那么我们引入表结构的设计。
如果是gbk字符集,含有下面的几个字段,则memo字段的varchar类型最大长度是多少?
> create table test_char3(id int,name varchar(20),memo varchar(32766)) charset=gbk;
ERROR
1118 (42000): Row size too large. The maximum row size for the used
table type, not counting BLOBs, is 65535. You have to change some
columns to TEXT or BLOBs
这个问题还是如法炮制,应用之前的计算方式,数值型是4个字节,字符型乘以2,含有字符型的长度小于255,所以减去1即可,这样下来就是(65535-1-4-20*2-2)约等于32743
> create table test_char3(id int,name varchar(20),memo varchar(32744)) charset=gbk;
ERROR
1118 (42000): Row size too large. The maximum row size for the used
table type, not counting BLOBs, is 65535. You have to change some
columns to TEXT or BLOB两种测试结果可以简单对比一下。
> create table test_char3(id int,name varchar(20),memo varchar(32743)) charset=gbk;
Query OK, 0 rows affected (0.01 sec)
select (65535-1-4-20*2-2)/2;
+———————-+
| (65535-1-4-20*2-2)/2 |
+———————-+
| 32744.0000 |
+———————-+
1 row in set (0.00 sec)
整个过程还是需要考虑到这些点的,否则前期不够重视,在后面去做扩展的时候就会有很大的限制。
本文来源:SecYe安全网[http://www.secye.com] (责任编辑:SecYe安全)
- ·SQL自动审核-自助上线平台
- ·MySQL 及 SQL 注入
- ·可视化管理工具 MySQL Workbench
- ·提高MySQL性能的7个技巧
- ·MySQL中需要注意的字段长度问题
- ·CentOS 64下编译安装MySQL 5614
- ·怎样将 MySQL 迁移到 MariaDB
- ·MySQL在Windows Server上安装多个实例的
- ·mysql 5.7.17 winx64.zip安装配置方法图
- ·MySQL 5.7 zip版本(zip版)安装配置步骤详
- ·MySQL安全配置
- ·Mysql5.7忘记root密码怎么办(简单且有效
- ·Mysql5.7忘记root密码及mysql5.7修改root
- ·MySQL数据库的备份方法介绍
- ·linux服务器清空MySQL的history历史记录
- ·MySQL和PostgreSQL数据库安全配置
- ·SQL自动审核-自助上线平台
- ·MySQL 及 SQL 注入
- ·可视化管理工具 MySQL Workbench
- ·提高MySQL性能的7个技巧
- ·MySQL中需要注意的字段长度问题
- ·CentOS 64下编译安装MySQL 5614
- ·怎样将 MySQL 迁移到 MariaDB
- ·MySQL在Windows Server上安装多个实例的方
- ·mysql 5.7.17 winx64.zip安装配置方法图文
- ·MySQL 5.7 zip版本(zip版)安装配置步骤详解
- ·MySQL安全配置
- ·Mysql5.7忘记root密码怎么办(简单且有效方
- ·Mysql5.7忘记root密码及mysql5.7修改root密
- ·MySQL数据库的备份方法介绍
- ·linux服务器清空MySQL的history历史记录 删
- ·MySQL手册版本 5.0.20-MySQL同步(四)
- ·从SQL Server导出到MYSQL的简单方法
- ·MySQL手册版本 5.0.20-MySQL优化(五)
- ·MySQL手册版本 5.0.20-MySQL优化(六)
- ·怎样从Windows命令行启动MySQL?
- ·一步步教你在Windows环境下安装MySQL
- ·mysql4,mysql4.1,mysql 5共存
- ·MySQL数据库德集群配置一般过程
- ·MySQL 5.0在windows上的安装详细介绍
- ·MySQL数据导入导出工具mysqlimport简介
- ·MySQL中文参考手册--获得数据库和表的信
- ·让Mysql在查询时区分大小写
- ·Mysql常用命令大全
- ·MySQL在CentOS中的初次使用配置