MySQL中的字符集和排序规则

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: MySQL中的字符集和排序规则

关键字: 字符集,utf8mb4,emoj

众所周知,mysql的utf8是假的utf8,没法存emoj等字符。要设置为utf8mb4...


问题


同事给了一段Update语句,更新某张表id=xxx的某个字段;

CREATE TABLE `table_name` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `xxx_id` int(11) NOT NULL,
  `description` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
  `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `end_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `max_xxx` int(11) NOT NULL DEFAULT '0',
  `max_xxx` int(11) NOT NULL DEFAULT '0',
  `xxx_generate_method` tinyint(4) NOT NULL,
  `xxx_generate_method` tinyint(4) NOT NULL,
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_table_name_xxx_id` (`xxx_id`),
  KEY `idx_table_name_end_time` (`end_time`),
  KEY `idx_table_name_start_time` (`start_time`)
) ENGINE=InnoDB AUTO_INCREMENT=5822 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

登陆跳板机,连接远程数据库后,执行sql,报错: ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x93\xA3Ev...'

\xF0\x9F\x93\xA3恰好是转义之后的emoj

这张表所在的库的字符集是utf8,但是表指定了是utf8mb4,字段没有指定,仅指定了排序方式为utf8mb4_unicode_ci

据说,字符集规则会按照  字段设置>表设置>库设置的顺序。

此处 这个字段没有设置字符集,那应该用表的字符集即*DEFAULT CHARSET=utf8mb4 *

(且经过试验,如果COLLATE=utf8mb4_unicode_ci,那字符集不可能是utf8,只可能是utf8mb4,不然报错时会直接报错)


下面补充一些mysql字符集的知识


查看库级别的 字符集和编码设置

SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';

微信截图_20230926003511.png

微信截图_20230926003531.png

Variable_name
character_set_client
character_set_connection
character_set_database
character_set_filesystem
character_set_results
character_set_server
character_set_system
character_sets_dir 

这都是干啥的?

这些变量是 MySQL 中与字符集相关的变量,用于控制不同环境中的字符集设置。以下是对每个变量的简要说明:

  1. character_set_client: 客户端连接到 MySQL 服务器时所使用的字符集。
  2. character_set_connection: 当前连接的默认字符集。它可以在客户端连接时通过 SET NAMES 命令来设置。
  3. character_set_database: 默认数据库的字符集。在创建数据库时设置,新创建的表将继承该字符集。
  4. character_set_filesystem: 文件系统的默认字符集。用于存储文件名和路径的字符集。
  5. character_set_results: 返回给客户端的结果集的字符集。
  6. character_set_server: MySQL 服务器的默认字符集。用于新建数据库、表和列的默认字符集。
  7. character_set_system: MySQL 系统数据字典和内部字符串的字符集。
  8. character_sets_dir: MySQL 字符集定义文件的目录路径。

这些变量的设置是相互关联的,通过调整它们的值可以控制 MySQL 在不同环境中的字符集行为。确保这些变量的值一致并与你的应用程序和数据的字符集一致,可以确保正确地存储、传输和显示数据。

注意:在修改这些字符集相关的变量之前,请确保了解其含义和影响,并在备份数据的情况下谨慎操作。修改字符集设置可能会对现有数据和应用程序产生影响。


一般说的字符集和排序规则,应该主要看

SHOW VARIABLES LIKE 'character_set_database';
SHOW VARIABLES LIKE 'collation_database';

查看表级别的字符集和编码设置

SHOW CREATE TABLE `your_table_name`;

能得到建表语句,看最后的DEFAULT CHARSET


具体到table的column的字符集如何查看?

SHOW FULL COLUMNS FROM your_table_name;

在查询结果中,查找 "Collation" 列。该列显示每个列(字段)的字符集和排序规则。

请注意,"Collation" 列中的值表示字符集和排序规则的组合。常见的字符集包括 UTF-8(如 utf8mb4)和 Latin1(如 latin1)。

微信截图_20230926003720.png

微信截图_20230926003728.png

微信截图_20230926003735.png

Collation 本意是校勘,校对之意,在数据库中 是排序规则

这个字段的第一部分,其实已经指明了字符集...所以SHOW FULL COLUMNS没有必要再多一个字符集列


那么,问题何在呢?


起初搜到,需要在连接时指定为utf8mb4才可以

mysql --default-character-set=utf8mb4 -u root -h xxx.xxx.xx.xx -p密码

但还是不行...

最后发现执行  SET NAMES utf8mb4后再执行更新语句,成功!

根据报错信息,看起来在尝试更新xxxxx表中的xxxxxxx字段时遇到了错误。报错信息是ERROR 1366 (HY000): Incorrect string value: '\xF0\x9F\x93\xA3Ev...' for column 'xxxxxxx' at row 1,这表明在该字段中插入了无效的字符。

尽管您已经将该字段的字符集设置为utf8mb4,支持存储四字节的UTF-8字符,但有可能连接或会话的字符集设置仍然不兼容。为了确保字符集一致,您可以尝试执行以下操作:

  1. 在更新语句之前,执行以下SQL语句设置会话字符集为utf8mb4
SET NAMES utf8mb4;
  1. 然后,再执行更新语句:
UPDATE `xxxxx` SET `xxxxxxx` = '...' WHERE (`id` = 5136);

通过这样的设置,会话的字符集将与字段的字符集一致,可以正常存储包含四字节UTF-8字符的字符串。

如果问题仍然存在,请确保数据库连接和客户端工具的字符集设置与字段的字符集设置一致。另外,您还可以检查MySQL服务器的全局字符集设置,以确保它也是utf8mb4



SET NAMES utf8mb4什么?


"SET NAMES utf8mb4" 是一个MySQL命令,用于设置数据库连接的字符集编码为utf8mb4。在MySQL中,字符集决定了数据库如何存储和处理数据。

utf8mb4是一种字符集编码,支持Unicode字符集的全部字符,包括一些较早版本的utf8字符集无法表示的一些字符。utf8mb4编码可以处理各种语言的文字和符号,包括一些较为特殊的字符,如表情符号和特殊符号等。

通过将数据库连接的字符集编码设置为utf8mb4,可以确保数据库可以正确地存储、检索和显示各种字符,避免出现乱码或字符丢失的问题。这在处理多语言或包含特殊字符的应用程序中特别重要。

只对当前连接有效吗?

是的,"SET NAMES utf8mb4" 命令只对当前数据库连接有效。这意味着只有在执行该命令后建立的数据库连接会使用 utf8mb4 字符集编码。

如果你在程序中使用了多个数据库连接,每个连接都需要单独执行 "SET NAMES utf8mb4" 命令来设置字符集编码。

另外,如果你希望永久地将数据库的字符集编码设置为 utf8mb4,你需要修改数据库的默认字符集配置。这样,在新建的数据库连接中不需要再手动执行 "SET NAMES utf8mb4" 命令,因为连接会默认使用数据库的字符集配置。请注意,在修改数据库的默认字符集之前,请确保备份数据和相应的预防措施。


结论


可能是:数据库是utf8,即便我在连接时指定--default-character-set=utf8mb4,依然会用utf8,必须要通过SET NAMES utf8mb4 再设置一次

为了验证,通过 mysql --default-character-set=utf8mb4 -u root -h xxx.xxx.xx.xx -p密码连接mysql,select 刚才更新成功的那条记录,发现emoj无法正常显示; 执行SET NAMES utf8mb4 后,再select能正常看到emoj


设置mysql数据库的字符集和编码设置(谨慎操作,一般不要乱改)


要设置 MySQL 数据库的字符集和编码设置,你可以采取以下步骤:

  1. 登录到 MySQL 数据库服务器,可以使用以下命令: mysql -u your_username -p 替换 your_username 为你的数据库用户名。
  2. 在登录后,可以执行以下命令来查看当前的字符集和编码设置:
SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';
  • 这将显示当前的字符集和编码设置。
  • 若要修改数据库的字符集和编码设置,可以执行以下命令(以utf8mb4为例):
ALTER DATABASE your_database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  • 替换 your_database_name 为你要修改的数据库名称。
  • 如果需要修改特定表的字符集和编码设置,可以执行以下命令(以utf8mb4为例):
ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  • 替换 your_table_name 为你要修改的表名称。
  • 如果你希望新创建的表默认采用特定的字符集和编码,可以在创建表时指定:
CREATE TABLE your_table_name (
  ...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  1. 替换 your_table_name 为你要创建的表名称,并根据需要修改其他表的列和选项。
  2. 重启 MySQL 服务以使更改生效,具体的重启方式取决于你的操作系统和安装方式。

请注意,修改字符集和编码设置可能会影响现有数据和应用程序,因此在进行任何更改之前,请确保备份数据库并谨慎操作。

如何 修改数据库的默认字符集配置

要修改数据库的默认字符集配置,你需要执行以下步骤:

  1. 登录到你的MySQL数据库服务器。
  2. 执行以下命令来打开MySQL的配置文件(通常是my.cnf或my.ini): sudo nano /etc/mysql/my.cnf 如果你使用的是Windows系统,则路径可能是C:\ProgramData\MySQL\MySQL Server X.X\my.ini,其中X.X代表你的MySQL版本号。
  3. 在配置文件中找到 [mysqld] 部分。
  4. 添加或修改以下两行来设置默认字符集编码为 utf8mb4: [mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci 上述配置将字符集设置为 utf8mb4,同时使用了 utf8mb4_unicode_ci 校对规则。你也可以选择其他适合你的校对规则。
  5. 保存并关闭配置文件。
  6. 重新启动MySQL服务以使配置生效,可以使用适合你的操作系统的命令,例如:
  • 在Linux上使用: sudo systemctl restart mysql
  • 在Windows上使用: net stop MySQL net start MySQL
  1. 现在,新建的数据库连接将默认使用 utf8mb4 字符集编码。

请注意,修改数据库的默认字符集可能会对现有的数据库和数据产生影响。在执行这些步骤之前,请确保备份数据并采取相应的预防措施。


mysql set names 命令和 mysql 字符编码问题

理解MySQL中的字符集和排序规则

TiDB-字符集和排序规则


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
3月前
|
自然语言处理 关系型数据库 MySQL
如何在mysql数据库里进行文本的相似度排序?
【8月更文挑战第28天】如何在mysql数据库里进行文本的相似度排序?
366 62
|
22天前
|
SQL NoSQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(5)作者——LJS[含MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页等详解步骤及常见报错问题所对应的解决方法]
MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页、INSERT INTO SELECT / FROM查询结合精例等详解步骤及常见报错问题所对应的解决方法
|
1月前
|
SQL 搜索推荐 关系型数据库
MySQL 如何实现 ORDER BY 排序?
本文详细解析了MySQL中`ORDER BY`的实现原理及优化方法。通过解析与优化、执行及多种优化技术,如索引利用、内存排序、外部排序等,帮助你提升排序性能。了解其背后的机制,可显著优化查询效率。
34 4
|
1月前
|
SQL 搜索推荐 关系型数据库
MySQL 如何实现 ORDER BY 排序?
在实际开发中,我们经常会使用 MySQL 的 `ORDER BY`进行排序,那么,`ORDER BY`是如何实现的排序的?我们该如何优化 `ORDER BY`的排序性能?这篇文章,我们来聊一聊。
28 3
|
2月前
|
算法 关系型数据库 MySQL
MySQL高级篇——排序、分组、分页优化
排序优化建议、案例验证、范围查询时索引字段选择、filesort调优、双路排序和单路排序、分组优化、带排序的深分页优化
MySQL高级篇——排序、分组、分页优化
|
2月前
|
自然语言处理 关系型数据库 MySQL
match如何在mysql数据库里进行文本的相似度排序?
【9月更文挑战第1天】match如何在mysql数据库里进行文本的相似度排序?
112 1
|
3月前
|
SQL 关系型数据库 MySQL
MySQL】-DQL(基本、条件、分组、排序、分页)详细版
通过这些查询方法,你可以高效地检索、分析和组织MySQL数据库中的数据,以满足各种应用需求。实践中,理解这些SQL语句的基础知识以及它们如何组合起来进行复杂的数据操作是至关重要的。
47 1
|
3月前
|
算法 关系型数据库 MySQL
揭秘MySQL中的版本号排序:这个超级算法将颠覆你的排序世界!
【8月更文挑战第8天】在软件开发与数据管理中,正确排序版本号对软件更新及数据分析至关重要。因MySQL默认按字符串排序版本号,可能出现'1.20.0'在'1.10.0'之前的不合理情况。解决办法是将版本号各部分转换为整数后排序。例如,使用`SUBSTRING_INDEX`和`CAST`函数从`software`表的`version`字段提取并转换版本号,再按这些整数排序。这种方法可确保版本号按逻辑正确排序,适用于'major.minor.patch'格式的版本号。对于更复杂格式,需调整处理逻辑。掌握此技巧可有效应对版本号排序需求。
193 3
|
4月前
|
存储 人工智能 关系型数据库
MySQL 8.0 字符集与比较规则介绍
我们都知道 MySQL 8.0 与 MySQL 5.7 的区别之一就是默认字符集从 latin1 改成了 utf8mb4 ,除此之外,MySQL 8.0 下的字符集和比较规则还有没有其他变化呢?本篇文章我们一起来学习下。
265 1
|
4月前
|
关系型数据库 MySQL 数据库
MySQL设计规约问题之索引的命名规则是什么
MySQL设计规约问题之索引的命名规则是什么
下一篇
无影云桌面