一. varchar存储规则:

4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 
5.0版本以上,varchar(20),指的是20字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放20个,最大大小是65532字节 
Mysql4中最大也不过是20个字节,但是Mysql5根据编码不同,存储大小也不同。

二. varchar和char 的区别:

char是一种固定长度的类型,varchar则是一种可变长度的类型,它们的区别是: char(M)类型的数据列里,每个值都占用M个字节,如果某个长度小于M,MySQL就会在它的右边用空格字符补足.(在检索操作中那些填补出来的空格字符将被去掉)在varchar(M)类型的数据列里,每个值只占用刚好够用的字节再加上一个用来记录其长度的字节(即总长度为L+1字节).

在MySQL中用来判断是否需要进行对据列类型转换的规则

1、在一个数据表里,如果每一个数据列的长度都是固定的,那么每一个数据行的长度也将是固定的.

2、只要数据表里有一个数据列的长度的可变的,那么各数据行的长度都是可变的.

3、如果某个数据表里的数据行的长度是可变的,那么,为了节约存储空间,MySQL会把这个数据表里的固定长度类型的数据列转换为相应的可变长度类型.例外:长度小于4个字符的char数据列不会被转换为varchar类型

被问到一个问题: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”了。

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

create table t4(c int, c2 char(30), c3 varchar(21812)) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

create table t5(c int, c2 varchar(30), c3 varchar(21812)) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

varchar(30)和char(30)最多能存放:

工在基工左基工在基顺工作奔大规模集成电路城工作东奔西走左夺工城鞯革城载模压地工魂牵梦萦栽土木工程魂牵梦萦栽植奇巧魂牵梦萦地厅城柑模压东奔西走苦村落模压革革柑可耕地村模压基栽魂牵梦基

 

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

 

111111111111111111111111111111111111111111111111111111

111111111111111111111111111111111111

CREATE TABLE `t` (                   
          `var` varchar(21844) default NULL   
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8

可以正常的执行。

[SQL] CREATE TABLE `t` (

`var` varchar(21845) default NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8

[Err] 1118 - 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

执行有错误

[MySQL]如何计算varchar最大长度

这里有一道我YY出来的关于MySQL的题:
表设计如下

  id  mediumint        
 name  varchar

问题是:  MySQL5.1 ,  在GBK字符环境下,这里的varchar最长能设多长?

正确答案是: 32764

那如果表设计为两个 varchar,   第一个长度设为300时,第二个varchar应该多长?  --答案见本文最后面

要想搞明白是怎么算出来的,请仔细下面的解释:
官方文档上对 int 及 varchar 的说明如下:


 
Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 255 before MySQL 5.0.3, and 0 to 65,535 in 5.0.3 and later versions.

看到这里,你以为上面的varchar长度是: 65535 /2=32767?  
不对,因为官方文档后面又说:
In contrast to CHAR, VARCHAR values are stored as a one-byte or two-byte length prefix plus data. The length prefix indicates the number of bytes in the value.
很明白了,varchar会保留一至两个字节来存放长度信息,但到底是1Byte还是2Byte? 
往后看:
A column uses one length byte if values require no more than 255 bytes, two length bytes if values may require 
more than 255 bytes.
你再来算一算varchar长度 最大为: (65535-2) /2 = 32766 ?
还是不对!
其实每一行的总长度是有限制的,即最大为65535.  
Every table has a maximum row size of 65,535 bytes. 
This maximum applies to all storage engines, but a given engine might have additional constraints that result in a lower effective maximum row size.
所以算varchar得把id的扣除:
(65535-3-2) /2 = 32765 ?

测试一下:
root@saker 05:27:28>create table t4(id mediumint, name varchar(32765));
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

用32764测试一下:
root@saker 05:27:31>create table t4(id mediumint, name varchar(32764));
Query OK, 0 rows affected (0.16 sec)
 
root@saker 05:27:35>desc t4;
+-------+----------------+------+-----+---------+-------+
| Field | Type           | Null | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| id    | mediumint(9)   | YES  |     | NULL    |       |
| name  | varchar(32764) | YES  |     | NULL    |       |
+-------+----------------+------+-----+---------+-------+

这说明还保留了1至2个字节来留其它控制信息。(在文档里面我没有找到说明,所以也不知道到底是1个还是2个byte)
但我想到了一个方法来反推出来,
我把id的类型从medium改成 int ,这时id的长度就从3变为4了,如果控制字节用了2Bytes,那varchar的长度还设为32764的话,显然是要报错的。。。
root@saker 05:29:14>create table t3(id int, name varchar(32764));
Query OK, 0 rows affected (0.18 sec)
root@saker 07:01:10>desc t3;
+-------+----------------+------+-----+---------+-------+
| Field | Type           | Null | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| id    | int(11)        | YES  |     | NULL    |       |
| name  | varchar(32764) | YES  |     | NULL    |       |
+-------+----------------+------+-----+---------+-------+
这样应该能说明,控制位只有1个字节。

下面用这个结论来计算第二个问题:
那如果表设计为两个 varchar,   第一个长度设为300时,第二个varchar应该多长?
(65535-1-2-2-300*2) /2 =  32465
测试一下:
root@saker 07:09:23>create table t1(id varchar(300), name varchar(32465));
Query OK, 0 rows affected (0.15 sec)
 
root@saker 07:09:26>desc t1;
+-------+----------------+------+-----+---------+-------+
| Field | Type           | Null | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| id    | varchar(300)   | YES  |     | NULL    |       |
| name  | varchar(32465) | YES  |     | NULL    |       |
+-------+----------------+------+-----+---------+-------+
2 rows in set (0.02 sec)

多一位都不行:
root@saker 07:08:12>create table t1(id varchar(300), name varchar(32466));
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

最后 把以上所有知识综合起来:
有一个表:
id int,   name1 char(20),  name2 varchar(100), name3 varchar(?)

算一下:
(65535-1-1-2-4-20*2-100*2) /2 = 32643

root@saker 07:16:09>create table tt(id int, name1 char(20), name2 varchar(100), name3 varchar(32643));
Query OK, 0 rows affected (0.18 sec)
 
root@saker 07:16:12>desc tt;
+-------+----------------+------+-----+---------+-------+
| Field | Type           | Null | Key | Default | Extra |
+-------+----------------+------+-----+---------+-------+
| id    | int(11)        | YES  |     | NULL    |       |
| name1 | char(20)       | YES  |     | NULL    |       |
| name2 | varchar(100)   | YES  |     | NULL    |       |
| name3 | varchar(32643) | YES  |     | NULL    |       |
+-------+----------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
 
root@saker 07:15:08>create table tt(id int, name1 char(20), name2 varchar(100), name3 varchar(32644));
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类型 最大长度是多少?相关推荐

  1. numeric转换varchar_数据库中varchar类型数据转换为numeric类型

    关于数据库中varchar/nvarchar类型数据的获取注意事项 当在页面后台获取数据库表中某字段的数据时,需注意该数据的类型.防止因实际数据的字符长度因达不到指定数据类型规定的字符长度而导致空格的 ...

  2. 数据库中varchar类型长度是指字符长度还是字节长度?两种定义方法

    Oracle中varchar2类型的字段长度单位默认是按照byte来定义, 比如常见写法varchar2(10)  代表只接收最大10字节长度 这种定义情况下10字节只能插入3个汉字,(数字字母只占一 ...

  3. 数据库中字段类型对应的C#中的数据类型

    数据库中字段类型对应C#中的数据类型: 数据库                 C#程序 int int32 text string bigint int64 binary System.Byte[] ...

  4. mysql 数据库中varchar的存储单位是什么

    一.先了解字节与字符 字节(Byte)是计量单位,表示数据量多少,是计算机信息技术用于计量存储容量的一种计量单位,通常情况下一字节等于八位. 字符(Character)计算机中使用的字母.数字.字和符 ...

  5. java中时间入数据库格式转换_数据库中字段类型为datetime,转换成java中的Date类型...

    数据类型对照 点击打开链接 JDBC: PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuer ...

  6. 使用MyBatis Plus 3.2.0版本插件代码生成器生成实体类后,对于数据库中字段类型datetime的字段会转变为LocalDateTime类型

    问题描述: 使用MyBatis Plus 3.2.0版本插件代码生成器生成实体类后,对于数据库中字段类型datetime的字段会转变为LocalDateTime类型,IDEA提示报错"Usa ...

  7. mysql varchar 中英文_MySQL5.1中varchar类型中文和英文长度的问题

    今天,也是突发奇想,在MySQL上验证varchar(15)会存15个中文,超过的会自动截取前15个. 一直抱守旧的观念(这种观念可能来源与s 今天,也是突发奇想,在MySQL上验证varchar(1 ...

  8. 数据库中的datatime的长度怎么设定_软件测试必备之数据库知识(一)

    无论是运维.开发.测试,还是架构师,数据库技术是一个必备加薪神器,那么,一直说学习数据库.学MySQL,到底是要学习它的哪些东西呢? 1.如何快速掌握MySQL? ​培养兴趣 兴趣是最好的老师,不论学 ...

  9. MySQL中varchar类型在5.0.3后的变化

    1.mysql varchar类型变化: mysql 5.0.3 之前: 0--255字节 varchar(20)中的20表示字节数,如果存放urf8编码的话只能放6个汉字. MySQL 5.0.3 ...

最新文章

  1. 用ASP.NET如何读取NT用户名
  2. python中的encode()和decode()函数_python里面的encode和decode函数
  3. 常用的 分布式事务 都有哪些?我该用哪个?
  4. java txt中文乱码,JAVA读取TXT文件 可解决中文乱码问题
  5. php mysql 登录注销_laravel 实现用户登录注销并限制功能
  6. 0.2 控制系统的状态空间表示法
  7. boost::process::env相关的测试程序
  8. server输出几行 sql_如何将SQL Server存储过程的输出存储在.txt文件中
  9. 服务器交换机项目购买,四川大学网络空间安全研究院服务器、交换机等采购项目...
  10. “寒武纪大爆发”之后的云原生,2021年走向何处?
  11. 数仓(一)简介数仓,OLTP和OLAP
  12. webpack4打包js
  13. PLATO上线LAAS协议Elephant Swap,用户可借此获得溢价收益
  14. antd日期选择组件a-range-picker默认选中的时分秒
  15. 免费ssl申请且如何应用到宝塔
  16. 《老路用得上的商学课》21-30学习笔记
  17. ATAC-seq数据分析(一)
  18. Matlab之绘制三维曲面图
  19. NOAA气象监测数据下载(可下载最新及每日气象数据)
  20. rocksdb的基本操作

热门文章

  1. mysql查看数据库时区CST
  2. CIDR地址块及其子网划分(内含原始IP地址分类及其子网划分的介绍)
  3. 高校学生“在家实践”计划 怎么样可以免费领取12个月阿里云ECS云服务器的方法
  4. 论文阅读笔记:Glyce: Glyph-vectors for Chinese Character Representations
  5. mybatis 之缓存接口
  6. 基于jsp的高校网上订餐系统设计与实现(项目报告+答辩PPT+源代码+数据库+截图+部署视频)
  7. AD中的所有域帐户经常被锁定
  8. Nordic系列芯片讲解八( Nordic SDK常见特殊指令汇集)
  9. 蜡炬教育:如何处理机器学习中大型数据的加载问题?
  10. delegate的用法