MySQL中varchar和char类型的区别


Posted in MySQL onNovember 17, 2021

前述

VARCHAR和CHAR是两种最主要的字符串类型。不幸的是,很难精确地解释这些值是怎么存储在磁盘和内存中的,因为这跟存储引擎的具体实现有关。下面的描述假设使用的存储引擎是InnoDB和/或者MyISAM。如果使用的不是这两种存储引擎,请参考所使用的存储引擎的文档。

先看看VARCHAR和CHAR值通常在磁盘上怎么存储。请注意,存储引擎存储CHAR或者VARCHAR值的方式在内存中和在磁盘上可能不一样,所以MySQL服务器从存储引擎读出的值可能需要转换为另一种存储格式。

VARCHAR类型

VARCHAR类型用于存储可变长字符串,是最常见的字符串数据类型。它比定长类型更节省空间,因为它仅使用必要的空间(例如,越短的字符串使用越少的空间)。有一种情况例外,如果MySQL表使用ROW_FORMAT=FIXED创建的话,每一行都会使用定长存储,这会很浪费空间。

VARCHAR需要使用1或2个额外字节记录字符串的长度:如果列的最大长度小于或等于255字节,则只使用1个字节表示,否则使用2个字节。假设采用latin1字符集,一个VARCHAR(10)的列需要11个字节的存储空间。VARCHAR(1000)的列则需要1002个字节,因为需要2个字节存储长度信息。

VARCHAR节省了存储空间,所以对性能也有帮助。但是,由于行是变长的,在UPDATE时可能使行变得比原来更长,这就导致需要做额外的工作。如果一个行占用的空间增长,并且在页内没有更多的空间可以存储,在这种情况下,不同的存储引擎的处理方式是不一样的。例如,MyISAM会将行拆成不同的片段存储,InnoDB则需要分裂页来使行可以放进页内。其他一些存储引擎也许从不在原数据位置更新数据。

VARCHAR适用情况

下面这些情况下适用VARCHAR是合适的:

  • 字符串列的最大长度比平均长度大很多
  • 列的更新很少,所以碎片不是问题
  • 使用了像UTF-8这样复杂的字符集,每个字符都使用不同的字节数进行存储

CHAR类型

CHAR类型是定长的:MySQL总是根据定义的字符串长度分配足够的空间。当存储CHAR值时,MySQL会删除所有的末尾空格。CHAR值会根据需要采用空格进行填充以方便比较。

CHAR适合存储很短的字符串,或者所有值都接近同一个长度。例如,CHAR非常适合存储密码的MD5值,因为这是一个定长的值。对于经常变更的数据,CHAR也比VARCHAR更好,因为定长的CHAR类型不容易产生碎片。对于非常短的列,CHAR比VARCHAR在存储空间上也更有效率。例如用CHAR(1)来存储只有Y和N的值,如果采用单字节字符集只需要一个字节,但是VARCHAR(1)却需要两个字节,因为还有一个记录长度的额外字节。

测试

下面通过例子来具体说明CHAR与VARCHAR行为上的不同,首先,我们创建一张只有一个CHAR(10)字段的表,并且往里面插入一些值:

CREATE TABLE char_test
(
    char_col CHAR(10)
);
 
INSERT INTO char_test 
VALUES
    ('string1').
    ('  string2').
    ('string3  ');

当我们检索这些值的时候,会发现string3末尾的空格被截断了。

SELECT CONCAT("'", char_col, "'")
FROM char_test;

MySQL中varchar和char类型的区别 

 

 

执行结果

 

如果用VARCHAR(10)字段存储相同的值,可以得到如下结果:

 

 

 

CREATE TABLE varchar_test
(
    varchar_col VARCHAR(10)
);
 
INSERT INTO varchar_test 
VALUES
    ('string1').
    ('  string2').
    ('string3  ');
 
SELECT CONCAT("'", varchar_col, "'")
FROM varchar_test;

MySQL中varchar和char类型的区别 

执行结果

VARCHAR(5)与VARCHAR(200)的区别

我们倘若用VARCHAR(5)和VARCHAR(200)来存储'hello',我们知道这两者的空间开销是一样的。那么我们可以让VARCHAR的长度始终保持很大吗?使用更短的列有什么优势吗?

事实证明有很大的优势。更长的列会消耗更多的内存,因为MySQL通常会分配固定大小的内存块来保存内部值。尤其是使用内存临时表进行排序或操作时会特别糟糕。在利用磁盘临时表进行排序时也同样糟糕。

所以最好的策略是只分配真正需要的空间。

总结

当我们为字符串类型的字段选取类型的时候,判断该选取VARCHAR还是CHAR,我们可以从以下几个方面来考虑:

  • 该字段数据集的平均长度与最大长度是否相差很小,若相差很小优先考虑CHAR类型,反之,考虑VARCHAR类型。
  • 若字段存储的是MD5后的哈希值,或一些定长的值,优先选取CHAR类型。
  • 若字段经常需要更新,则优先考虑CHAR类型,由于CHAR类型为定长,因此不容易产生碎片。
  • 对于字段值存储很小的信息,如性别等,优先选取CHAR类型,因为VARCHAR类型会占用额外的字节保存字符串长度信息。

总之一句话,当我们能够选取CHAR类型的时候,或者说空间消耗相对并不是影响因素的重点时,尽量选取CHAR类型,因为在其他方面,CHAR类型都有着或多或少的优势。而当空间消耗成为了很大的影响因素以后,我们则考虑使用VARCHAR类型。

到此这篇关于MySQL中varchar和char类型的区别的文章就介绍到这了,更多相关MySQL varchar和char类型内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL infobright的安装步骤
Apr 07 MySQL
MYSQL数据库使用UTF-8中文编码乱码的解决办法
May 26 MySQL
MySql开发之自动同步表结构
May 28 MySQL
mysql5.7使用binlog 恢复数据的方法
Jun 03 MySQL
如何使用分区处理MySQL的亿级数据优化
Jun 18 MySQL
MySQL连表查询分组去重的实现示例
Jul 01 MySQL
MySQL中datetime时间字段的四舍五入操作
Oct 05 MySQL
mysql的Buffer Pool存储及原理
Apr 02 MySQL
MySQL数据库查询进阶之多表查询详解
Apr 08 MySQL
CentOS MySql8 远程连接实战
Apr 19 MySQL
MySQL索引失效场景及解决方案
Jul 23 MySQL
MySQL索引失效十种场景与优化方案
May 08 MySQL
mysql中varchar类型的日期进行比较、排序等操作的实现
Nov 17 #MySQL
MySQL数据库中varchar类型的数字比较大小的方法
Nov 17 #MySQL
MySQL和Oracle批量插入SQL的通用写法示例
Nov 17 #MySQL
SQL 聚合、分组和排序
Nov 11 #MySQL
SQL基础的查询语句
Nov 11 #MySQL
MySQL之select、distinct、limit的使用
Nov 11 #MySQL
MySQL表类型 存储引擎 的选择
Nov 11 #MySQL
You might like
PHP date函数常用时间处理方法
2015/05/11 PHP
php根据数据id自动生成编号的实现方法
2016/10/16 PHP
Laravel使用RabbitMQ的方法示例
2019/06/18 PHP
javascript脚本调试方法小结
2008/11/24 Javascript
formvalidator验证插件中有关ajax验证问题
2013/01/04 Javascript
在Linux上用forever实现Node.js项目自启动
2014/07/09 Javascript
分享两个手机访问pc网站自动跳转手机端网站代码
2020/12/24 Javascript
jquery实现页面关键词高亮显示的方法
2015/03/12 Javascript
轻松实现JavaScript图片切换
2016/01/12 Javascript
javascript用正则表达式过滤空格的实现代码
2016/06/14 Javascript
AngularJS全局scope与Isolate scope通信用法示例
2016/11/22 Javascript
JavaScript组成、引入、输出、运算符基础知识讲解
2016/12/08 Javascript
JavaScript 字符串数字左补位,右补位,取固定长度,截位扩展函数代码
2017/03/25 Javascript
详解微信小程序 template添加绑定事件
2017/06/23 Javascript
js使用原型对象(prototype)需要注意的地方
2017/08/28 Javascript
iview日期控件,双向绑定日期格式的方法
2018/03/15 Javascript
webpack之引入图片的实现及问题
2018/10/08 Javascript
JQuery判断radio单选框是否选中并获取值的方法
2019/01/17 jQuery
VUE的history模式下除了index外其他路由404报错解决办法
2019/08/21 Javascript
如何基于js判断浏览器版本
2020/02/20 Javascript
详解如何在vue+element-ui的项目中封装dialog组件
2020/12/11 Vue.js
python 实现归并排序算法
2012/06/05 Python
python监控网卡流量并使用graphite绘图的示例
2014/04/27 Python
浅析python协程相关概念
2018/01/20 Python
Pandas_cum累积计算和rolling滚动计算的用法详解
2019/07/04 Python
HTML5里的placeholder属性使用实例和美化显示效果的方法
2014/04/23 HTML / CSS
美国女性服饰销售网站:Nasty Gal(坏女孩)
2016/07/26 全球购物
CHARLES & KEITH英国官网:新加坡时尚品牌
2018/07/04 全球购物
Rossignol金鸡美国官网:始于1907年法国百年雪具品牌
2019/03/06 全球购物
俄罗斯儿童和青少年服装、鞋子及配件的在线商店:Orby
2020/02/20 全球购物
定义一结构体数组表示分数,并求两个分数相加之和
2013/06/11 面试题
房产公证书范本
2014/04/10 职场文书
迎国庆演讲稿
2014/09/15 职场文书
2014保险公司内勤工作总结
2014/12/16 职场文书
2015年党风建设工作总结
2015/04/29 职场文书
小学教育见习总结
2015/06/23 职场文书