varchar(N),N指的是最大字符数,不是字节数。

记住:

(1)MySQL要求一个行的定义长度不能超过65535。

(2)单个字段如果大于65535,则转换为TEXT 。

(3)单行最大限制为65535,这里不包括TEXT、BLOB。

(4)utf8:
1character=3bytes, 1汉字=1character
也就是说一个字段定义成 varchar(200),则它可以存储200个汉字或者200个字母。
(5)gbk:
1character=2bytes,1汉字=1character
也就是说一个字段定义成 varchar(200),则它可以存储200个汉字或者200个字母。

在MySQL建表时,遇到一个奇怪的现象:

root@localhost : test 10:30:54>CREATE TABLE tb_test (-> recordid varchar(32) NOT NULL,-> areaShow varchar(10000) DEFAULT NULL,-> areaShow1 varchar(10000) DEFAULT NULL,-> areaShow2 varchar(10000) DEFAULT NULL,-> PRIMARY KEY (recordid)-> ) ENGINE=INNODB DEFAULT 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
报错root@localhost : test 10:31:01>CREATE TABLE tb_test (-> recordid varchar(32) NOT NULL,-> areaShow varchar(30000) DEFAULT NULL,-> areaShow1 varchar(30000) DEFAULT NULL,-> areaShow2 varchar(30000) DEFAULT NULL,-> PRIMARY KEY (recordid)-> ) ENGINE=INNODB DEFAULT CHARSET=utf8;
Query OK, 0 rows affected, 3 warnings (0.26 sec)
可以建立,只是类型被转换了。root@localhost : test 10:31:14>show warnings;
+-------+------+----------------------------------------------------+
| Level | Code | Message                                            |
+-------+------+----------------------------------------------------+
| Note  | 1246 | Converting column 'areaShow' from VARCHAR to TEXT  |
| Note  | 1246 | Converting column 'areaShow1' from VARCHAR to TEXT |
| Note  | 1246 | Converting column 'areaShow2' from VARCHAR to TEXT |
+-------+------+----------------------------------------------------+
3 rows in set (0.00 sec)

疑问:

为什么字段小(10000)的反而报错,而大(30000)的则可以建立。为什么小的不能直接转换呢?

解决:

原来MySQL在建表的时候有个限制:MySQL要求一个行的定义长度不能超过65535。具体的原因可以看:

http://dev.mysql.com/doc/refman/5.1/en/silent-column-changes.html

(1)单个字段如果大于65535,则转换为TEXT 。

(2)单行最大限制为65535,这里不包括TEXT、BLOB。

按照上面总结的限制,来解释出现的现象:

第一个情况是:
单个字段长度:varchar(10000) ,字节数:10000*3(utf8)+(1 or 2) = 30000 ,小于65535,可以建立。
单行记录长度:varchar(10000)3,字节数:300003(utf8)+(1 or 2) = 90000,大于65535,不能建立,所以报错:

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

第二个情况是:
单个字段长度:varchar(30000) ,字节数:30000*3+(1 or 2) = 90000 , 大于65535,需要转换成TEXT,才可以建立。所以报warnings。
单行记录长度:varchar(30000)*3,因为每个字段都被转换成了TEXT,而TEXT没有限制,所以可以建立表。

root@localhost : test 10:31:14>show warnings;
+-------+------+----------------------------------------------------+
| Level | Code | Message                                            |
+-------+------+----------------------------------------------------+
| Note  | 1246 | Converting column 'areaShow' from VARCHAR to TEXT  |
| Note  | 1246 | Converting column 'areaShow1' from VARCHAR to TEXT |
| Note  | 1246 | Converting column 'areaShow2' from VARCHAR to TEXT |
+-------+------+----------------------------------------------------+

用了这么久的MySQL,这个基本的建表限制都还不知道,惭愧啊。。

原因如下:

被问到一个问题:MySQL中varchar最大长度是多少?这不是一个固定的数字。本文简要说明一下限制规则。

1、限制规则

字段的限制在字段定义的时候有以下规则:

a) 存储限制

​ varchar 字段是将实际内容单独存储在聚簇索引之外,内容开头用1到2个字节表示实际长度(长度超过255时需要2个字节),因此最大长度不能超过65535。

b) 编码长度限制

​ 字符类型若为gbk,每个字符最多占2个字节,最大长度不能超过32766;

​ 字符类型若为utf8,每个字符最多占3个字节,最大长度不能超过21845。

​ 若定义的时候超过上述限制,则varchar字段会被强行转为text类型,并产生warning。

c) 行长度限制

​ 导致实际应用中varchar长度限制的是一个行定义的长度。 MySQL要求一个行的定义长度不能超过65535。若定义的表长度超过这个值,则提示

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。

2、计算例子

举两个例说明一下实际长度的计算。

a)若一个表只有一个varchar类型,如定义为

​ create table t4(c varchar(N)) charset=gbk;

​ 则此处N的最大值为(65535-1-2)/2= 32766。

​ 减1的原因是实际行存储从第二个字节开始’;

​ 减2的原因是varchar头部的2个字节表示长度;

​ 除2的原因是字符编码是gbk。

b) 若一个表定义为

​ create table t4(c int, c2 char(30), c3 varchar(N)) charset=utf8;

​ 则此处N的最大值为 (65535-1-2-4-30*3)/3=21812

​ 减1和减2与上例相同;

​ 减4的原因是int类型的c占4个字节;

​ 减30*3的原因是char(30)占用90个字节,编码是utf8。

如果被varchar超过上述的b规则,被强转成text类型,则每个字段占用定义长度为11字节,当然这已经不是“varchar”了。

MySQL建表字段长度的限制、汉字和字母占字节数相关推荐

  1. MySQL 建表字段长度的限制问题

    在MySQL建表时,遇到一个奇怪的现象: root@localhost : test 10:30:54>CREATE TABLE tb_test ( -> recordid varchar ...

  2. NAVICAT MYSQL 建表字段 默认值、EMPTY STRING、空白、NULL 的区别

    Navicat mysql 建表字段 默认值.empty string.空白.NULL 的区别 总结在最后,没啥干货 简单测试了4种类型 bigint tinyint varchar char 单引号 ...

  3. 计算字符串长度(可同时字母和汉字,字母占一个字符,汉字占2个字符)

    charCodeAt() 定义和用法 : charCodeAt() 方法可返回指定位置的字符的 Unicode 编码.这个返回值是 0 - 65535 之间的整数. 方法 charCodeAt() 与 ...

  4. 字符集及八种编码对汉字和字母所占字节数

    字符集 1.ASII:美国标准信息交换码,用一个字节的7位可以表示: 2.ISO8859-1:拉丁码表,欧洲码表,用一个字节的8位可以表示: 3.GBK2312:中国的中文编码表,最多两个字节编码所有 ...

  5. mysql 创建表字段长度范围_Mysql的建表规范与注意事项

    一. 表设计规范 库名.表名.字段名必须使用小写字母,"_"分割. 库名.表名.字段名必须不超过12个字符. 库名.表名.字段名见名知意,建议使用名词而不是动词. 建议使用Inno ...

  6. mysql建表字段属性为clob_MySQL建表的优化策略

    MySQL 建表的优化策略 目录 1. 字符集的选择 1 2. 主键 1 3. 外键 2 4. 索引 2 4.1. 以下情况适合于创建索引 2 4.2. 以下的情况下不适合创建索引 3 4.3. 联合 ...

  7. mysql修改表字段长度和添加表字段

    1.修改表字段长度 alter table message_record modify column title varchar(130); alter table 表名 modify column ...

  8. MySql中用sql语句实现按汉字首字母排序

    转载自https://blog.csdn.net/hulinyi123456/article/details/79915521 1.mysql 1)按照汉字的拼音排序 如果存储汉字的字段编码使用的是G ...

  9. 各类编码格式中汉字和字母所占字节数

    编码格式: 1.ASII:美国标准信息交换码,用一个字节的7位可以表示: 2.ISO8859-1:拉丁码表,欧洲码表,用一个字节的8位可以表示: 3.GBK2312:中国的中文编码表,最多两个字节编码 ...

最新文章

  1. UITextField的代理方法
  2. python3 正则表达式 匹配多个 单词 字符串
  3. pandas的DataFrame用法
  4. 互联网晚报 | 11月21日 星期日 | B站公布《三体》动画首个预告片;涪陵榨菜回应天价礼盒;农行个人贷款余额突破7万亿元...
  5. Zookeeper的一些Bugs
  6. 虚拟机从网卡路由问题
  7. html设置功能区菜单,html – 具有“3D”效果的功能区
  8. 2016值得关注的5大IT趋势
  9. android 布局中的单位及分辨率自解
  10. 极客学院腾讯 TAPD·极客开放日 [敏捷开发畅想与实战]
  11. mysql 错误代码:1293
  12. Win2012 R2 IIS8.5+PHP(FastCGI)+MySQL运行环境搭建教程
  13. springboot整合mybatis-pluss、sharding-JDBC 水平分表demo
  14. Android开发指南-窗口小部件(App Widgets)
  15. 淘宝网发展史:揭开神秘组织的技术内幕与艰辛历程
  16. Android App Bundle出来了,App加壳技术不能用了怎么办?
  17. js移动端文字提示框
  18. 扒一扒网易云课堂python课程,发现还有不少可以白嫖的免费好资源
  19. 需求调研第三篇--现场调研阶段容易犯哪些错误
  20. 批量添加搜狗域名绑站工具

热门文章

  1. Java PipedInputStream close()方法与示例
  2. mysql怎样查表的模式_mysql常用基础操作语法(四)--对数据的简单无条件查询及库和表查询【命令行模式】...
  3. python 发送邮件connect none_使用python向IP地址发送邮件
  4. python爬虫与django_请问django和爬虫程序如何整合?
  5. mysql查看日志命令_面对成百上千台服务器产生的日志,试试这款轻量级日志搬运神器!...
  6. 计算机故障检修课过时,第三场公开课|电脑故障维修以及笔记本知识科普
  7. Java LocalDate类| isLeapYear()方法与示例
  8. nodejs字符与字节之间的转换
  9. CentOS7 源码编译安装Redis shell脚本
  10. java数组怎么倒循环_java – 用于数组倒计时的反向循环