mysql md5 长度_MySQL:The CHAR and VARCHAR Types

本文介绍了MySQL中CHAR和VARCHAR类型的长度定义、存储差异及尾部空格处理,包括它们在不同长度和存储引擎下的表现。CHAR类型在存储时固定长度,可能会补足空格并检索时自动移除,适合存储如md5密码;VARCHAR则按需存储,更节省空间,但更新可能带来额外操作。在创建表时应根据实际需求选择合适的数据类型。
摘要由CSDN通过智能技术生成
da1651712fa1256bbd3059e087215120.gif

点击上方蓝色字体,关注我们

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,后同):

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则会保留空格。示例如下:

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》第四章

709d1ddf4449015effde6a750f6a984d.gif因为你的分享、点赞、在看我足足的精气神儿! c7b47158916b32b622fecab9fb7458e3.gif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值