sql:字符集(ASCII、GB2312、GBK、Unicode和UTF)、Mysql字符集(查看默认字符集和支持的字符集、层次级别、连接字符集、JDBC对连接字符集的影响)

仅为个人学习所用。请支持javaGuide原文。

1.字符集

1.1.ASCII

ASCII 字符集是一套现代美国英语适用的字符集,至今为止共定义了 128 个字符,其中有 33 个控制字符(比如回车、删除)无法显示。

一个 ASCII 码长度是一个字节也就是 8 个 bit。不过最高位是 0 仅仅作为校验位,其余 7 位使用 0 和 1 进行组合,所以,ASCII 字符集可以定义 128(2^7)个字符。

1.2.GB2312

GB2312 字符集是一种对汉字比较友好的字符集,共收录 6700 多个汉字,基本涵盖了绝大部分常用汉字。不过,GB2312 字符集不支持绝大部分的生僻字和繁体字。对于英语字符,GB2312 编码和 ASCII 码是相同的,1 字节编码即可。对于非英字符,需要 2 字节编码。

1.3.GBK

GBK 字符集可以看作是 GB2312 字符集的扩展,兼容 GB2312 字符集,共收录了 20000 多个汉字。

GBK 中 K 是汉语拼音 Kuo Zhan(扩展)中的“Kuo”的首字母。

1.4.Unicode和UTF

Unicode 字符集中包含了世界上几乎所有已知的字符。不过,Unicode 字符集并没有规定如何存储这些字符(也就是如何使用二进制数据表示这些字符)。

然后,就有了 UTF-8(8-bit Unicode Transformation Format)。类似的还有 UTF-16、 UTF-32。

UTF-8 使用 1 到 4 个字节为每个字符编码, UTF-16 使用 2 或 4 个字节为每个字符编码,UTF-32 固定位 4 个字节为每个字符编码。UTF-8 可以根据不同的符号自动选择编码的长短,像英文字符只需要 1 个字节就够了,这一点 ASCII 字符集一样 。

因此,对于英语字符,UTF-8 编码和 ASCII 码是相同的。UTF-32 的规则最简单,不过缺陷也比较明显,对于英文字母这类字符消耗的空间是 UTF-8 的 4 倍之多。UTF-8 是目前使用最广的一种字符编码。

utf8mb4:UTF-8 的完整实现,正版!最多支持使用 4 个字节表示字符,因此,可以用来存储 emoji 符号。

2.Mysql字符集

2.1.默认字符集和查看支持的字符集

可以通过 SHOW CHARSET 命令来查看Mysql支持的字符集,支持 like 和 where 子句。

在 MySQL5.7 中,默认字符集是 latin1 ;在 MySQL8.0 中,默认字符集是 utf8mb4

2.1.层次级别

MySQL 中的字符集有以下的层次级别:

  • server(MySQL 实例级别)
  • database(库级别)
  • table(表级别)
  • column(字段级别)

它们的优先级可以简单的认为是从上往下依次增大,也即 column 的优先级会大于 table 等其余层次的。如指定 MySQL 实例级别字符集是utf8mb4,指定某个表字符集是latin1,那么这个表的所有字段如果不指定的话,编码就是latin1。

2.1.1.server级别的字符集修改

可以通过在启动 mysqld 时指定 --character-set-server 来设置 server 级别的字符集。

mysqld
mysqld --character-set-server=utf8mb4
mysqld --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_0900_ai_ci

也可以在运行时改变 character_set_server 的值,从而达到修改 server 级别的字符集的目的。server级别的字符集还会影响到客户端和服务器之间的连接字符集。

2.1.2.database级别的修改和查看

database 级别的字符集是我们在创建数据库和修改数据库时指定的:

CREATE DATABASE db_name
    [[DEFAULT] CHARACTER SET charset_name]
    [[DEFAULT] COLLATE collation_name]

ALTER DATABASE db_name
    [[DEFAULT] CHARACTER SET charset_name]
    [[DEFAULT] COLLATE collation_name]

可以通过下面的方式查看某个数据库的字符集:

USE db_name;
SELECT @@character_set_database, @@collation_database;
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'db_name';

2.1.3.table级别的修改

CREATE TABLE tbl_name (column_list)
    [[DEFAULT] CHARACTER SET charset_name]
    [COLLATE collation_name]]

ALTER TABLE tbl_name
    [[DEFAULT] CHARACTER SET charset_name]
    [COLLATE collation_name]

2.1.4.column级别的修改

CREATE TABLE t1
(
    col1 VARCHAR(5)
      CHARACTER SET latin1
      COLLATE latin1_german1_ci
);

2.2.连接字符集

连接字符集与下面这几个变量息息相关:

  • character_set_client :描述了客户端发送给服务器的 SQL 语句使用的是什么字符集。
  • character_set_connection :描述了服务器接收到 SQL 语句时使用什么字符集进行翻译。
  • character_set_results :描述了服务器返回给客户端的结果使用的是什么字符集。

查看可通过如下方式:

SELECT * FROM performance_schema.session_variables
WHERE VARIABLE_NAME IN (
'character_set_client', 'character_set_connection',
'character_set_results', 'collation_connection'
) ORDER BY VARIABLE_NAME;
SHOW SESSION VARIABLES LIKE 'character\_set\_%';

修改可通过如下方式:
1、修改配置文件

[mysql]
# 只针对MySQL客户端程序
default-character-set=utf8mb4
set names utf8mb4
# 或者一个个进行修改
# SET character_set_client = utf8mb4;
# SET character_set_results = utf8mb4;
# SET collation_connection = utf8mb4;

2.3.JDBC 对连接字符集的影响

不知道你们有没有碰到过存储 emoji 表情正常,但是使用类似 Navicat 之类的软件的进行查询的时候,发现 emoji 表情变成了问号的情况。这个问题很有可能就是 JDBC 驱动引起的。

根据前面的内容,我们知道连接字符集也是会影响我们存储的数据的,而 JDBC 驱动会影响连接字符集。
mysql-connector-java (JDBC 驱动)主要通过这几个属性影响连接字符集:

  • characterEncoding
  • characterSetResults

以 DataGrip 2023.1.2 来说,在它配置数据源的高级对话框中,可以看到 characterSetResults 的默认值是 utf8 ,在使用 mysql-connector-java 8.0.25 时,连接字符集最后会被设置成 utf8mb3 。那么这种情况下 emoji 表情就会被显示为问号,并且当前版本驱动还不支持把 characterSetResults 设置为 utf8mb4 ,不过换成 mysql-connector-java driver 8.0.29 却是允许的。

你可能感兴趣的:(sql,mysql,数据库)