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个字节。

减20
3的原因是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。

减50
2的原因是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类型的猫腻!的更多相关文章

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

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

  2. 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不会 ...

  3. MySQL中varchar类型排序

    -- +0后就转换INT类型排序 SELECT * FROM T_TEST ORDER BY (SORT + 0) DESC ;

  4. mysql中字符串类型char(n)和varchar(n)的区别

    n的含义 根据网络上找到的结果(不能保证准确),在5.0.3以后版本中,n均代表字符数,而不是字节数:我用来测试的版本是5.7.20,该版本中,n表示字符数. 验证过程如下 建表 CREATE TAB ...

  5. 【转】MySQL中varchar最大长度是多少?

    一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...

  6. int(11)最大长度是多少,MySQL中varchar最大长度是多少(转)

    int(11)最大长度是多少,MySQL中varchar最大长度是多少? int(11)最大长度是多少? 在SQL语句中int代表你要创建字段的类型,int代表整型,11代表字段的长度. 这个11代表 ...

  7. 浅谈mysql中varchar(m)与char(n)的区别与联系

    mysql建表长度的限制 在mysql建表时,出现以下报错信息: 错误一:行大小过大,所使用的表这种类型的最大的行大小,不算BLOB类型,是65535.(这是我翻译的)    原因是MySQL在建表的 ...

  8. 计算:表中varchar类型的字段能容纳的最大字符数?

    建表语句: CREATE TABLE `test2` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `content` varchar(21842) NOT ...

  9. MySQL中varchar最大长度是多少?

    一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...

随机推荐

  1. 第15.16节 PyQt(Python+Qt)入门学习:PyQt中的信号(signal)和槽(slot)机制以及Designer中的使用

    老猿Python博文目录 老猿Python博客地址 一.引言 前面一些章节其实已经在使用信号和槽了,但是作为Qt中最重要的机制也是Qt区别与其他开发平台的重要核心特性,还是非常有必要单独介绍. 二.信 ...

  2. cookie的理解

    第一:每个特定的域名下最多生成20个cookie IE6或更低版本最多20个cookie IE7和之后的版本最多可以有50个cookie Firefox最多50个cookie chrome和Safar ...

  3. 网络拓扑实例13:IPv4静态路由与NQA联动简介

    组网图形 IPv4静态路由与NQA联动简介 网络质量分析NQA(Network Quality Analysis)是一种实时的网络性能探测和统计技术,可以对响应时间.网络抖动.丢包率等网络信息进行统计 ...

  4. AcWing 322. 消木块

    由于木块可以由一些木块的消除,使两边相同颜色的合并 所以我们设定一个归并方式,即每个区间记录一下右边的延展性. (等于左边找右边) 设 \(f[i][j][k]\) 为\([i, j]\) 区间,右侧 ...

  5. Python迭代器&生成器&装饰器

    1. 迭代器 1.1 可迭代对象(Iterator) 迭代器协议:某对象必须提供一个__next__()方法,执行方法要么返回迭代中的下一项,要么引起一个Stopiteration异常,以终止迭代(只 ...

  6. tornado 作业 自定义模板 UIMethod以UIModule

    自定义uimodule s3.py import tornado.ioloop import tornado.web import UIMethod as mt class MainHandler(t ...

  7. USB接口禁用小工具v1.0.1

    由论坛用户原创制作的一个USB接口工具, 可选择手动/自动启动或者禁止启动模式, 开启禁止启动模式后USB接口将关闭识别功能, 有效防止U盘设备侵入,对于机房实验室设施来说相当管用. 下载地址:htt ...

  8. 跨站点脚本编制 - SpringBoot配置XSS过滤器(基于Jsoup)

    1. 跨站点脚本编制   风险:可能会窃取或操纵客户会话和 cookie,它们可能用于模仿合法用户,从而使黑客能够以该用户身份查看或变更用户记录以及执行事务.   原因:未对用户输入正确执行危险字符清 ...

  9. js 控制输入框保存数字级小数点后一位

    $('#Question8').on('keyup', function () { var regVoter = $("#Question8").val(); regVoter = ...

  10. String概述

    String的基本特性 String是字符串,使用一对引号("")包装. String声明是final的,不可被继承. String实现了Serializable接口,表示字符串是 ...