MySQL存储秘密揭示:CHAR vs.VARCHAR,解锁定长神器的终极选择指南!

CHAR和VARCHAR类型在存储和检索方式上有相似之处,但在最大长度以及是否保留尾随空格方面存在差异。

一、存储方面

1、存储对比

CHAR和VARCHAR类型的声明包含一个长度,表示要存储的最大字符数。例如,CHAR(30)可以容纳最多30个字符。

CHAR列的长度在创建表时被固定为您声明的长度。长度可以是从0到255的任何值。当存储CHAR值时,它们会被右填充到指定的长度。当检索CHAR值时,除非启用了PAD_CHAR_TO_FULL_LENGTH SQL模式(默认没启用),否则会删除尾随空格。

VARCHAR列中的值是可变长度字符串。长度可以指定为0到65,535的值。VARCHAR的有效最大长度取决于最大行大小(65,535字节,这个大小被所有列共享)和所使用的字符集。

2、具体对比

假设当前一个表里包含类型为char(4)及varchar(4)的列(假设该列使用单字节字符集如latin1),则,存储所需的大小对比如下:

注:

  • 如果字符集为其他类型(utf8mb4),则根据存储的内容进行换算即可
  • 上例中为了演示,非严格模式时可以截断存储

二、显示及检索对比

本文后续案例是在utf8的字符集的实例上进行演示的

1、默认SQL模式

默认没开启PAD_CHAR_TO_FULL_LENGTH SQL模式的情况下,char及varchar的显示几乎没有区别,例如:

mysql> create table tb_char (id int primary key auto_increment, c_char char(10),c_varchar  varchar(10));
Query OK, 0 rows affected (0.01 sec)


mysql> insert into tb_char (c_char,c_varchar) values ('a','a'),('张三','张三'),('tc一','tc一');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

查询显示如下:

mysql> select * from  tb_char;
+----+--------+-----------+
| id | c_char | c_varchar |
+----+--------+-----------+
|  1 | a      | a         |
|  2 | 张三   | 张三      |
|  3 | tc一   | tc一      |
+----+--------+-----------+
3 rows in set (0.00 sec)

查看长度如下:

mysql> select c_char,c_varchar, length(c_char)len_char,length(c_varchar)len_varchar,char_length(c_char),char_length(c_varchar) from tb_char;
+--------+-----------+----------+-------------+---------------------+------------------------+
| c_char | c_varchar | len_char | len_varchar | char_length(c_char) | char_length(c_varchar) |
+--------+-----------+----------+-------------+---------------------+------------------------+
| a      | a         |        1 |           1 |                   1 |                      1 |
| 张三   | 张三      |        6 |           6 |                   2 |                      2 |
| tc一   | tc一      |        5 |           5 |                   3 |                      3 |
+--------+-----------+----------+-------------+---------------------+------------------------+
3 rows in set (0.00 sec)

从显示结果来看,char与varchar在此时看上去是一致的,即:查询时,char类型的数据会将末尾空格去除。

此时,如果写入末尾带空格的值,则结果会如何呢?

mysql> insert into tb_char (c_char,c_varchar) values ('abc ','abc ');
Query OK, 1 row affected (0.01 sec)

mysql> select * from  tb_char;
+----+--------+-----------+
| id | c_char | c_varchar |
+----+--------+-----------+
|  1 | a      | a         |
|  2 | 张三   | 张三      |
|  3 | tc一   | tc一      |
|  4 | abc    | abc       |
+----+--------+-----------+
4 rows in set (0.00 sec)
mysql> select c_char,c_varchar, length(c_char)len_char,length(c_varchar)len_varchar,char_length(c_char),char_length(c_varchar) from tb_char;
+--------+-----------+----------+-------------+---------------------+------------------------+
| c_char | c_varchar | len_char | len_varchar | char_length(c_char) | char_length(c_varchar) |
+--------+-----------+----------+-------------+---------------------+------------------------+
| a      | a         |        1 |           1 |                   1 |                      1 |
| 张三   | 张三      |        6 |           6 |                   2 |                      2 |
| tc一   | tc一      |        5 |           5 |                   3 |                      3 |
| abc    | abc       |        3 |           4 |                   3 |                      4 |
+--------+-----------+----------+-------------+---------------------+------------------------+
4 rows in set (0.00 sec)

此时,结果出现了不同,char类型的显示依旧将末尾空格去除,而varchar则原样显示

如果此时按条件查询‘abc’及‘abc ’,结果会如何?

mysql> select * from  tb_char where c_char ='abc';
+----+--------+-----------+
| id | c_char | c_varchar |
+----+--------+-----------+
|  4 | abc    | abc       |
+----+--------+-----------+
1 row in set (0.00 sec)
mysql> select * from  tb_char where c_varchar ='abc';
+----+--------+-----------+
| id | c_char | c_varchar |
+----+--------+-----------+
|  4 | abc    | abc       |
+----+--------+-----------+
1 row in set (0.00 sec)
mysql> select * from  tb_char where c_char ='abc ';
+----+--------+-----------+
| id | c_char | c_varchar |
+----+--------+-----------+
|  4 | abc    | abc       |
+----+--------+-----------+
1 row in set (0.00 sec)
mysql> select * from  tb_char where c_varchar ='abc ';
+----+--------+-----------+
| id | c_char | c_varchar |
+----+--------+-----------+
|  4 | abc    | abc       |
+----+--------+-----------+
1 row in set (0.00 sec)

结果是都可以显示。

不过,如果做了concat操作,结果如下:

mysql> select c_char,c_varchar,concat(c_char,'concat'),concat(c_varchar,'concat') from tb_char;
+--------+-----------+-------------------------+----------------------------+
| c_char | c_varchar | concat(c_char,'concat') | concat(c_varchar,'concat') |
+--------+-----------+-------------------------+----------------------------+
| a      | a         | aconcat                 | aconcat                    |
| 张三   | 张三      | 张三concat              | 张三concat                 |
| tc一   | tc一      | tc一concat              | tc一concat                 |
| abc    | abc       | abcconcat               | abc concat                 |
+--------+-----------+-------------------------+----------------------------+

2、PAD_CHAR_TO_FULL_LENGTH 模式

将SQL模式改为PAD_CHAR_TO_FULL_LENGTH后,再对比看一下。

mysql>  set sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';
Query OK, 0 rows affected (0.00 sec)
mysql> select * from  tb_char;
+----+----------------+-----------+
| id | c_char         | c_varchar |
+----+----------------+-----------+
|  1 | a              | a         |
|  2 | 张三           | 张三      |
|  3 | tc一           | tc一      |
|  4 | abc            | abc       |
+----+----------------+-----------+
4 rows in set (0.00 sec)
mysql> select c_char,c_varchar, length(c_char)len_char,length(c_varchar)len_varchar,char_length(c_char),char_length(c_varchar) from tb_char;
+----------------+-----------+----------+-------------+---------------------+------------------------+
| c_char         | c_varchar | len_char | len_varchar | char_length(c_char) | char_length(c_varchar) |
+----------------+-----------+----------+-------------+---------------------+------------------------+
| a              | a         |       10 |           1 |                  10 |                      1 |
| 张三           | 张三      |       14 |           6 |                  10 |                      2 |
| tc一           | tc一      |       12 |           5 |                  10 |                      3 |
| abc            | abc       |       10 |           4 |                  10 |                      4 |
+----------------+-----------+----------+-------------+---------------------+------------------------+
4 rows in set (0.00 sec)

此时使用concat,结果如下:

mysql> select c_char,c_varchar,concat(c_char,'concat'),concat(c_varchar,'concat') from tb_char;
+----------------+-----------+-------------------------+----------------------------+
| c_char         | c_varchar | concat(c_char,'concat') | concat(c_varchar,'concat') |
+----------------+-----------+-------------------------+----------------------------+
| a              | a         | a         concat        | aconcat                    |
| 张三           | 张三      | 张三        concat      | 张三concat                 |
| tc一           | tc一      | tc一       concat       | tc一concat                 |
| abc            | abc       | abc       concat        | abc concat                 |
+----------------+-----------+-------------------------+----------------------------+
4 rows in set (0.00 sec)

可见,此时char类型每一行的末尾都已经填充了空格。

使用‘abc’及‘abc ’查看结果:

mysql> select * from  tb_char where c_char ='abc';
+----+------------+-----------+
| id | c_char     | c_varchar |
+----+------------+-----------+
|  4 | abc        | abc       |
+----+------------+-----------+
1 row in set (0.00 sec)
mysql> select * from  tb_char where c_varchar ='abc';
+----+------------+-----------+
| id | c_char     | c_varchar |
+----+------------+-----------+
|  4 | abc        | abc       |
+----+------------+-----------+
1 row in set (0.00 sec)
mysql> select * from  tb_char where c_char ='abc ';
+----+------------+-----------+
| id | c_char     | c_varchar |
+----+------------+-----------+
|  4 | abc        | abc       |
+----+------------+-----------+
1 row in set (0.00 sec)
mysql> select * from  tb_char where c_varchar ='abc ';
+----+------------+-----------+
| id | c_char     | c_varchar |
+----+------------+-----------+
|  4 | abc        | abc       |
+----+------------+-----------+
1 row in set (0.00 sec)
mysql> select * from  tb_char where c_char ='abc    ';
+----+------------+-----------+
| id | c_char     | c_varchar |
+----+------------+-----------+
|  4 | abc        | abc       |
+----+------------+-----------+
1 row in set (0.00 sec)

该结果是没有区别的。

三、字符串长度查看函数

在MySQL中,字符串计算函数有如下几种,在使用是注意区分。

1、LENGTH 函数

用于返回字符串的字节数。对于英文字符,一个字符占用一个字节;而对于一些多字节字符(如UTF-8编码的中文字符),一个字符可能占用多个字节。

SELECT LENGTH('Hello'); -- 返回 5
SELECT LENGTH('你好');   -- 返回 6(UTF-8编码中文字符占用3个字节)

2、CHAR_LENGTH 函数

用于返回字符串的字符数,而不是字节数。这意味着它会考虑字符的多字节性,确保正确地计算字符的数量。

SELECT CHAR_LENGTH('Hello'); -- 返回 5
SELECT CHAR_LENGTH('你好');   -- 返回 2(两个中文字符)

3、CHARACTER_LENGTH 函数

 与 CHAR_LENGTH 函数功能相似,也用于返回字符串的字符数。

SELECT CHARACTER_LENGTH('Hello'); -- 返回 5
SELECT CHARACTER_LENGTH('你好');   -- 返回 2

4、BIT_LENGTH 函数

 返回字符串的位数,而不是字节数或字符数。

SELECT BIT_LENGTH('Hello'); -- 返回 40(5个英文字符,每个字符8位)
SELECT BIT_LENGTH('你好');   -- 返回 48(2个中文字符,每个字符24位)

四、结语

了解CHAR和VARCHAR类型的差异对于有效地设计和管理MySQL数据库极为重要。选择合适的数据类型和了解它们的行为有助于避免意外的数据处理问题。同时,开发人员应根据具体需求和预期行为来选择合适的数据类型,以确保数据存储和检索的一致性和准确性。

文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/240589.html<

(0)
运维的头像运维
上一篇2025-04-23 22:52
下一篇 2025-04-23 22:53

相关推荐

  • 个人主题怎么制作?

    制作个人主题是一个将个人风格、兴趣或专业领域转化为视觉化或结构化内容的过程,无论是用于个人博客、作品集、社交媒体账号还是品牌形象,核心都是围绕“个人特色”展开,以下从定位、内容规划、视觉设计、技术实现四个维度,详细拆解制作个人主题的完整流程,明确主题定位:找到个人特色的核心主题定位是所有工作的起点,需要先回答……

    2025-11-20
    0
  • 社群营销管理关键是什么?

    社群营销的核心在于通过建立有温度、有价值、有归属感的社群,实现用户留存、转化和品牌传播,其管理需贯穿“目标定位-内容运营-用户互动-数据驱动-风险控制”全流程,以下从五个维度展开详细说明:明确社群定位与目标社群管理的首要任务是精准定位,需明确社群的核心价值(如行业交流、产品使用指导、兴趣分享等)、目标用户画像……

    2025-11-20
    0
  • 香港公司网站备案需要什么材料?

    香港公司进行网站备案是一个涉及多部门协调、流程相对严谨的过程,尤其需兼顾中国内地与香港两地的监管要求,由于香港公司注册地与中国内地不同,其网站若主要服务内地用户或使用内地服务器,需根据服务器位置、网站内容性质等,选择对应的备案路径(如工信部ICP备案或公安备案),以下从备案主体资格、流程步骤、材料准备、注意事项……

    2025-11-20
    0
  • 如何企业上云推广

    企业上云已成为数字化转型的核心战略,但推广过程中需结合行业特性、企业痛点与市场需求,构建系统性、多维度的推广体系,以下从市场定位、策略设计、执行落地及效果优化四个维度,详细拆解企业上云推广的实践路径,精准定位:明确目标企业与核心价值企业上云并非“一刀切”的方案,需先锁定目标客户群体,提炼差异化价值主张,客户分层……

    2025-11-20
    0
  • PS设计搜索框的实用技巧有哪些?

    在PS中设计一个美观且功能性的搜索框需要结合创意构思、视觉设计和用户体验考量,以下从设计思路、制作步骤、细节优化及交互预览等方面详细说明,帮助打造符合需求的搜索框,设计前的规划明确使用场景:根据网站或APP的整体风格确定搜索框的调性,例如极简风适合细线条和纯色,科技感适合渐变和发光效果,电商类则可能需要突出搜索……

    2025-11-20
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注