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表的增删改查基础教程
Apr 07 MySQL
MySql学习笔记之事务隔离级别详解
May 12 MySQL
MySQL数据库压缩版本安装与配置详细教程
May 21 MySQL
MYSQL数据库使用UTF-8中文编码乱码的解决办法
May 26 MySQL
MySQL下使用Inplace和Online方式创建索引的教程
May 26 MySQL
MySQL如何使用使用Xtrabackup进行备份和恢复
Jun 21 MySQL
MySQL系列之开篇 MySQL关系型数据库基础概念
Jul 02 MySQL
MySQL约束超详解
Sep 04 MySQL
深入解析MySQL索引数据结构
Oct 16 MySQL
Mysql超详细讲解死锁问题的理解
Apr 01 MySQL
mysql使用FIND_IN_SET和group_concat两个方法查询上下级机构
Apr 20 MySQL
mysql序号rownum行号实现方式
Dec 24 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/02/20 PHP
php生成随机字符串可指定纯数字、纯字母或者混合的
2014/04/18 PHP
php的ZipArchive类用法实例
2014/10/20 PHP
php结合正则批量抓取网页中邮箱地址
2015/05/19 PHP
php生成短网址/短链接原理和用法实例分析
2020/05/29 PHP
JS 控制非法字符的输入代码
2009/12/04 Javascript
jQuery学习笔记之jQuery的事件
2010/12/22 Javascript
一次失败的jQuery优化尝试小结
2011/02/06 Javascript
字段太多jquey快速清空表单内容方法
2014/08/21 Javascript
JS动态改变表格边框宽度的方法
2015/03/31 Javascript
JavaScript数据库TaffyDB用法实例分析
2015/07/27 Javascript
在jQuery中处理XML数据的大致方法
2015/08/14 Javascript
JS简单获取客户端IP地址的方法【调用搜狐接口】
2016/09/05 Javascript
Json按某个键的值进行排序
2016/12/22 Javascript
angular4 如何在全局设置路由跳转动画的方法
2017/08/30 Javascript
详解解决Vue相同路由参数不同不会刷新的问题
2018/10/12 Javascript
浅析vue-cli3配置webpack-bundle-analyzer插件【推荐】
2019/10/23 Javascript
Vue自定义组件双向绑定实现原理及方法详解
2020/09/03 Javascript
用Python和MD5实现网站挂马检测程序
2014/03/13 Python
详细介绍Python中的偏函数
2015/04/27 Python
django ajax json的实例代码
2018/05/29 Python
python如何发布自已pip项目的方法步骤
2018/10/09 Python
python输出带颜色字体实例方法
2019/09/01 Python
Python如何爬取b站热门视频并导入Excel
2020/08/10 Python
你不知道的5个HTML5新功能
2016/06/28 HTML / CSS
美国时尚配饰品牌:Dooney & Bourke
2017/11/14 全球购物
跑步、骑行和铁人三项的高性能眼镜和服装:ROKA
2018/07/06 全球购物
意向协议书范本
2014/04/23 职场文书
领导干部群众路线个人对照检查材料思想汇报
2014/09/30 职场文书
高考作弊检讨书1500字
2015/02/16 职场文书
2015中秋祝酒词
2015/08/12 职场文书
2016年“6.26”禁毒宣传月系列活动总结
2016/04/05 职场文书
2019年汽车租赁合同范本!
2019/08/12 职场文书
Nginx+Tomcat实现负载均衡、动静分离的原理解析
2021/03/31 Servers
css3实现背景图片颜色修改的多种方式
2021/04/13 HTML / CSS
volatile保证可见性及重排序方法
2022/08/05 Java/Android