Mysql中varchar类型的猫腻!
varchar的存储规则
4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节)。
5.0版本以上,varchar(20),指的是20字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放20个,最大大小是65532字节。
varchar 字段是将实际内容单独存储在聚簇索引之外,内容开头用1到2个字节表示实际长度。
官方是这么说的:
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.
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.
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和char 的区别
区别一,定长和变长
char 表示定长,长度固定,varchar表示变长,即长度可变。当所插入的字符串超出它们的长度时,视情况来处理,如果是严格模式,则会拒绝插入并提示错误信息,如果是宽松模式,则会截取然后插入。如果插入的字符串长度小于定义长度时,则会以不同的方式来处理,如char(10),表示存储的是10个字符,无论你插入的是多少,都是10个,如果少于10个,则用空格填满。而varchar(10),小于10个的话,则插入多少个字符就存多少个。
varchar怎么知道所存储字符串的长度呢?实际上,对于varchar字段来说,需要使用一个(如果字符串长度小于255)或两个字节(长度大于255)来存储字符串的长度。但是因为他需要有一个prefix来表示他具体bytes数是多少(因为varchar是变长的,没有这个长度值他不知道如何读取数据)。
区别之二,存储的容量不同
对 char 来说,最多能存放的字符个数 255,和编码无关。
而 varchar 呢,最多能存放 65532 个字符。VARCHAR 的最大有效长度由最大行大小和使用的字符集确定。整体最大长度是 65,532字节
varchar的编码长度限制
字符类型若为 gbk,则个字符最多占2个字节,最大长度不能超过32766; 字符类型若为utf8,则每个字符最多占3个字节,最大长度不能超过21845。 若定义的时候超过上述限制,则varchar字段会被强行转为text类型,并产生warning。
行长度限制
导致实际应用中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。
这就是说,比如创建一个表,表结构中有两个varhcar类型字段,那么这两个字段的总长度不能超过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的控制位
MySQL 中的Varchar字符类型还保留了1个字节来留其它控制信息。
示例
示例一:若一张表中只有一个字段VARCHAR(N)类型,utf8编码,则N最大值为多少?
如:create table tb_name1(a varchar(N)) default charset=utf8,则N最大值=(65535-1-2)/3=21844。
减1的原因是实际行存储从第二个字节开始。
减2的原因是varchar头部的2个字节表示长度。
除3的原因是字符编码是utf8。
sql测试:
create table tb_name1(a varchar(21844)) default charset=utf8;
Query OK, 0 rows affected (0.38 sec)
drop table tb_name1;
Query OK, 0 rows affected (0.00 sec)
create table tb_name1(a varchar(21845)) 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
示例二:若一张表中有一个字段VARCHAR(N)类型,并且有其它的字段类型,utf8编码,则N的最大值为多少?
如:create table tb_name2(a int, b char(20), c varchar(N)) default charset=utf8;
则:N最大值=(65535-1-2-4-203)/3=21822
减1的原因是实际行存储从第二个字节开始。
减2的原因是varchar头部的2个字节表示长度。
减4的原因是a字段的int类型占4个字节。
减203的原因是char(20)占用60个字节,编码是utf8。
sql测试:
create table tb_name2(a int, b char(20), c varchar(21822)) default charset=utf8;
Query OK, 0 rows affected (0.28 sec)
drop table tb_name2;
Query OK, 0 rows affected (0.20 sec)
create table tb_name2(a int, b char(20), c varchar(21823)) 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
实例三:若一张表中有多字段VARCHAR(N)类型,并且有其它的字段类型,gbk编码,则N的最大值为多少?
如:create table tb_name3(a int, b char(20), c varchar(50), d varchar(N)) default charset=gbk;
则:N最大值=(65535-1-1-2-4-202-502)/2=32693
第一个减1的原因是实际行存储从第二个字节开始。
第二个减1表示第二个varchar(50)头部一个1个字节表示长度(小于255)。
减2的原因是varchar头部的2个字节表示长度。
减202的原因是char(20)占用40个字节,编码是gbk。
减502的原因是varchar(50)占用100个字节,编码是gbk。
SQL测试:
create table tb_name3(a int, b char(20), c varchar(50), d varchar(32694)) default 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
create table tb_name3(a int, b char(20), c varchar(50), d varchar(32693)) default charset=gbk;
Query OK, 0 rows affected (0.18 sec)
Mysql中varchar类型的猫腻!的更多相关文章
- MySQL中varchar类型在5.0.3后的变化
1.mysql varchar类型变化:mysql 5.0.3 之前: 0--255字节 varchar(20)中的20表示字节数,如果存放urf8编码的话只能放6个汉字. MySQL 5.0.3 之 ...
- 2020-06-07:mysql中varchar类型的id,where id=1,会用到索引吗?int 类型的id,where id="1",会用到索引吗?为什么?
福哥答案2020-06-07: 答案来自群员:对于int类型id,查询的varchar 类型 ‘1’会隐式转换成 1,‘1’和 1都能正常走索引:对于varchar类型id,查询的int 类型 1不会 ...
- MySQL中varchar类型排序
-- +0后就转换INT类型排序 SELECT * FROM T_TEST ORDER BY (SORT + 0) DESC ;
- mysql中字符串类型char(n)和varchar(n)的区别
n的含义 根据网络上找到的结果(不能保证准确),在5.0.3以后版本中,n均代表字符数,而不是字节数:我用来测试的版本是5.7.20,该版本中,n表示字符数. 验证过程如下 建表 CREATE TAB ...
- 【转】MySQL中varchar最大长度是多少?
一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...
- int(11)最大长度是多少,MySQL中varchar最大长度是多少(转)
int(11)最大长度是多少,MySQL中varchar最大长度是多少? int(11)最大长度是多少? 在SQL语句中int代表你要创建字段的类型,int代表整型,11代表字段的长度. 这个11代表 ...
- 浅谈mysql中varchar(m)与char(n)的区别与联系
mysql建表长度的限制 在mysql建表时,出现以下报错信息: 错误一:行大小过大,所使用的表这种类型的最大的行大小,不算BLOB类型,是65535.(这是我翻译的) 原因是MySQL在建表的 ...
- 计算:表中varchar类型的字段能容纳的最大字符数?
建表语句: CREATE TABLE `test2` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `content` varchar(21842) NOT ...
- MySQL中varchar最大长度是多少?
一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...
随机推荐
- PyQt(Python+Qt)学习随笔:Qt Designer中连接Action和槽函数
在Designer中试了半天,终于找到了Action添加槽函数的方法,操作步骤: 在Designer右边界面中点击鼠标右键 确保信号/槽编辑被勾选,如图是未勾选的情况:. 勾选后会出现信号和槽的编辑界 ...
- 解读 authentication.py
""" Provides various authentication policies. """ import base64 import ...
- day010|python之装饰器
装饰器02 目录 装饰器02 1 装饰器的语法糖 1.1 定义 1.2 基本使用 2 有参装饰器 2.1 基本用法 2.2 示例 3叠加多个装饰器 3.1 基本用法 3.2 示例 4 wraps装饰器 ...
- 模拟数组 push() 方法
var array =[]; Array.prototype.push = function (){ for (var i=0; i< arguments.length; i++){ this[ ...
- Zabbix 新版微信告警-转载
Zabbix 新版微信告警 Zabbix可以通过多种方式把告警信息发送到指定人,常用的有邮件,短信报警方式,但是越来越多的企业开始使用zabbix结合微信作为主要的告警方式,这样可以及时有效的把告警信 ...
- Python不同包之间调用注意事项
1.不同包之间调用,因为在不同文件夹下,引用的时候加上包名就可以了.运行时,在eclipse直接运行没有问题.但是在,命令行运行时出现找不到模块的错误.原因是,Python只搜索当前目录和内置模块以及 ...
- Scala中的IO操作及ArrayBuffer线程安全问题
通过Scala对文件进行读写操作在实际业务中应用也比较多,这里介绍几种常用的方式,直接上代码: 1. 从文件中读取内容 object Main { def loadData(): Array[Stri ...
- 图像处理论文详解 | Deformable Convolutional Networks | CVPR | 2017
文章转自同一作者的微信公众号:[机器学习炼丹术] 论文名称:"Deformable Convolutional Networks" 论文链接:https://arxiv.org/a ...
- Linux vmstat 使用说明
摘自 https://www.thomas-krenn.com/en/wiki/Linux_Performance_Measurements_using_vmstat Linux Performanc ...
- Python高级语法-多继承MRO相关-多继承顺序(4.5.1)
@ 目录 1.说明 2.代码 关于作者 1.说明 使用类的魔法方法__mro__ 可以查看他的父类调用顺序 还有调用父类的构造方法的时候,使用super调用,里面有C3算法支持,不会重复调用相同的祖先 ...