MySQL原理 - 字符集与排序规则(下)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL原理 - 字符集与排序规则(下)

库级别


创建数据库的时候,可以指定字符集还有排序规则。


mysql> create database test_db character set utf8mb4 collate utf8mb4_general_ci;
Query OK, 1 row affected (0.01 sec)


不指定的话,就用实例级别的字符集还有排序规则。


查看当前数据库的字符集还有排序规则则是通过use命令指定数据库之后,查看character_set_database变量以及collation_database来实现:


mysql> show variables like 'character_set_database';
+------------------------+---------+
| Variable_name          | Value   |
+------------------------+---------+
| character_set_database | utf8mb4 |
+------------------------+---------+
1 row in set (0.07 sec)
mysql> show variables like 'collation_database';
+--------------------+--------------------+
| Variable_name      | Value              |
+--------------------+--------------------+
| collation_database | utf8mb4_general_ci |
+--------------------+--------------------+
1 row in set (0.09 sec)


就算设置这两个变量,也是无效的:


mysql> set character_set_database = 'utf8';
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like 'character_set_database';
+------------------------+---------+
| Variable_name          | Value   |
+------------------------+---------+
| character_set_database | utf8mb4 |
+------------------------+---------+
1 row in set (0.09 sec)


修改数据库的字符集还有排序规则的方式:


mysql> alter database test_db character set = 'utf8';
Query OK, 1 row affected (0.01 sec)
mysql> show variables like 'character_set_database';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| character_set_database | utf8  |
+------------------------+-------+
1 row in set (0.08 sec)


这个更新只会对新建的表如果没指定字符集和排序规则的生效,并不会更新老表的字符集还有排序规则。


表级别


可以在创建时指定字符集合排序规则,不指定的话,用数据库的字符集还有排序规则,也可以修改字符集和排序规则。


mysql> create table test (name varchar(32)) character set utf8mb4 collate utf8mb4_bin; 
Query OK, 0 rows affected (0.04 sec)
mysql> show create table test;
+-------+---------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                          |
+-------+---------------------------------------------------------------------------------------------------------------------------------------+
| test  | CREATE TABLE `test` (
  `name` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |
+-------+---------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.09 sec)
mysql> alter table test character set = 'utf8';
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> show create table test;
+-------+--------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                         |
+-------+--------------------------------------------------------------------------------------------------------------------------------------+
| test  | CREATE TABLE `test` (
  `name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.06 sec)

可以看出,仅仅是表的字符集还有排序规则变了,对于已有字段,并没有改变编码和排序规则。


列级别


可以在创建表的时候,指定不同的列有不同的字符集和排序规则,也可以修改列的字符集和排序规则:


mysql> create table test (name varchar(32) character set utf8 collate utf8_bin) character set utf8mb4 collate utf8mb4_bin; 
Query OK, 0 rows affected (0.03 sec)
mysql> show create table test;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                          |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
| test  | CREATE TABLE `test` (
  `name` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.09 sec)
mysql> alter table test modify column name  varchar(32) COLLATE latin1_bin;
Query OK, 0 rows affected (0.09 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> show create table test;
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                              |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
| test  | CREATE TABLE `test` (
  `name` varchar(32) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.09 sec)


MySQL客户端字符编码问题


有时候,我们会遇到字符编码不一致导致的程序问题。例如我们的 Java 程序,使用 jdbc 链接。读取的数据,打印出来是乱码。或者是,MySQL 无法识别我们客户端发来的命令。这涉及到字符编码问题。我们需要保持 Java 程序的字符编码与 JDBC 链接指定的字符编码一致,这样才不会有乱码的问题。


**指定 Java 程序编码:**通过启动参数:-Dfile.encoding=UTF-8 设置默认的字符编码(java.nio.charset.Charset.defaultCharset();)是utf-8(对应 MySQL 的utf8还有utf8mb4)。


指定 JDBC 链接编码:

jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8


mysql客户端命令行指定字符集


mysql -h 127.0.0.1 -P 3306 -u root  --default-character-set=utf8mb4  -p

之后查看有关编码的环境变量,都是和设置的这个字符集一样。


mysql> SHOW VARIABLES LIKE 'character_set_client';
+----------------------+---------+
| Variable_name        | Value   |
+----------------------+---------+
| character_set_client | utf8mb4 |
+----------------------+---------+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW VARIABLES LIKE 'character_set_connection';
+--------------------------+---------+
| Variable_name            | Value   |
+--------------------------+---------+
| character_set_connection | utf8mb4 |
+--------------------------+---------+
1 row in set, 1 warning (0.00 sec)
mysql> SHOW VARIABLES LIKE 'character_set_results';
+-----------------------+---------+
| Variable_name         | Value   |
+-----------------------+---------+
| character_set_results | utf8mb4 |
+-----------------------+---------+
1 row in set, 1 warning (0.00 sec)


其中:

  • character_set_client: 服务器解码请求时使用的字符集
  • character_set_connection:服务器处理请求时将字符集转换成这个字符集处理。操作具体列时,在转换为具体列的编码。
  • character_set_results:服务器向客户端返回数据时使用的字符集

MySQL 设计这三个编码的时候,出于以下考虑:

  • 一个 MySQL,可能有多种不同语言和操作系统或者国家的客户端,所以通过设置character_set_client还有character_set_results进行兼容。
  • 由于操作具体列数据的时候需要编码转换,如果character_set_connection和字段一致的话,就不用转换了,所以设置character_set_connection可以让 MySQL 用一种编码理解命令统一处理,同时设置character_set_connection为最常用的可以减少转换。


一般情况下,保持这三个一致就好。我们就设置好连接使用的字符集就行了。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5天前
|
存储 SQL 关系型数据库
【MySQL】主从同步原理、分库分表
【MySQL】主从同步原理、分库分表
13 0
|
4天前
|
存储 关系型数据库 MySQL
MySQL各字符集、排序规则的由来、用法,区别和联系
MySQL支持多种字符集和排序规则,这些在数据库设计和数据处理中起着重要作用。下面是它们的由来、用法、区别和联系: 1. **字符集(Character Set)**: - **由来**:字符集定义了数据库中可以存储的字符集合,以及这些字符在数据库中的存储方式。 - **用法**:在创建数据库或表时,可以指定所需的字符集。常见的字符集包括UTF-8、UTF-16、Latin1等。 - **区别和联系**:不同的字符集支持不同的字符范围和存储方式,选择合适的字符集可以确保数据的正确存储和处理。例如,UTF-8支持全球范围内的大多数字符,而Latin1只支持西欧语言字符集。
|
5天前
|
存储 算法 关系型数据库
MySQL连接的原理⭐️4种优化连接的手段性能提升240%🚀
MySQL连接的原理⭐️4种优化连接的手段性能提升240%🚀
|
5天前
|
存储 算法 关系型数据库
MySQL怎样处理排序⭐️如何优化需要排序的查询?
MySQL怎样处理排序⭐️如何优化需要排序的查询?
|
5天前
|
SQL 存储 关系型数据库
MySQL查询原理,看这一篇就够了!
MySQL查询原理,看这一篇就够了!
|
5天前
|
SQL 关系型数据库 MySQL
【MySQL】DQL-排序查询-语法&注意事项&可cv例题语句
【MySQL】DQL-排序查询-语法&注意事项&可cv例题语句
|
5天前
|
SQL 关系型数据库 MySQL
【MySQL】DQL-排序查询-语法&排序方式&注意事项&可cv例题语句
【MySQL】DQL-排序查询-语法&排序方式&注意事项&可cv例题语句
|
5天前
|
SQL 关系型数据库 MySQL
【MySQL-8】DQL-查询语句全解 [ 基础/条件/分组/排序/分页查询 ](附带代码演示&案例练习)
【MySQL-8】DQL-查询语句全解 [ 基础/条件/分组/排序/分页查询 ](附带代码演示&案例练习)
|
5天前
|
存储 关系型数据库 MySQL
MySQL 8 索引原理详细分析
了解索引的详细原则,不仅有助于优化,能把索引搞清楚的,面试中优势也会很突显。 关于数据库优化的话题,V哥觉得还有很多地方可以聊,如果你有兴趣,欢迎关注一起讨论。
MySQL 8 索引原理详细分析
|
3天前
|
关系型数据库 MySQL API
实时计算 Flink版产品使用合集之可以通过mysql-cdc动态监听MySQL数据库的数据变动吗
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
20 0

推荐镜像

更多