服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|数据库技术|

服务器之家 - 数据库 - Mysql - MySQL存储秘密揭示:CHAR vs.VARCHAR,解锁定长神器的终极选择指南!

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

2023-11-21 15:28数据库干货铺 Mysql

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

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),则,存储所需的大小对比如下:

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

注:

  • 如果字符集为其他类型(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)

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

从显示结果来看,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则原样显示

MySQL存储秘密揭示:CHAR vs.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                 |
+--------+-----------+-------------------------+----------------------------+

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

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)

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

此时使用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)

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

可见,此时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存储秘密揭示:CHAR vs.VARCHAR,解锁定长神器的终极选择指南!

该结果是没有区别的。

三、字符串长度查看函数

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

1、LENGTH 函数

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

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

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

2、CHAR_LENGTH 函数

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

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

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

3、CHARACTER_LENGTH 函数

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

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

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

4、BIT_LENGTH 函数

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

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

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

四、结语

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

原文地址:https://mp.weixin.qq.com/s/e3VwKg6Q3DDg6qBk43za-Q

延伸 · 阅读

精彩推荐
  • Mysql导致MySQL索引失效的一些常见写法总结

    导致MySQL索引失效的一些常见写法总结

    这篇文章主要给大家介绍了关于导致MySQL索引失效的一些常见写法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,...

    一个程序员的成长8532021-02-03
  • MysqlMysql事务处理详解

    Mysql事务处理详解

    什么是事务处理呢??事务处理是用来维护数据库的完整性的,它保证成批的MySQL操作要么完全执行,要么完成不执行。...

    代码成就未来5012020-08-12
  • Mysqlmysql prompt的用法详解

    mysql prompt的用法详解

    本篇文章是对mysql中prompt的用法进行了详细的分析介绍,需要的朋友参考下 ...

    MYSQL教程网3782019-12-28
  • Mysqlsql脚本函数编写postgresql数据库实现解析

    sql脚本函数编写postgresql数据库实现解析

    这篇文章主要介绍了sql脚本函数编写postgresql数据库实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋...

    火鸦哈士奇4412020-12-04
  • MysqlMySQL too many connections错误的原因及解决

    MySQL too many connections错误的原因及解决

    这篇文章主要介绍了MySQL too many connections错误的原因及解决,帮助大家更好的理解和学习使用MySQL,感兴趣的朋友可以了解下...

    AsiaYe3602021-05-04
  • Mysql安装Mysql时可能会遇到的一些疑难杂症

    安装Mysql时可能会遇到的一些疑难杂症

    这篇文章主要给大家介绍了关于安装Mysql时可能会遇到的一些疑难杂症,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价...

    学无止境还得学8922021-03-30
  • MysqlMysql中正则表达式Regexp常见用法

    Mysql中正则表达式Regexp常见用法

    这篇文章主要介绍了Mysql中正则表达式Regexp常见用法,MySql REGEXP运算符匹配字符串,mysql正则REGEXP学习练习笔记,需要的朋友可以参考下...

    MYSQL教程网11252021-01-06
  • Mysqlmysql 数据类型TIMESTAMP

    mysql 数据类型TIMESTAMP

    timestamp数据类型是一个比较特殊的数据类型,他可以自动在你不使用程序更新情况下只要你更新了记录timestamp会自动更新时间 ...

    whsnow4512020-04-11