从零开始学Mysql - 字符集和编码(上)(二)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 从零开始学Mysql - 字符集和编码(上)(二)

字符集和比较规则级别介绍



下面到了本文的重点,MySQL 有4个级别的字符集和比较规则,分别是:

  • 服务器级别:启动的时候根据配置或者数据库默认规则生成字符集和比较规则
  • 数据库级别:数据库的系统变量为只读,修改数据库字符集和比较规则需要保证数据兼容。
  • 表级别:表级别比较规则默认跟随数据库,修改字符集同样需要保证数据兼容,否则会报错。
  • 列级别:不建议关注,只需了解即可,通常没有人会去单独改某一列的字符集

当然这些特点只是简单列举,下面会按照实际的案例进行一一阐述。


服务器级别规则


MySQL 提供了两个系统变量来表示服务器级别的字符集和比较规则:

  • Character_set_server:服务器级别的字符集
  • Collation_server:服务器级别的比较规则

下面是具体的案例:


mysql> show variables like 'character_set_server';
character_set_server  utf8mb4
mysql> SHOW VARIABLES LIKE 'collation_server';
collation_server  utf8mb4_0900_ai_ci


可以看到这里是标记为utf8mb4,但是如果这里显示是utf8,其实本质上是utf8mb3。最后可以看到上面服务器级别的字符集为utfmb4,而服务器级别的比较规则为:utf8mb4_0900_ai_ci,不过有些人可能是输出:utf8_general_ci

设置字符集和比较规则:

如果想要设置服务器级别的字符集和比较规则,可以使用如下的方式,上一节关于mysql的系统配置中说过可以设置配置文件的内容如下,注意需要分配到[server]的组下面:


[server]
 character_set_server=gbk
 collation_server=gbk_chinese_ci


数据库级别规则


我们在创建数据库的时候更多的时候使用create database 数据名,但是使用这种语法创建的数据库使用为配置文件配置的字符集和比较规则,下面我们来了解一下如何创建自定义的比较规则和字符集的数据库。

自定义创建数据库字符集和比较规则:

下面是创建自定义数据库级别的字符集和比较规则的语法,当然如果不小心建错了字符集,可以使用alter database来进行修改


create database 数据库名称
  [[DEFAULT] CHARACTER SET 字符集名称]
  [[DEFAULT] COLLATE 比较规则名称];
alter database 数据库名
  [[DEFAULT] CHARACTER SET 字符集名称]
  [[DEFAULT] COLLATE 比较规则名称];


下面为实际的操作案例以及具体的操作效果:


CREATE DATABASE charset_demo_db
         CHARACTER SET gb2312
        COLLATE gb2312_chinese_ci;


网络异常,图片无法展示
|


关于上面的参数[DEFAULT]可以进行忽略,如果我们想要查看当前的数据库比较规则,可以使用下面两个 系统变量进行查看:(前提是使用 USE 语句选择当前默认数据库,如果没有默认数据库,则变量与相应的服务器级别的系统变量具有相同的值)

  • character_set_database:当前数据库字符集
  • Collation_database:当前数据库比较规则

下面为具体的案例:


> 如果没有use database,则会显示下面的内容(个人测试)
character_set_database  utf8mb3
> use charset_demo_db;
> show variables like 'character_set_database';
character_set_database  gb2312
> show variables LIKE 'collation_database';
collation_database  gb2312_chinese_ci


可以看到charset_demo_db使用的还是创建的时候默认的字符集和比较规则,这里有一个需要注意的点是数据库级别的系统变量是只读的,也就意味着character_set_databasecollation_database是只读的,不能修改这两个参数修改字符集和比较规则。但是我们可以使用alter database命令修改数据库的级别。

最后,如果不指定字符集和比较规则,这样的话将使用服务器级别的字符集和比较规则作为数据库的字符集和比较规则。


表级别规则


下面我们来看下表级别的规则,表级别顾名思义就是在创建表的时候我们可以追定字符集和字符的比较规则,具体的命令记忆也就是把数据库换成表而已,这里有读者可能注意到的是不能使用charset替代,只有character set这一个写法:


CREATE TABLE 表名 (列的信息)
[[DEFAULT] CHARACTER SET 字符集名称] [COLLATE 比较规则名称]]
ALTER TABLE 表名
[[DEFAULT] CHARACTER SET 字符集名称] [COLLATE 比较规则名称]


下面我们来看下具体的案例:


create table test(
  id int auto_increment primary key
) character set utf8mb4 
COLLATE utf8mb4_0900_ai_ci


之前说过,如果你在创建表的时候没有制定字符集和比较规则,默认会使用所在数据库的字符集和比较规则,这个规则比较好理解,因为你在哪个地盘构建表用哪个地盘的配置也合情合理。

下面是关于数据表的字符集查看规则的语法:

查看数据表的字符集:show table status from '数据库名称' like '数据表名称';

除此之外,还有一种方法:SELECT TABLE_SCHEMA, TABLE_NAME,TABLE_COLLATION FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME = '数据表名称',通过这样的sql也可以推断出具体的字符集。


> show table status from bank like 'admin';
admin InnoDB  10  Dynamic 0 0 16384 0 0 0 1 2021-11-21 09:23:52     utf8_general_ci   
> use bank;
> SELECT TABLE_SCHEMA, TABLE_NAME,TABLE_COLLATION FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'status';
TABLE_SCHEMA  TABLE_NAME    TABLE_COLLATION
bank          status        utf8_general_ci


这里将数据库bank里面的admin表拿出来看了一下,可以看到具体的比较规则是utf8_general_ci,所以可以肯定字符集是utf8。(注意不是utf8mb4)


列级别规则


列级别规则我相信也没有多少人会去关注,在同一个表中其实是可以存在多个字符集和比较规则的,如果我们想要在列中指定字符集,可以使用如下的语法:


CREATE TABLE 表名(
  列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称], 其他列...
);


如果想要修改某一个列的字符集或者比较规则,使用如下的语法:


ALTER TABLE 表名 MODIFY 列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称];


下面是一个案例:


ALTER TABLE t MODIFY col VARCHAR(10) CHARACTER SET gbk COLLATE gbk_chinese_ci;


最后提醒一遍,尽量保持一张表使用同一个字符集,不然很有可能出现各种莫名其妙的问题,比如你如果不小心把汉字存放在不支持的字符集,就会出现乱码的情况。另外,如果列没有指定字符集,毫无疑问会使用表所在的字符集和比较规则

补充:在转换列的字符集时需要注意,如果转换前列中存储的数据不能用转换后的字符集进行表示会发生错误,就好比上面说的汉字存储在不兼容的字符集的时候就会出现报错。

最后是查看列的字符集:

show full columns from '表名称' like '列名';


字符集和比较规则的联动


我们在使用navicat创建字符集的时候,会有一种切换的效果,就是我们选择某一个字符集之后就会出现对应的比较规则,但是如果我们选择比较规则再选字符集,这么做是行不通滴,为了验证我们来看下面对应的截图内容:

选择比较规则再选字符集:


网络异常,图片无法展示
|


选择字符集再选择比较规则:


网络异常,图片无法展示
|


所以,关于字符集和比较规则的变更规则如下(适用于所有级别的字符集和比较规则):

  • 只修改字符集,比较规则会变更为变更之后的字符集默认的比较规则
  • 只修改比较规则,字符集变为修改比较规则之后的字符集


各级别字符集和比较规则小结


下面我们来看下从启动服务器开始我们创建字符集和比较规则的默认规则是什么,注意这里前提是 创建的时候没有显式指定字符集和比较规则

  • 列默认会使用表的字符集和比较规则。
  • 表默认使用数据库的字符集和比较规则。
  • 数据库默认使用当前启动服务器指定的字符集和比较规则。

通过这样的规则,我们很容易推测出一个某一个列中的字段数据占多少节。

最后,介绍这些规则并不是说需要记忆,因为多数情况你会使用服务器甚至数据库的规则代替一切的默认规则。


总结


为了更好的了解这一篇文章关于四个级别的总结,我做了下面的一个表来帮助自己复习和回顾:


数据库级别 查看字符集 查看比较规则 系统变量 修改/创建方式 案例
服务器级别 show variables like 'character_set_server'; SHOW VARIABLES LIKE 'collation_server' character_set_server
:当前服务器比较规则collation_server:当前服务器比较规则
修改配置文件
[server]
character_set_server=gbk
collation_server=gbk_chinese_ci
CREATE DATABASE charset_demo_db
CHARACTER SET gb2312
COLLATE gb2312_chinese_ci;
数据库级别 show variables like 'character_set_database'; show variables LIKE 'collation_database'; character_set_database:当前数据库字符集 Collation_database:当前数据库比较规则 alter database 数据库名
[[DEFAULT] CHARACTER SET 字符集名称]
[[DEFAULT] COLLATE 比较规则名称];
CREATE DATABASE charset_demo_db
CHARACTER SET gb2312
COLLATE gb2312_chinese_ci;
表级别 show table status from '数据库名称' like '数据表名称' SELECT TABLE_SCHEMA, TABLE_NAME,TABLE_COLLATION FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME = '数据表名称' 未设置情况下默认参考数据库的级别设置 CREATE TABLE 表名 (列的信息)
[[DEFAULT] CHARACTER SET 字符集名称] [COLLATE 比较规则名称]]

ALTER TABLE 表名
[[DEFAULT] CHARACTER SET 字符集名称] [COLLATE 比较规则名称]
create table test(
id int auto_increment primary key
) character set utf8mb4
COLLATE utf8mb4_0900_ai_ci
列级别 show full columns from admin like 'username'; show full columns from admin like 'username'; 未设置情况下默认参考数据表的级别设置 CREATE TABLE 表名(
列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称], 其他列...
);
ALTER TABLE t MODIFY col VARCHAR(10) CHARACTER SET gbk COLLATE gbk_chinese_ci;


问答题



为什么mysql的utfmb3和utf8mb4两个编码?


在非常早期的时候,Unicode 只用到了 0~0xFFFF 范围的数字编码,这就是 BMP 字符集。所以,最初MySQL在设计之初,也就只涉及了包含BMP 字符集的utfmb3(utf-8),但是随着文字越来越多,3个字节肯定无法全部表示,于是Unicode支持的字符就更多了。所以在最后我们可以对于mysql的unicode做如下区分:

  • utf8mb3 :阉割过的 utf8 字符集,只使用1~3个字节表示字符。
  • utf8mb4 :正宗的 utf8 字符集,使用1~4个字节表示字符


写在最后


如果对于内容有疑问或者有错误欢迎指出,个人也将会不断的吸取教训并改进。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4月前
|
关系型数据库 MySQL 存储
【MySQL】——数据类型及字符集
【MySQL】——数据类型及字符集
【MySQL】——数据类型及字符集
|
4月前
|
SQL 关系型数据库 MySQL
【MySQL】— —熟练掌握用SQL语句实现数据库和基本表的创建。熟练掌握MySQL的安装、客户端登录方法;熟练掌握MySQL的编码、数据类型等基础知识;掌握实体完整性的定义和维护方法、掌握参照完整性
【MySQL】— —熟练掌握用SQL语句实现数据库和基本表的创建。熟练掌握MySQL的安装、客户端登录方法;熟练掌握MySQL的编码、数据类型等基础知识;掌握实体完整性的定义和维护方法、掌握参照完整性
|
4月前
|
存储 人工智能 搜索推荐
详解MySQL字符集和Collation
MySQL支持了很多Charset与Collation,并且允许用户在连接、Server、库、表、列、字面量多个层次上进行精细化配置,这有时会让用户眼花缭乱。本文对相关概念、语法、系统变量、影响范围都进行了详细介绍,并且列举了有可能让字符串发生字符集转换的情况,以及来自不同字符集的字符串进行比较等操作时遵循的规则。对于最常用的基于Unicode的字符集,本文介绍了Unicode标准与MySQL中各个字符集的关系,尤其详细介绍了当前版本(8.0.34)默认字符集utf8mb4。
|
2月前
|
存储 人工智能 关系型数据库
MySQL 8.0 字符集与比较规则介绍
我们都知道 MySQL 8.0 与 MySQL 5.7 的区别之一就是默认字符集从 latin1 改成了 utf8mb4 ,除此之外,MySQL 8.0 下的字符集和比较规则还有没有其他变化呢?本篇文章我们一起来学习下。
78 1
|
3月前
|
存储 自然语言处理 关系型数据库
|
4月前
|
存储 关系型数据库 MySQL
MySQL各字符集、排序规则的由来、用法,区别和联系
MySQL支持多种字符集和排序规则,这些在数据库设计和数据处理中起着重要作用。下面是它们的由来、用法、区别和联系: 1. **字符集(Character Set)**: - **由来**:字符集定义了数据库中可以存储的字符集合,以及这些字符在数据库中的存储方式。 - **用法**:在创建数据库或表时,可以指定所需的字符集。常见的字符集包括UTF-8、UTF-16、Latin1等。 - **区别和联系**:不同的字符集支持不同的字符范围和存储方式,选择合适的字符集可以确保数据的正确存储和处理。例如,UTF-8支持全球范围内的大多数字符,而Latin1只支持西欧语言字符集。
|
4月前
|
存储 数据可视化 关系型数据库
Mysql字符集
Mysql字符集
|
4月前
|
存储 SQL 关系型数据库
详解MySQL字符集和Collation
详解MySQL字符集和Collation
344 2
|
4月前
|
关系型数据库 MySQL Shell
Windows下的mysql字符集格式修改
在Windows上的MySQL 5.7.17,若安装时未设置字符集,可能导致乱码问题。本文提供了解决方案:首先,通过`mysql -uroot -p`登录并使用`show variables like '%char%';`查看当前字符集。然后,有两种修改方法:一是使用Shell命令临时修改9个相关属性为utf8;二是永久修改,在my.ini配置文件中将[mysqld]、[client]、[mysql]下的字符集改为utf8。记得重启MySQL服务以应用更改。此外,还提供了修改数据库和表字符集的SQL命令。
|
4月前
|
存储 关系型数据库 MySQL
【2024】新建mysql数据库,如何选择字符集和排序规则
【2024】新建mysql数据库,如何选择字符集和排序规则
455 1

热门文章

最新文章