MySQL数据类型 CHAR和VARCHAR

CHAR和VARCHAR是最常使用的两种字符串类型。一般来说,CHAR(N)用来保存固定长度的字符串,VARCHAR(N)用来保存变长字符类型。
对于CHAR类型,N的范围为0~255,对于VARCHAR类型,N的范围为0~65 535。CHAR(N)和VARCHAR(N)中的N都代表 字符长度,而非字节长度。
注意 对于MySQL 4.1之前的版本,如MySQL 3.23和MySQL 4.0,CHAR(N)和VARCHAR(N)中的N代表字节长度。
对于CHAR类型的字符串,MySQL数据库会自动对存储列的右边进行填充(Right Padded)操作(默认填充 空格),直到字符串达到指定的长度N。
而在读取该列时,MySQL数据库会自动将填充的字符删除。
有一种情况例外,那就是显式地将SQL_MODE设置为PAD_CHAR_TO_FULL_LENGTH(这种情况下,填充的字符也被读取!),例如:

mysql> CREATE TABLE t ( a CHAR(10));                                  
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO t SELECT 'abc';
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> SELECT a,HEX(a),LENGTH(a) FROM t\G;
*************************** 1. row ***************************
        a: abc
   HEX(a): 616263
LENGTH (a): 3
1 row in set (0.00 sec)

mysql> SET SQL_MODE='PAD_CHAR_TO_FULL_LENGTH';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT a,HEX(a),LENGTH(a) FROM t\G;   
*************************** 1. row ***************************
        a: abc      
   HEX(a): 61626320202020202020
LENGTH (a): 10
1 row in set (0.00 sec)

在上述这个例子中,先创建了一张表t,a列的类型为CHAR(10)。然后通过INSERT语句插入值“abc”,因为a列的类型为CHAR型,
所以会自动在后面填充空格,使其长度为10。接下来在通过SELECT语句取出数据时会将a列右填充的空格移除,从而得到值“abc”。
通过LENGTH函数看到a列的字节长度为3而非10。
接着我们将SQL_MODE显式地设置为PAD_CHAR_TO_FULL_LENGTH。这时再通过SELECT语句进行查询时,得到的结果是“abc       ”,
abc右边有7个填充字符0x20(空格),并通过HEX函数得到了验证。这次LENGTH函数返回的长度为10。
需要注意的是,LENGTH函数返回的是 字节长度,而不是字符长度。
对于多字节字符集,CHAR(N)长度的列最多可占用的字节数为该字符集 单字符最大占用字节数*N
例如,对于utf8下,CHAR(10)最多可能占用30个字节。
通过对多字节字符串使用CHAR_LENGTH函数和LENGTH函数,可以发现两者的不同,示例如下:
mysql> SET NAMES gbk;
Query OK, 0 rows affected (0.03 sec)

mysql> SELECT @a:='MySQL技术内幕';
Query OK, 0 rows affected (0.03 sec)

mysql> SELECT @a,HEX(@a),LENGTH(@a),CHAR_LENGTH(@a)\G;
***************************** 1. row ****************************
a: MySQL技术内幕
HEX(a): 4D7953514CBCBCCAF5C4DAC4BB
LENGTH (a): 13
CHAR_LENGTH(a): 9
1 row in set (0.00 sec)
变量@a是gbk字符集的字符串类型,值为“MySQL技术内幕”,十六进制为0x4D7953514CBCBCCAF5C4DAC4BB,
LENGTH函数返回13,即该字符串占用13字节,因为gbk字符集中的中文字符占用两个字节,因此一共占用13字节。
CHAR_LENGTH函数返回9,很显然该字符长度为9。

VARCHAR类型存储变长字段的字符类型,与CHAR类型不同的是,其存储时需要在前缀长度列表加上实际存储的字符,该字符占用1~2字节的空间。当存储的字符串长度小于等于255字节时,其需要1字节的空间,当大于255字节时,需要2字节的空间。
所以,对于单字节的latin1来说,CHAR(10)和VARCHAR(10)最大占用的存储空间是不同的,CHAR(10)占用10个字节这是毫无疑问的,而VARCHAR(10)的最大占用空间数是11字节,因为其需要1字节来存放字符个数。

注意:对于有些多字节的字符集类型,其CHAR和VARCHAR在存储方法上是一样的,同样需要为长度列表加上字符串的值。
对于GBK和UTF-8这些字符类型,其有些字符是以1字节存放的,有些字符是按2或3字节存放的,因此同样需要1~2字节的空间来存储字符的长度。

虽然CHAR和VARCHAR的存储方式不太相同,但是对于两个字符串的比较,都只比较其值,忽略CHAR值存在的右填充,
即使将SQL _MODE设置为PAD_CHAR_TO_FULL_LENGTH 也仍然会忽略CHAR值存在的右填充,例如:
mysql> CREATE TABLE t ( a CHAR(10), b VARCHAR(10));
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO t SELECT 'a','a';
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> SELECT a=b FROM t\G;
*************************** 1. row ***************************
a=b: 1
1 row in set (0.00 sec)

mysql> SET SQL_MODE='PAD_CHAR_TO_FULL_LENGTH';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT a=b FROM t\G;
*************************** 1. row ***************************
a=b: 1

1 row in set (0.00 sec)


原文链接:点击打开链接



  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值