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


对这varchar和char这两个数据类型最简单区分是: varchar存放变长字符串,char存放定长字符串。

那么他们是否 还有其他差别呢?本文将从浅显的层次以抛出问题解决问题的形式对两者的区分进一步了解。

首先我们确认一下mysql版本。本文中的所有知识点都基于mysql5.0+,本文中的例子基于mysql5.6。

那么,接下来开始抛出我的问题。


问题一:varchar(m),char(n)里面的m或n代表的是字节还是字符的个数?

为了得到答案,我们打开mysql手册,看到这样一句话 

The CHAR and VARCHAR types are declared with a length

that indicates the maximum number of   characters   you want to store. 

For example, CHAR(30) can hold up to 30  characters.

注意描红的单词, 手册中明确指出,存放的是【字符】的个数。

问题二:varchar(m),char(n)里面的m和n是否有长度限制?分别是多少?
首先我们明确一下,m和n是一定会有长度限制的。那么究竟是多少呢?这个问题需要我们详细看一下各个知识点。

第一:讨论char(n)

The length of a CHAR column is fixed to the length that you declare when you create  the table.

The length can be a ny value from 0 to 255. When CHAR values are stored, 

t hey are right-padded with spaces to the specified length. When CHAR values are  retrieved, 

trailing spaces are removed unless the PAD_CHAR_TO_FULL_LENGTH  [581] SQL mode is enabled.

手册中指出,长度的限制是0-255,经过验证,长度的限制是 0-255个【字符】。也就是说,没有明确标出字

节的限 制数。


第二:讨论varchar(m)

Values in VARCHAR columns are variable-length strings.
The length can be  specified as a value from 0 to 65,535.
The effective maximum length of a VARCHAR is subject to the maximum row size ( 65,535 bytes, which is shared  a mong all  columns )
and the character set used. See Section E.10.4, “Table Column-Count  and Row-Size Limits”.

In contrast to CHAR,VARCHAR values are stored as a 1-byte or 2-byte length prefix plus data.
The length prefix  in dicates 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.

注意上面两段话中的描红部分。
首先我们明确,m也是字符的个数。而上面句子中提到的   65535是指 varchar列最大可存放的【字节】数。

我们知道, 在gbk编码格式下,【*中文情况下】 字节数=字符数*2 ;在utf8编码格式下,字节数=字符数*3 【*中文
情况下】

但是,在varchar中,因为是变长, 所以需要1-2个字节来标识这一列的长度 。如果varchar字段定义中带有default nu
ll允许列空, 则需要需要1bit来标识,每8个bits的标识组成一个字段。一张表中存在N个varchar字段,那么需要(N+
7)/8 (取整)bytes存储所有的NULL标识位
我们假设一张表只有varchar一列,且此时该字段设置为DEFAULT NULL,那么该varchar字段的最大长度为65535-
2-(1+7)/8 = 65532bytes.
这时候新的疑问出现了。为什么要假设表只有一列数据,这是很不符合常规的。原因在上面描紫的语句。
什么意思?
我们要知道,每一行数据的总长度是有限制的,每一行最大字节数就是65535个。我们创建一张表时,需要把每个
字段需要占用的字节进行统计,总数不能超过65535即可。其中text和blob根据存放的数据量不同可能占用1,2,3,4
个字节。在计算的时候要按4字节进行计算。


问题三:使用myisam和Innodb引擎对varchar和char的选择应该怎么考虑?
myisam 存储引擎 建议使用固定长度,数据列代替可变长度的数据列。 
memory存储引擎 目前都使用固定数据行存储,因此无论使用char varchar列都没关系。
 
innodb 存储引擎 建意使用varchar 类型。 


本文补充:
在mysql中,函数LENGTH(s)函数返回字符串的字节长度。使用utf-8(UNICODE的一种变长字符编码,又称为万国
码)编码字符集时,一个汉字是2个字节、一个数字或者字母为一个字节。

char_length:返回字符串所占的字符数,不管汉字还是数字或者是字母都算是一个字符。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值