前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL:The CHAR and VARCHAR Types

MySQL:The CHAR and VARCHAR Types

作者头像
用户7685359
发布2020-08-28 16:16:43
1.2K0
发布2020-08-28 16:16:43
举报
文章被收录于专栏:FluentStudy

CHAR 和 VARCHAR 类型相似,但在存储的检索时有区别,同时在最大长度定义与尾部空格上是否保留也有区别。

CHAR 和 VARCHAR 声明时格式为 CHAR(num) 和 VARCHAR(num),这里的 num 表示的是你想存储的最大字符数。注意是字符数,而不是字节数。

一、长度定义区别

CHAR(num),存储时长度是固定的,num值的范围在[0, 255](0和255均可取值)。当存储的字符不足时,会右边补足空格。

VARCHAR(num),长度定义为变长,num值的范围是[0, 65535]。需要注意的是这里的 65535 是所有列的总和不能超过的值,也就是说当只有一个 VARCHAR 列时可选的最大值。

即 VARCHAR 仅使用必要空间,一般情况下,它比 CHAR 要更节省空间。

二、存储区别

VARCHAR 会额外使用1到2个字节来记录字符串的长度。当长度小于等于255字节时,使用1个字节,大于255字节时使用2个字节。

此外,VARCHAR 在更新时需要做额外的操作,因为如果更新的操作是将行变得更长,并且在页内没有更多的空间可以存储,在这种情况下,不同的存储引擎的处理方式不一样。例如 MyISAM 会将行拆成不同的片段存储,InnoDB则需要分裂页来使行可以放进页内。总而言之都会带开额外的操作。而 CHAR 因为每次分配的空间都是固定的,因为不会有这个问题存在。

所以,当长度比较小或者长度固定时,更适合用 CHAR 类型来存储,因为不会经常变动,且节省了空间。

三、尾部空格截断区别

CHAR 类型不足长度时会在右侧补足空格,但在检索时会自动移除掉右边的空格(这里的移除不仅是自动补足的,实际插入的也会移除)。但当 sql_mode 设置为 PAD_CHAR_TO_FULL_LENGTH 时,则不会被移除。示例如下(mysql版本5.7,后同):

代码语言:javascript
复制
CREATE TABLE t1 (c1 CHAR(10));

INSERT INTO t1 (c1) VALUES('xy');

set sql_mode = '';

show variables like 'sql_mode';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_mode      |       |
+---------------+-------+

SELECT concat('(', c1, ')'), CHAR_LENGTH(c1) FROM t1;
+----------------------+-----------------+
| concat('(', c1, ')') | CHAR_LENGTH(c1) |
+----------------------+-----------------+
| (xy)                 |               2 |
+----------------------+-----------------+

SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';

mysql> SELECT concat('(', c1, ')'), CHAR_LENGTH(c1) FROM t1;
+----------------------+-----------------+
| concat('(', c1, ')') | CHAR_LENGTH(c1) |
+----------------------+-----------------+
| (xy        )         |              10 |
+----------------------+-----------------+

VARCHAR 不会填充空格,而对于实际插入的尾部空格,在4.1版本之前,VHARCHAR的处理方式和 CHAR 是一致的,但是之后的版本中,VARCHAR则会保留空格。示例如下:

代码语言:javascript
复制
CREATE TABLE vc (v VARCHAR(4), c CHAR(4));

INSERT INTO vc VALUES ('ab  ', 'ab  ');

SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc;
+---------------------+---------------------+
| CONCAT('(', v, ')') | CONCAT('(', c, ')') |
+---------------------+---------------------+
| (ab  )              | (ab)                |
+---------------------+---------------------+

四、总结

  • 对于数据如何存储,取决于存储引擎,并非所有的存储引擎都会按照相同的方式处理定长和变长的字符串,比如 Memory 引擎只支持定长的行,即使有变长的行也会根据最大长度分配空间
  • 但对于填充和截断空格行为在不同存储引擎上都是一样的,因为这是在 MySQL 服务器层进行处理的
  • 在实际进行表创建时,要根据实际情况进行选择。一般对于长度固定,或者长度特别小时,适合用 CHAR ,比如存储密码的 md5 值的情况就很适合用 CHAR

五、扩展

使用 VARCHAR(5) 和 VARCHAR(10) 存储 hello 的空间开销是一样的,那实际使用更短的列有什么优势吗?

更长的列会消耗更多的内存。因为 MySQL 通常会分配固定大小的内存块来保存内部值,尤其是使用内存临时表进行排序或操作时。在利用磁盘临时表进行排序也同样糟糕。所以,最好的策略是只分配真正需要的空间。from 《高性能MySQL》

六、参考资料

  1. 官方文档
  2. 《高性能MySQL》第四章
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FluentStudy 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、长度定义区别
  • 二、存储区别
  • 三、尾部空格截断区别
  • 四、总结
  • 五、扩展
  • 六、参考资料
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档