精华内容
下载资源
问答
  • varchar最大长度
    千次阅读
    2019-11-22 11:52:41

    MySQL5.0.3之前varchar(n)这里的n表示字节数

    MySQL5.0.3之后varchar(n)这里的n表示字符数,比如varchar(200),不管是英文还是中文都可以存放200个

    • varchar最大长度可以是多少

    根据字符集,字符类型若为gbk,每个字符占用2个字节,最大长度不能超过65535/2 =32766; 字符类型若为utf8,每个字符最多占用3个字节,最大长度不能超过 65535/3 =21845,若超过这个限制,则会自动将varchar类型转为mediumtext或longtext,例如

    mysql> create table test12(id int(10),context varchar(79000));
    Query OK, 0 rows affected, 1 warning (0.03 sec)
    
    mysql> show create table test12;
    +--------+--------------------------------------------------------------------------------------------------------------------+
    | Table  | Create Table                                                                                                       |
    +--------+--------------------------------------------------------------------------------------------------------------------+
    | test12 | CREATE TABLE `test12` (
      `id` int(10) DEFAULT NULL,
      `context` mediumtext
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
    +--------+--------------------------------------------------------------------------------------------------------------------+
    1 row in set (0.01 sec)
    
    
    更多相关内容
  • 今天群里有人问varchar 不是最大应该只可以设置65532(第一个字节+两个长度字节)吗 ,但是为什么可以设置成65533
  • 转自: ... ... 一. varchar存储规则: ...4.0版本以下,varchar(20),指的...5.0版本以上,varchar(20),指的是20字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放20个,最大大小是65532字节 ...

    转自:

    https://www.cnblogs.com/gomysql/p/3615897.html

    https://developer.aliyun.com/article/8826

    目前看到的是表有限制,库没有限制。

     

    一. varchar存储规则:

    4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 
    5.0版本以上,varchar(20),指的是20字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放20个,最大大小是65532字节 

     

    二. varchar和char 的区别:

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

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

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

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

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

     

     

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

     

    1、限制规则

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

    a) 存储限制

    varchar最多能存储65535个字节的数据。varchar 的最大长度受限于最大行长度(max row size,65535bytes)。65535并不是一个很精确的上限,可以继续缩小这个上限。65535个字节包括所有字段的长度,变长字段的长度标识(每个变长字段额外使用1或者2个字节记录实际数据长度)、NULL标识位的累计。

     

    NULL标识位,如果varchar字段定义中带有default null允许列空,则需要需要1bit来标识,每8个bits的标识组成一个字段。一张表中存在N个varchar字段,那么需要(N+7)/8 (取整)bytes存储所有的NULL标识位。

    如果数据表只有一个varchar字段且该字段DEFAULT NULL,那么该varchar字段的最大长度为65532个字节,即65535-2-1=65532 byte。

    mysql> create table t1 ( name varchar(65532) default null)charset=latin1;
    Query OK, 0 rows affected (0.09 sec)
    
    mysql> 
    mysql> create table t2 ( name varchar(65533) default null)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
    mysql> 

    可以看见当设置长度为65533时,已经超过行最大长度,我们可以计算一下,行最大长度是65535字节。上面t2表name字段使用varchar(65533),字符集是latin1,占用1个字节。还有默认为空,那么还有null标识位,( 1 + 7 ) / 8 =1,所以null标识位占用1个字节。现在我们来看看,65533 + 1 + 2=65536字节,已经大于行最大长度。这里2字节怎么来的???因为varchar类型存储变长字段的字符类型,与char类型不同的是,其存储时需要在前缀长度列表加上实际存储的字符,当存储的字符串长度小于255字节时,其需要1字节的空间,当大于255字节时,需要2字节的空间。

    如果数据表只有一个varchar字段且该字段NOT NULL,那么该varchar字段的最大长度为65533个字节,即65535-2=65533byte

    mysql> create table t2 ( name varchar(65533) not null) charset=latin1;   
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> 
    mysql> create table t3 ( name varchar(65534) not null) 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
    mysql> 

    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,例子如下:

    mysql> create table t4(c int, c2 char(30), c3 varchar(21812)) charset=utf8; 
    Query OK, 0 rows affected (0.05 sec)
    
    mysql> 
    mysql> create table t5(c int, c2 char(30), c3 varchar(21813)) 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
    mysql> 

     

    最后让我们来看一个例子

    复制代码

    CREATE TABLE t6 (
    id int,
    a VARCHAR(100) DEFAULT NULL,
    b VARCHAR(100) DEFAULT NULL,
    c VARCHAR(100) DEFAULT NULL,
    d VARCHAR(100) DEFAULT NULL,
    e VARCHAR(100) DEFAULT NULL,
    f VARCHAR(100) DEFAULT NULL,
    g VARCHAR(100) DEFAULT NULL,
    h VARCHAR(100) DEFAULT NULL,
    i VARCHAR(N) DEFAULT NULL
    ) CHARSET=utf8;                                                                                                                                                                                                                   

    复制代码

    那么上面这条语句中的varchar(N)的最大值是多少呢?

    让我们来计算一下

    每个NULL字段用1bit标识,10个字段都是default null,那么需要用(10+7)/8bit = 2 bytes存储NULL标识位。int占用4个 byte。

    (65535 - 1 - 2*8  -4 - 100*3*8 -2)/3=21037

    mysql> CREATE TABLE t6 ( id int, a VARCHAR(100) DEFAULT NULL, b VARCHAR(100) DEFAULT NULL, c VARCHAR(100) DEFAULT NULL, d VARCHAR(100) DEFAULT NULL, e VARCHAR(100) DEFAULT NULL, f VARCHAR(100) DEFAULT NULL, g VARCHAR(100) DEFAULT NULL, h VARCHAR(100) DEFAULT NULL, i VARCHAR(21037) DEFAULT NULL ) CHARSET=utf8;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> 
    mysql> CREATE TABLE t7 ( id int, a VARCHAR(100) DEFAULT NULL, b VARCHAR(100) DEFAULT NULL, c VARCHAR(100) DEFAULT NULL, d VARCHAR(100) DEFAULT NULL, e VARCHAR(100) DEFAULT NULL, f VARCHAR(100) DEFAULT NULL, g VARCHAR(100) DEFAULT NULL, h VARCHAR(100) DEFAULT NULL, i VARCHAR(21038) DEFAULT NULL ) 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
    mysql> 

     可以看见多一个字符都报错了。

    varchar到底能存多少个字符?这与使用的字符集相关,latin1、gbk、utf8编码存放一个字符分别需要占1、2、3个字节。

     

    3、varchar物理存储

    在物理存储上,varchar使用1到2个额外的字节表示实际存储的字符串长度(bytes)。如果列的最大长度小于256个字节,用一个字节表示(标识)。如果最大长度大于等于256,使用两个字节。

    当选择的字符集为latin1,一个字符占用一个byte

    varchar(255)存储一个字符,一共使用2个bytes物理空间存储数据实际数据长度和数据值。

    varchar(256)存储一个字符,使用2 bytes表示实际数据长度,一共需要3 bytes物理存储空间。

    varchar对于不同的RDBMS引擎,有不通的物理存储方式,虽然有统一的逻辑意义。对于mysql的不同存储引擎,其实现方法与数据的物理存放方式也不同。

    4、InnoDB中的varchar

    InnoDB中varchar的物理存储方式与InnoDB使用的innodb_file_format有关。早期的innodb_file_forma使用的Antelope文件格式,支持redundant和compact两种row_format。从5.5开始或者InnoDB1.1,可以使用一种新的file format,Barracuda。Barracuda兼容Redundant,另外还支持dynamic和compressed两种row_format.

    当innodb_file_format=Antelope,ROW_FORMAT=REDUNDANT 或者COMPACT。

    innodb的聚集索引(cluster index)仅仅存储varchar、text、blob字段的前768个字节,多余的字节存储在一个独立的overflow page中,这个列也被称作off-page。768个字节前缀后面紧跟着20字节指针,指向overflow pages的位置。

    另外,在innodb_file_format=Antelope情况下,InnoDB中最多能存储10个大字段(需要使用off-page存储)。innodbd的默认page size为16KB,InnoDB单行的长度不能超过16k/2=8k个字节,(768+20)*10 < 8k。

    当innodb_file_format=Barracuda, ROW_FORMAT=DYNAMIC 或者 COMPRESSED

    innodb中所有的varchar、text、blob字段数据是否完全off-page存储,根据该字段的长度和整行的总长度而定。对off-page存储的列,cluster index中仅仅存储20字节的指针,指向实际的overflow page存储位置。如果单行的长度太大而不能完全适配cluster index page,innodb将会选择最长的列作为off-page存储,直到行的长度能够适配cluster index page。

    5、MyISAM中的varchar

    对于MyISAM引擎,varchar字段所有数据存储在数据行内(in-line)。myisam表的row_format也影响到varchar的物理存储行为。

    MyISAM的row_format可以通过create或者alter sql语句设为fixed和dynamic。另外可以通过myisampack生成row_format=compresse的存储格式。

    当myisam表中不存在text或者blob类型的字段,那么可以把row_format设置为fixed(也可以为dynamic),否则只能为dynamic。

    当表中存在varchar字段的时候,row_format可以设定为fixed或者dynamic。使用row_format=fixed存储varchar字段数据,浪费存储空间,varchar此时会定长存储。row_format为fixed和dynamic,varchar的物理实现方式也不同(可以查看源代码文件field.h和field.cc),因而myisam的row_format在fixed和dynamic之间发生转换的时候,varchar字段的物理存储方式也将会发生变化。

     

     

     

    MySQL-没有必要的varchar(255)长度及存储汉字问题汇总

    起因

    最近在整理代码规范,按照之前oracle的习惯,定了以下的字段长度设定规范:

    • 名称字段:varchar(200)
    • 较长的名称字段/简介字段:varchar(500)
    • 特别长的描述字段: varchar(2000)
    • 超过2000中文字的字段:text
      为什么是200长度,而不是100或300,也是拍脑袋想的,类似DND里的房规。
      但在被问起为什么不设置为经常见到的varchar(255)时,一时回答不上来。趁这个机会,把字段长度这块的知识汇总梳理一下。

    为什么会经常被设置为varchar(255)

    MySQL 4.1版本之前,varchar的最大长度是255 byte字节(也有一说是5.0.3版本之前)。查了下这个版本发布都是2004年的事情了。惯性真恐怖,我可不相信还有多少系统是从2004年升级过来的。

    varchar(50)和varchar(255)有性能上的差别么?

    对于INNODB,varchar(50)varchar(255)这两者在存放方式上完全一样:1-2 byte保存长度,实际的字符串存放在另外的位置,每个字符1 byte到4 byte不定(视编码和实际存储的字符而定)。所以将一个字段从varchar(50)长度改成varchar(100)长度不会导致表的重建。但如果把长度从varchar(50)改成varchar(256)就不一样了,表示长度会需要用到2 byte或更多。

    既然255长度以下对INNODB都一样,而且我们平时基本上也不太会使用到MYISAM,那么是不是为了省心,我们就可以把255长度以下的字段的类型都设置成varchar(255)了呢?
    非也。
    因为内存表介意。
    虽然我们不会明文创建内存表,但所有的中间结果都会被数据库引擎存放在内存表。我们可以通过EXPLAIN或者SHOW STATUS可以查看MYSQL是否使用了内存表用来帮助完成某个操作。
    而内存表会按照固定长度来保存。以utf-8编码为例,对于varchar(255),每一行所占用的内存就是长度的2 byte + 3 * 255 byte。对于100条数据,光一个varchar字段就占约1GB内存。如果我们该用varchar(50),就可以剩下来约80%的内存空间。
    除此之外,255长度也可能会对索引造成坑。MySQL在5.6版本及之前的最大长度是767 byte。但MySQL 5.5版本后开始支持4个byte的字符集utf8mb4(沙雕表情用到的字符太多,长度不够用)。255 * 4 > 767,所以索引就放不下varchar(255)长度的字段了。虽然MySQL在5.7版本后将限制改成了3072 byte,但如果是多字段的联合索引还是有可能会超过这个限制。

    所以我们的结论就是:在长度够用的情况下,越短越好。

    varchar的最大长度是多少

    varchar的最大长度是65535 byte。所以

    • 字符类型若为gbk,每个字符最多占2个字节,最大长度不能超过32766字符
    • 字符类型若为utf8,每个字符最多占3个字节,最大长度不能超过21845字符
    • 字符类型若为utf8mb,每个字符最多占4个字节,最大长度不能超过16383字符
      但通常导致varchar长度限制的通常是一行定义的长度,就是表里所有字段定义的长度总和。这个限制也是65535 byte。如果超出长度,会报错:
      1
      
      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。
      

    这也是为什么阿里开发规范中这么要求:

    1
    
    【强制】varchar是可变长字符串,不预先分配存储空间,长度不要超过5000,如果存储长度大于此值,定义字段类型为text,独立出来一张表,用主键来对应,避免影响其它字段索引效率。
    

    varchar(50)是能保存16个汉字,还是25个,抑或50个?

    以前SQL Server的nvarchar转Oracle的varchar2时造成的固有印象,让我一直觉得varchar保存中文字时长度需要打对折或除以3。
    但这个也是MySQL 5.0版本之前的事。现在varchar(n)是几,就能存几个中文字。
    不过也需要注意统计字数使用CHARACTER_LENGTH而非LENGTH

    1
    2
    3
    4
    
    -- 返回为12
    SELECT LENGTH("轻松工作");
    -- 返回为4
    SELECT CHARACTER_LENGTH("轻松工作");
    

    为什么还是用MySQL

    为什么MySQL坑那么多,不改用PostgreSQL?
    相比MySQL,我个人更偏好PostgreSQL,能从各种设计细节就感觉得到很规范。但无奈国内分布式数据库方案基本都是基于MySQL的。。。虽然我们的场景在今年年内暂时也看不到用分布式的必要性,但万一有了呢。。。
    先发优势真是可怕。

    参考资料

     

    展开全文
  • VARCHAR最大长度、字符串类型选择,用MySQL的人中十之七八是不清楚的。网上文章鱼目混珠,以讹传讹居多。 本文不止介绍了原理,还提供了案例手把手教你自己分析,彻底解决你的疑惑

    如果要了解MySQL其他类型长度,可以参考《MySQL字段长度、取值范围、存储开销》

    以我多年经验来看,VARCHAR的最大长度、字符串类型选择,用MySQL的人中十之七八是不清楚的。网上文章鱼目混珠,以讹传讹居多。
    本文不止介绍了原理,还提供了案例手把手教你自己分析,彻底解决你的疑惑。

    假设有个VARCHAR(64) CHARSET utf8mb4列,存储了中国cn这个字符串。
    那你猜一猜,MySQL存储时用了多少字节?

    • A:4 Bytes
    • B:5 Bytes
    • C:8 Bytes
    • D:9 Bytes
    • E:10 Bytes
    • F:10.125 Bytes
    • G:11 Bytes
    • H:12 Bytes
    • I:12.125 Bytes
    • K:13 Bytes

    正确答案是F和G。

    如果您没猜对,那么花7~10分钟读完本文,即可破解这一谜题。成长快乐轻轻松松。

    本文内容适用于MySQL 5.5/5.6/5.7/8.x

    VARCHAR的定义

    VARCHAR是变长字符串。
    考虑其变长原理中有较多要素,在具体分解前,有必要一起重温下官方定义。

    为了便于理解,我用CHAR定长类型来对比介绍。先看两个小例子:

    • VARCHAR(4),最多存储4个字符,有几个字符存储几个。存储字节数 = 数据值的字节和 + 1字节(长度标识,后面会讲到)
    • CHAR(4),最多存储4个字符,不足4个尾部用空格填满。存储字节数 = 数据值的字节和 + 补位空格数

    概括地说,VARCHARCHAR都是MySQL的字符串类型,存储多个字符、可设置最大存储的字符数,存储开销都与数据长度、字符集有关。是MySQL最常用的字符串类型。

    CHARVARCHAR具体对比:

    特性CHARVARCHAR
    长度定长,固定字符数
    最大255个字符
    数据长度不足声明值时,在尾部自动填充空格
    长度可变,可设置最大存储字符数
    最大不超过行大小(默认65535字节,注意是字节,下面会讲原因)
    前缀1~2字节,看列长度是否可能超过255字节
    比如VARCHAR(100),字符集为UTF8,则字节最大可能为300字节,所以会使用2个字节标识长度
    有否尾部空格长度不足默认用空格填满
    检索和获取时会自动去除
    不会自动填充空格输入值就包含空格,则会存储,检索和获取数据都会体现
    超长处理超长部分如果是空格自动截断
    如果是字符,严格模式下会报错
    超长部分如果是空格自动截断,并生成警告
    如果是字符,严格模式下会报错
    存储开销数据值的字节和 + 补位空格数数据值的字节和 + 长度标识字节数
    • 如果开启PAD_CHAR_TO_FULL_LENGTH模式,检索时尾部空格不会去除
    • CHAR超过255字符会报错,提示使用TEXTBLOB
      ERROR 1074 (42000): Column length too big for column ''long_char'' 	(max = 255); use BLOB or TEXT instead
      

    这是两个类型的简单介绍。要了解MySQL类型详细内容,可参考《MySQL字段长度、取值范围、存储开销》

    VARCHAR的最大长度


    在MySQL官方定义中,常用的COMPACTDYNAMIC行模式下,最大长度受几个因素影响:

    • 行存储的最大字节数
    • 数据之外的存储开销,官方定义中包括:NULL标识长度标识
    • 存储字符的字符集

    算法如下:
    最大长度(字符数) = (行存储最大字节数 - NULL标识列占用字节数 - 长度标识字节数) / 字符集单字符最大字节数。有余数时向下取整。

    关于MySQL行大小定义,可参考《MySQL字段长度、取值范围、存储开销》

    下面通过逐步实例验证,演示如何计算出最大长度。

    最大行大小

    MySQL行默认最大65535字节,是所有列共享的,所以VARCHAR的最大值受此限制。
    接下来,我们要创建一个65536字节的VARCHAR,来验证这个边界值。

    前面讲过,VARCHAR声明的长度是指字符数。要换算为65536字节,最好一个字符只占一个字节。
    所以这里使用了latin1字符集(MySQL默认字符集,不指定即为默认)。
    要了解更多MySQL字符集,可参考《MySQL有哪些字符集?如何使用?》

    mysql> create table test_varchar_length(v varchar(65536) not null);
    ERROR 1074 (42000): Column length too big for column 'v' (max = 65535); use BLOB or TEXT instead
    

    可以看到报错了,提示我们行最大长度为65535字节。
    如果我们要插入一个非空的VARCHAR,其最大长度不能超过65535(行最大值) - 2(长度标识位) = 65533字节(长度标识位需2字节才能表示216=65536个数字):

    /** 测试边界值65534,确认仍然过大;注意这里使用默认字符集latin1、单字节字符集 */
    mysql> create table test_varchar_length(v varchar(65534) not null); 
    ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
    
    /** 测试边界值65533,创建成功,说明行最大值为65535 */
    mysql> create table test_varchar_length(v varchar(65533) not null); 
    Query OK, 0 rows affected (0.02 sec)
    
    /** 查看默认字符集,确认是latin1,每个字符只占用1个字节 */
    mysql> show create table test_varchar_length;
    +----------------------+------------------------------------------------------------------------------------------------------------+
    | Table                | Create Table                                                                                               |
    +----------------------+------------------------------------------------------------------------------------------------------------+
    | test_varchar_length | CREATE TABLE `test_varchar_length` (
      `v` varchar(65533) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
    +----------------------+------------------------------------------------------------------------------------------------------------+
    1 row in set (0.00 sec)
    

    可空列标识位

    COMPACTDYNAMIC行格式下,行大小除了数据列长度,还包括可空列标识,即NULL标识位。

    • 如果有一个列允许为空,则需要1 bit来标识,每8 bits的标识会组成一个字段,该字段会存放在每行最开始的位置

      注意,这个标识位不是放在每列,而是每行共享。

    • 假设一张表中存在N个可空字段,NULL标识位需要 ⌈ N / 8 ⌉ \lceil{N/8}\rceil N/8 (向上取整)个字节。此时整行可用于数据存储的空间只有 65535 − ⌈ N / 8 ⌉ 65535 - \lceil{N/8}\rceil 65535N/8个字节。

    Talk is cheep,一起来验证下:
    在行大小的例子中,我们知道最大可创建65533字节长度的非空VARCHAR列。现在要创建一个可空列,每行需要1 bitNULL标识位、MySQL会将其组装成1 byte的字段存放,那么我们应该可创建最大为65533(最大非空VARCHAR列) - 1(NULL标识列)= 65532字节的可空VARCHAR列:

    /** 删除前面创建的表 */
    mysql> drop table test_varchar_length;
    Query OK, 0 rows affected (0.01 sec)
    
    /** 测试边界值65533,确认仍然过大;注意这里使用默认字符集latin1、单字节字符集 */
    mysql> create table test_varchar_length(v varchar(65533));
    ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
    
    /** 测试边界值65532,创建成功,说明可空标识列确实占去了1字节;注意这里使用默认字符集latin1、单字节字符集 */
    mysql> create table test_varchar_length(v varchar(65532));
    Query OK, 0 rows affected (0.03 sec)
    

    计算VARCHAR的最大长度,可空标识位是最容易忽略的。

    字符集的单字符最大字节数

    字符集单字符最大字节数不难理解,列举MySQL常见的三个字符集:

    • GBK:单字符最大可占用2个字节。
    • UTF8:单字符最大可占用3个字节。
    • UTF8MB4:单字符最大占4个字节。
      假设还有6字节可以存放字符,按单字符占用最大字节数来算,可以存放3个GBK、2个UTF8、1个UTF8MB4

    VARCHAR的长度标识位

    长度标识位是相对比较复杂的,网上的介绍错的很多,也容易算错。

    其作用是记录数据的字节数

    存储开销是小于255只要1字节、大于255后使用两字节。是因为按照可能的数据大小,分为0 - 255(28)、256 - 65535(216),刚好对应1字节和2字节。

    但要注意,其计算根据的是字段声明的字符长度、计算可能的字节数,再决定长度标志的字节数。如VARCHAR(100),字符集为UTF8,可能的字节数为300,长度标识则为2字节。这是网上介绍错的最多的。

    另外长度标志位是底层存储开销,不占用字段声明的字符长度。声明的字符长度的是数据的字符数,数据的字节数与字符集有关。

    VARCHAR(1)为例,可以存1个字符,MySQL会额外找一个字节存放长度标识


    样例

    公式应该都理解了:VARCHAR的最大长度 = (最大行大小 - NULL标识列占用字节数 - 长度标识字节数) / 字符集单字符最大字节数。有余数时向下取整。

    接下来通过实验来验证。为了便于理解计算,例子做了一些调整:

    • 不设置可空列、这样可以去掉NULL标识列
    • 为了便于体现长度标识位的差距,采用多个列的形式放大其存在
    • 为了体现按可能字节数计算长度,这里采用多字节的字符集GBK

    创建一个表,包含2个非空VARCHAR(127),每个列存储开销为127*2(可能的最大字节数, GBK字符占2字节)+长度标识位1=255字节:

    • 剩余空间为65535 - 255*2 = 65025字节
    • 剩余空间可存放一个VARCHAR(32511) NOT NULL列(32511*2(GBK字符占2字节)+2(长度标识位占2字节)=65024
    mysql> drop table test_varchar_length;
    Query OK, 0 rows affected (0.01 sec)
    /** 测试边界值32512,确认仍然过大 */
    mysql> create table test_varchar_length(v1 varchar(127) not null,v2 varchar(127) not null,vm varchar(32512) not null) CHARSET=GBK;    
    ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
    
    /** 测试边界值32511,创建成功,说明两个长度标识位共占去了2字节 */
    mysql> create table test_varchar_length(v1 varchar(127) not null,v2 varchar(127) not null,vm varchar(32511) not null) CHARSET=GBK; 
    Query OK, 0 rows affected (0.02 sec)
    

    接下来将两个字段调大到128字符,每个列的存储为最大字节数256+长度标识位2=258字节

    • 剩余空间65535 - 258*2 = 65019字节
    • 剩余空间可存放一个VARCHAR(32508) NOT NULL列(32508*2(GBK字符占2字节)+2(长度标识位占2字节)=65018):
    mysql> drop table test_varchar_length;
    Query OK, 0 rows affected (0.01 sec)
    /** 测试边界值32509,确认仍然过大 */
    mysql> create table test_varchar_length(v1 varchar(128) not null,v2 varchar(128) not null,vm varchar(32509) not null) CHARSET=GBK; 
    ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs
    
    /** 测试边界值32508,创建成功,说明两个长度标识位共占去了4字节 */
    mysql> create table test_varchar_length(v1 varchar(128) not null,v2 varchar(128) not null,vm varchar(32508) not null) CHARSET=GBK; 
    Query OK, 0 rows affected (0.02 sec)
    



    恭喜你,能看到这里的人估计不多,坚持下来的你已经得到了提升。
    在这里插入图片描述

    那么再一起解下最初的问题:

    • UTF8MB4字符中,中文字符需要3个字节(大部分中文只需要3字节,4字节主要是emoji等辅助平面字符),那么“中国cn”需要3+3+1+18个字节
    • VARCHAR(64) CHARSET utf8mb4字段,数据最大可能的字节数是64*4=256,所以需要 2个字节 作为长度标识位;
    • 该字段是可以为空的,那么还需要NULL标识位,MySQL会生成一个 1字节NULL标识列来记录;
    • 所以要存储“中国cn”,列需要8 + 2个字节,还需要1字节作为NULL标识列;因为该列是多个列共享的,如果该表只有一个字段,那么可以存储开销应该是11个字节,否则只能算作10.125字节(1/8等于0.125

    所以答案是10.12511字节。

    😂哈哈哈我花了4个小时,占用了你10分钟,但你不用像我这么掉头发啦!摸着秀发给我点个赞吧~~

    同类文章推荐:


    以上,感谢您的阅读。

    后续更新收集中:

    • 行格式解析
    • 其他引擎表现
    展开全文
  • mysql中varchar最大长度有多大_数据库

    千次阅读 2021-04-20 10:30:24
    mysql中varchar最大长度有多大?mysql中varchar最多能存储65535个字节的数据。varchar 的最大长度受限于最大行长度(max row size,65535bytes)。65535并非一个很准确的上限,能够继承减少这个上限。65535个字节包含...

    d162236afdcfe882b3d9429aeb1bf053.png

    mysql中varchar最大长度有多大?

    mysql中varchar最多能存储65535个字节的数据。

    varchar 的最大长度受限于最大行长度(max row size,65535bytes)。65535并非一个很准确的上限,能够继承减少这个上限。65535个字节包含一切字段的长度,变长字段的长度标识(每一个变长字段分外运用1或许2个字节纪录现实数据长度)、NULL标识位的累计。

    f8c2afa88199c819e3fc74cc7c9c30c9.png

    扩大材料

    1、varchar存储划定规矩:mysql4.0版本以下,varchar(20),指的是20字节,假如寄存UTF8汉字时,只能存6个(每一个汉字3字节) mysql5.0版本以上,varchar(20),指的是20字符,不管寄存的是数字、字母照样UTF8汉字(每一个汉字3字节),都能够寄存20个,最大大小是65532字节 。

    2、varchar受编码长度限定划定规矩:字符范例若为gbk,每一个字符最多占2个字节,最大长度不能超过32766;

    字符范例若为utf8,每一个字符最多占3个字节,最大长度不能超过21845。

    引荐教程: 《mysql教程》

    以上就是mysql中varchar最大长度有多大的细致内容,更多请关注ki4网别的相干文章!

    收藏 | 0

    展开全文
  • SqlServer的varchar最大长度是8000; 总会遇到这种字符串截断问题,但是在给表字段长度添加时最好还是不要添加为max,能用varchar(n)的话就不必要去要求varchar(max)(性能问题), 项目上确实出现过问题,这个博主...
  • MySQL中char与varchar区别,varchar最大长度是多少? 一、首先来说下字符与字节的区别: 字符与字节它们完全不是一个位面的概念,所以两者之间没有“区别”这一说法。在不同编码里,字符和字节的对应关系是不同的...
  • mysql varchar最大长度

    2020-06-25 19:00:02
    varchar最大长度受限于最大行zhi长度(max row size,65535bytes)。65535并不是一个很精确的上限,可dao以继续缩小这个上限。65535个字节包括所有字段的长度,变长字段的长度标识(每个变长字段额外使用1或者2个...
  • sqlserver中 varchar 最大长度是多少?

    千次阅读 2020-12-30 02:22:11
    展开全部最大长度e69da5e887aa32313133353236313431303231363533313334313732388000,用max可以存储达到2G。例如:varchar [ ( n | max) ]可变长度,非 Unicode 字符数据。n 的取值范围为 1 至 8,000。max 指示最大...
  • Mysql5.6字符集utf8mb4中varcha的长度最大为15936使用二分法试出来的(见下图) 经过反复测试,最大值那个错误,官网说法最大值是65535bytes,utf8mb4每个字符占4个bytes,最大值应该为16383.75(如图)但是,...
  • MySQL中varchar最大长度是多少

    万次阅读 2019-05-29 09:43:05
    MySQL 数据库的varchar类型在4.1以下的版本中的最大长度限制为255,其数据范围可以是0~255或1~255(根据不同版本数据库来定)。在 MySQL5.0以上的版本中,varchar数据类型的长度支持到了65535,也就是说可以存放...
  • MySQL varchar最大长度,text类型占用空间剖析作者:nango 阅读:2270次 来源:http://blog.csdn.net/free_ant/article/details/52936756 时间:2016-10-26 22:32上一篇博文已经介绍了MySQL的字段类型以及占用的空间大小...
  • int(11)最大长度是多少,MySQL中varchar最大长度是多少?int(11)最大长度是多少?在SQL语句中int代表你要创建字段的类型,int代表整型,11代表字段的长度。这个11代表显示宽度,整数列的显示宽度与mysql需要用多少个...
  • varchar和char 的区别:ps :被问到一个问题:MySQL中varchar最大长度是多少?1、限制规则2、计算例子3、varchar物理存储4、InnoDB中的varchar5、MyISAM中的varchar一. varchar存储规则:4.0版本以下,varchar(20),...
  • 那么来验证下 varchar 类型的实际最大长度:测试环境:MySQL版本 5.7.19//首先要设置下 mysql 为严格执行模式,不然 varchar 超出最大长度为自动转为 text 类型set sql_mode="STRICT_TRANS_TABL...
  • mysql varchar最大长度多少

    千次阅读 2018-06-08 13:14:44
    最近去面试问了一个问题,mysql...一般是utf-8,那么varchar最大长度不能超过21845。刚刚查下博客最长长度也是2w字,赶脚是这个原因。所以现在回答面试问题,业务中有什么东西会超过2w字的吗,除了博客这些长篇章的...
  • varchar和char 的区别,varchar最大长度

    千次阅读 2019-07-04 15:39:43
    5.0版本以上,varchar(20),指的是20字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放20个,最大大小是65532字节 二. varchar和char 的区别: char是一种固定长度的类型,varcha...
  • MySQL中varchar字段最大长度是多少

    千次阅读 2020-12-31 10:55:40
    微信搜索『coder-home』,或者扫一扫右侧的二维码,关注『程序猿集锦』。了解更多干货分享,还有各类视频教程。...它的最大长度是多少?为什么有时候定义一个varchar(10)的字段可以存储10个汉字,但是不能存...
  • (VARCHAR最大实际长度由最长的行的大小和使用的字符集确定,最大有效长度是65,532字节)。 为何会这般变换?真是感觉MySQL的手册做的太不友好了,因为你要仔细的继续往下读才会发现这段描述:MyS

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 99,217
精华内容 39,686
关键字:

varchar最大长度

友情链接: EVEN.rar