MySQL CHAR和VARCHAR该如何选择


Posted in MySQL onMay 31, 2021

VARCHAR 和 CHAR 类型

VARCHAR 和 CHAR 是两种主要的字符串类型,用于存储字符。不幸的是,由于实现的方式依赖于存储引擎,因此很难解释这些字符串在磁盘和内存中如何存储,除了除了常用的 InnoDB 和 MyISAM 外,假设你使用了其他存储引擎,应当仔细阅读存储引擎的文档。​

VARCHAR 存储可变长度的字符串,也是最常用的字符数据类型。相比固定长度的类型,VARCHAR 所需的存储空间更小,它会尽可能少地使用存储空间(例如,短的字符串占据的空间)。对于 MyISAM 来说,如果创建表的时候指定了 ROW_FORMAT=FIXED 的话,那么会使用固定的空间存储字段而导致空间浪费。VARCHAR 使用1-2个额外的字节存储字符串的长度:当最大长度低于255字节的时候使用1个字节,如果更多的话就使用2个字节。因此,拉丁字符集的 VARCHAR(10)会使用11个字节的存储空间,而 VARCHAR(1000)则会使用1002个字节的存储空间。​

VARCHAR 由于能够节省空间,因此可以改善性能。但是,由于长度可变,当更新数据表的时候数据行的存储空间会变化,这一定程度上会带来额外的开销。如果数据行的长度导致原有的存储位置无法存放,那么不同的存储引擎会做不同的处理。例如 MyISAM 可能产生数据行的碎片,而 InnoDB 需要进行磁盘分页来存放更新后的数据行。​

通常,如果最大的列长度远远高于平均长度的话(例如可选的备注字段),使用 VARCHAR 是划算的,同时如果更新的频次很低,那么碎片化也不会是一个问题。需要注意的是,如果使用的是 UTF-8字符集,则实际存储的字节长度是根据字符定的。对于中文,推荐的存储字符集是 utf8mb4。​

CHAR 类型的长度是固定的,MySQL 会对每个字段分配足够的存储空间。存储CHAR 类型值的时候,MySQL 会移除后面多出来的空字符。值是使用空字符进行对齐以便进行比较。对于短的字符串来说,使用 CHAR 更有优势,而如果所有的值的长度几乎一致的话,就可以使用 CHAR。例如存储用户密码的MD5值时使用 CHAR 就更合适,这是因为 MD5的长度总是固定的。同时,对于字段值经常改变的数据类型来说,CHAR 相比 VARCHAR 也更有优势,因为 CHAR 不会产生碎片。对于很短的数据列,使用 CHAR 比 VARCHAR更高效,例如使用CHAR(1)存储逻辑值的 Y 和 N,这种情况下只需要1个字节,而 VARCHAR 需要2个字节。 对于移除空字符这个特性会感觉奇怪,我们举个例子:

CREATE TABLE t_char_varchar_test (
  id INT PRIMARY KEY,
  char_col CHAR(10),
  varchar_col VARCHAR(10)
);

INSERT INTO t_char_varchar_test 
VALUES 
(1, 'string1', 'string1'),
(2, '  string2', '  string2'),
(3, 'string3  ', 'string3  ');

按上面的结果插入数据表后,string2中的前置空格不会移除,但使用 CHAR 类型存储时,string3尾随空格会被移除,使用 SQL 查询结果来检验一下:

SELECT CONCAT("'", char_col, "'"), CONCAT("'", varchar_col, "'") 
FROM t_char_varchar_test WHERE 1

得出来的结果如下,可以看到 CHAR 类型的 string3后面的空格被移除了,而 VARCHAR类型的没有。这种情况大多数时候不会有什么问题,实际在应用中也经常会使用 trim 函数移除两端的空字符,但是如果确实需要存储空格的时候,那就需要注意不要选择使用 CHAR 类型:

MySQL CHAR和VARCHAR该如何选择

数据如何存储是由存储引擎决定的,而且存储引擎处理固定长度和可变长度的数据的方式并不相同。Memory 引擎使用固定大小的行,因此它需要分配最大可能的存储空间——即便数据长度是可变的。但是,对于字符串的对齐和空字符截断是由 MySQL 服务端完成的,因此所有存储引擎都是一样的。​

与 CHAR 和 VARCHAR 相似的是 BINARY和 VARBINARY,用于存储二进制字节字符,BINARY 的对齐使用字符0的字节值来对齐,并且再获取值的时候不会截断。如果需要使用字符的字节值而不是字符的话,使用 BINARY 会更高效,这是因为比较时,一方面不需要考虑大小写,另一方面是MySQL一次只比较一个字节。​

结语:

在实际数据表设计中,大多数情况下会选择使用 VARCHAR,但 VARCHAR 需要额外的1-2个字节存储字符串长度。需要注意的是在应用中最好能够限定字段的最大长度,从而可以使得数据表尽可能使用短的 VARCHAR来提高效率。同时,对于固定长度、长度很短或长度变化很小的字符类型,推荐使用 CHAR 类存储,以提高存储效率。

以上就是MySQL CHAR和VARCHAR的选择的详细内容,更多关于MySQL CHAR和VARCHAR的资料请关注三水点靠木其它相关文章!

MySQL 相关文章推荐
MySQL 使用SQL语句修改表名的实现
Apr 07 MySQL
MySQL 使用索引扫描进行排序
Jun 20 MySQL
MySQL 十大常用字符串函数详解
Jun 30 MySQL
MySQL 聚合函数排序
Jul 16 MySQL
Mysql数据库中datetime、bigint、timestamp来表示时间选择,谁来存储时间效率最高
Aug 23 MySQL
MySQL基础快速入门知识总结(附思维导图)
Sep 25 MySQL
浅谈MySQL表空间回收的正确姿势
Oct 05 MySQL
一篇文章看懂MySQL主从复制与读写分离
Nov 07 MySQL
Mysql忘记密码解决方法
Feb 12 MySQL
SQL注入篇学习之盲注/宽字节注入
Mar 03 MySQL
MySQL数据库优化之通过索引解决SQL性能问题
Apr 10 MySQL
使用Mysql计算地址的经纬度距离和实时位置信息
Apr 29 MySQL
带你学习MySQL执行计划
May 31 #MySQL
MySQL完整性约束的定义与实例教程
MySQL注入基础练习
解决Navicat for MySQL 连接 MySQL 报2005错误的问题
MYSQL(电话号码,身份证)数据脱敏的实现
May 28 #MySQL
MySql开发之自动同步表结构
mysql升级到5.7时,wordpress导数据报错1067的问题
May 27 #MySQL
You might like
简单实用的PHP防注入类实例
2014/12/05 PHP
PHP+jQuery翻板抽奖功能实现
2015/10/19 PHP
php实现购物车功能(以大苹果购物网为例)
2017/03/09 PHP
PHP实现与java 通信的插件使用教程
2019/08/11 PHP
php封装实现钉钉机器人报警接口的示例代码
2020/08/08 PHP
jQuery(1.6.3) 中css方法对浮动的实现缺陷分析
2011/09/09 Javascript
jQuery中使用each处理json数据
2015/04/23 Javascript
基于JavaScript实现单选框下拉菜单添加文件效果
2016/06/26 Javascript
jquery获取easyui日期控件的值实现方法
2016/11/09 Javascript
vue 2.0路由之路由嵌套示例详解
2017/05/08 Javascript
VUE在for循环里面根据内容值动态的加入class值的方法
2018/08/12 Javascript
小程序实现人脸识别功能(百度ai)
2018/12/23 Javascript
javascript使用canvas实现饼状图效果
2020/09/08 Javascript
[02:02]2018DOTA2亚洲邀请赛Mineski赛前采访
2018/04/04 DOTA
[01:11:21]DOTA2-DPC中国联赛 正赛 Phoenix vs CDEC BO3 第三场 3月7日
2021/03/11 DOTA
python插入排序算法实例分析
2015/07/03 Python
python+opencv+caffe+摄像头做目标检测的实例代码
2018/08/03 Python
python进阶之多线程对同一个全局变量的处理方法
2018/11/09 Python
django 连接数据库 sqlite的例子
2019/08/14 Python
使用Python爬虫库BeautifulSoup遍历文档树并对标签进行操作详解
2020/01/25 Python
python em算法的实现
2020/10/03 Python
Linux系统下升级pip的完整步骤
2021/01/31 Python
CSS3绘制超炫的上下起伏波动进度加载动画
2016/04/21 HTML / CSS
英国高端食品和葡萄酒超市:Waitrose
2016/08/23 全球购物
Bergfreunde丹麦:登山装备网上零售商
2017/02/26 全球购物
应届大学生简历中的自我评价
2014/01/15 职场文书
《长城》教学反思
2014/02/14 职场文书
以幸福为主题的活动方案
2014/08/22 职场文书
2014机关党员干部“正风肃纪”思想汇报
2014/09/15 职场文书
乡镇党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
乡镇干部个人对照检查材料思想汇报
2014/10/04 职场文书
起诉意见书范文
2015/05/19 职场文书
高中班主任培训心得体会
2016/01/07 职场文书
pytorch finetuning 自己的图片进行训练操作
2021/06/05 Python
Python中生成随机数据安全性、多功能性、用途和速度方面进行比较
2022/04/14 Python
MySQL串行化隔离级别(间隙锁实现)
2022/06/16 MySQL