`

[转载]mysql关于varchar的说明

 
阅读更多

文章来源于 MySQL中的varchar最大长度是多少

一. 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

所以设计表的时候,这个要注意了,每一行是有长度限制的。
分享到:
评论

相关推荐

    Mysql中varchar长度设置方法

    关于`NVARCHAR`,它在MySQL 4.1以下的版本中,无论存储的是英文还是中文,每个字符都会占用2个字节,这是为了存储Unicode数据,避免乱码问题。而在4.1及以上版本,`VARCHAR`已经足够处理UTF-8编码的中文字符,因此`...

    对比MySQL中int、char以及varchar的性能

    总的来说,MySQL中的int、char和varchar在性能上的差异并非显著到足以成为决定性因素。开发者应根据实际需求,如数据的类型、大小、预期的增长、是否需要索引以及对可读性和可维护性的要求,来综合考虑选择哪种数据...

    MySQL动态修改varchar长度的方法

    关于`VARCHAR`长度的几个关键点: 1. `VARCHAR`的最大长度限制是65,535字节,这是根据MySQL的内部存储机制设定的。但这并不意味着你可以直接定义`VARCHAR(65535)`,因为还需要考虑字符集的影响。 2. 对于使用`UTF-...

    char和varchar在mysql中的效率怎样.docx

    在MySQL数据库中,`CHAR`和`VARCHAR`是两种常见的字符串数据类型,它们在存储和处理数据时具有不同的效率特点。理解这两种类型的差异对于优化数据库性能至关重要。 `CHAR`是一种固定长度的数据类型,这意味着无论...

    mysql的varchar到底能存多少个字符 - 副本.md

    mysql的varchar到底能存多少个字符 - 副本

    MySQL中VARCHAR与CHAR格式数据的区别

    在MySQL数据库中,CHAR和VARCHAR是两种常见的字符串数据类型,它们在存储和处理方式上有着显著的区别,这对于数据库设计和性能优化至关重要。 首先,CHAR是一种固定长度的数据类型。这意味着无论你存储的实际数据有...

    MySQL数据库varchar的限制规则说明

    在MySQL数据库中,`VARCHAR`是一种非常常用的可变长度字符串数据类型,用于存储较短的文本数据。它的优点在于空间利用率高,因为它只存储实际的数据长度,而不是固定长度的存储空间。然而,`VARCHAR`类型并非没有...

    MySQL中把varchar类型转为date类型方法详解

    在MySQL和Oracle这两个广泛使用的数据库管理系统中,我们经常遇到需要将字符串(varchar)类型的日期转换为日期(date)类型的情况。这通常是因为原始数据以字符串格式存储,而我们需要对这些日期进行比较、排序或...

    Mysql varchar大小长度问题介绍

    MySQL中的VARCHAR类型是一种可变长度的字符串数据类型,它在存储空间上相比固定长度的CHAR类型更为节省。本文将深入探讨VARCHAR类型的大小长度问题及其在不同版本和编码下的限制。 首先,VARCHAR字段的长度限制主要...

    mysql varchar类型求和实例操作

    有的小伙伴在学习数据库的时候,创建表结构的时候不小心把某字段设置成了varchar但是在统计求和的时候就傻眼了,接下来跟着小编学习一下,不用改该列数据类型也能求和的方法吧! 1、打开 数据库连接客户端Navicat ...

    varchar 和varchar2之间的联系和区别

    ### VARCHAR与VARCHAR2之间的联系和区别 在数据库设计与应用中,正确理解并选择合适的数据类型对于确保数据的准确存储及高效查询至关重要。在Oracle数据库中,`VARCHAR`与`VARCHAR2`是两种常见的用于存储可变长度...

    varchar日期字段分区demo

    Range分区:最为常用,基于属于一个给定连续区间的列值,把多行分配给分区。最常见的是基于时间字段. 基于分区的列最好是整型,如果日期型的可以使用函数转换为整型。varchar日期字段分区sql demo

    MySQL说明书中文

    MySQL数据库管理系统支持多种数据类型,包括数值类型(如整数、浮点数和双精度数)、字符串类型(如VARCHAR、TEXT和BLOB)、日期和时间类型(如DATE、TIME和TIMESTAMP),以及二进制类型(如BINARY和VARBINARY)。...

    MySQL数据类型varchar详解

    MySQL中的`VARCHAR`数据类型是用于存储可变长度的字符串数据的,它的主要优势在于空间效率,因为它只存储实际输入的字符数量,不像`CHAR`数据类型会预留固定长度的空间。下面将详细介绍`VARCHAR`的逻辑意义、最大...

    python遇到sql2005 varchar(4000) varchar(MAX)

    标题中的“python遇到...以上就是关于标题和描述中提到的知识点的详细说明。在实际开发过程中,充分理解和掌握这些知识点,可以有效解决Python与SQL Server 2005在处理varchar(4000)和varchar(MAX)时可能遇到的问题。

Global site tag (gtag.js) - Google Analytics