MySQL中varchar和char类型的区别

 更新时间:2021年11月14日 19:55   作者:满丶怀
VARCHAR和CHAR是两种最主要的字符串类型。那么MySQL中varchar和char类型的区别是什么,本文就具体来介绍一下,感兴趣的可以了解一下

前述

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;

 

执行结果

如果用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;

 

执行结果

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类型内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

原文出处:https://blog.csdn.net/weixin_42570248/article/details/897868

相关文章

  • MySQL性能监控软件Nagios的安装及配置教程

    这篇文章主要介绍了MySQL性能监控软件Nagios的安装及配置教程,这里以CentOS操作系统为环境进行演示,需要的朋友可以参考下...2015-12-14
  • mysql的3种分表方案

    一、先说一下为什么要分表:当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。根据个人经验,mysql执行一个sql的过程如下:1...2014-05-31
  • 深入研究mysql中的varchar和limit(容易被忽略的知识)

    为什么标题要起这个名字呢?commen sence指的是那些大家都应该知道的事情,但往往大家又会会略这些东西,或者对这些东西一知半解,今天我总结下自己在mysql中遇到的一些commen sense类型的问题。 ...2015-03-15
  • Centos5.5中安装Mysql5.5过程分享

    这几天在centos下装mysql,这里记录一下安装的过程,方便以后查阅Mysql5.5.37安装需要cmake,5.6版本开始都需要cmake来编译,5.5以后的版本应该也要装这个。安装cmake复制代码 代码如下: [[email protected] ~]# wget http://www.cm...2015-03-15
  • Windows服务器MySQL中文乱码的解决方法

    我们自己鼓捣mysql时,总免不了会遇到这个问题:插入中文字符出现乱码,虽然这是运维先给配好的环境,但是在自己机子上玩的时候咧,总得知道个一二吧,不然以后如何优雅的吹牛B。...2015-03-15
  • 忘记MYSQL密码的6种常用解决方法总结

    首先要声明一点,大部分情况下,修改MySQL密码是需要有mysql里的root权限的...2013-09-11
  • Mysql命令大全(详细篇)

    一、连接Mysql格式: mysql -h主机地址 -u用户名 -p用户密码1、连接到本机上的MYSQL。首先打开DOS窗口,然后进入目录mysql/bin,再键入命令mysql -u root -p,回车后提示你输密码.注意用户名前可以有空格也可以没有空格,但是密...2015-11-08
  • 用VirtualBox构建MySQL测试环境

    宿主机使用网线的时候,客户机在Bridged Adapter模式下,使用Atheros AR8131 PCI-E Gigabit Ethernet Controller上网没问题。 宿主机使用无线的时候,客户机在Bridged Adapter模式下,使用可选项里唯一一个WIFI选项,Microsoft Virtual Wifi Miniport Adapter也无法上网,故弃之。...2013-09-19
  • MySQL数据库备份还原方法

    MySQL命令行导出数据库: 1,进入MySQL目录下的bin文件夹:cd MySQL中到bin文件夹的目录 如我输入的命令行:cd C:/Program Files/MySQL/MySQL Server 4.1/bin (或者直接将windows的环境变量path中添加该目录) ...2013-09-26
  • RHEL6.5编译安装MySQL5.6.26教程

    一、准备编译环境,安装所需依赖包yum groupinstall 'Development' -y yum install openssl openssl-devel zlib zlib-devel -y yum install readline-devel pcre-devel ncurses-devel bison-devel cmake -y二、编译安...2015-10-21
  • mongodb与mysql命令详细对比

    传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB对于关系型数据库里的表,但是集合中没有列、行和关...2013-09-11
  • 如何解决安装MySQL5.0后出现1607异常

    最近项目比较多,时间不宽松,一直没给大家整理,今天小编抽个时间把我的解决方案分享给大家,具体内容如下所示。问题描述:我在自己的电脑上配置了Mysql5环境,同时安装了一个phpMyAdmin管理工具,安装完成后,发现在phpMyAdmin里面...2015-10-21
  • MySQL数据库遭到攻击篡改(使用备份和binlog进行数据恢复)

    这篇文章主要介绍了MySQL数据库遭到攻击篡改(使用备份和binlog进行数据恢复),需要的朋友可以参考下...2016-04-26
  • mysql Non-Transactional Database Only(只支持MyISAM)

    按照discuz官方的建议,选的都是Non-Transactional Database Only 只支持MyISAM,其实默认都安装也挺好 ...2016-04-18
  • MySQL 从全库备份中恢复指定的表和库示例

    这篇文章主要介绍了MySQL 从全库备份中恢复指定的表和库示例的相关资料,这里提供了相应的方法,来实现恢复指定的表和库数据,需要的朋友可以参考下...2016-12-02
  • python操作mysql、excel、pdf的示例

    这篇文章主要介绍了python操作mysql、excel、pdf的示例,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下...2021-03-29
  • 查找MySQL中查询慢的SQL语句方法

    这篇文章主要介绍了查找MySQL中查询慢的SQL语句方法,需要的朋友可以参考下...2017-05-25
  • 带你彻底搞懂python操作mysql数据库(cursor游标讲解)

    这篇文章主要介绍了带你彻底搞懂python操作mysql数据库(cursor游标讲解),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-30
  • MySql数据库单表查询与多表连接查询效率对比

    在遇到数据之间的联系很复杂,建表就很纠结,到底该怎么去处理这些复杂的数据呢,是单表查询,然后在业务层去处理数据间的关系,还是直接通过多表连接查询来处理数据关系呢...2021-09-27
  • MySQL中开启和使用通用查询日志的实例教程

    这篇文章主要介绍了MySQL中开启和使用通用查询日志的实例教程,包括其备份和关闭等基础操作的例子讲解,需要的朋友可以参考下...2015-12-25