character_set_server 
collation_server
character_set_database
collation_database

character_set_client
character_set_results

character_set_connection <===character_set_client
collation_connection

skip-character-set-client-handshake

client (character_set_client) -----> character_set_connection -------> mysqld  ------> client(character_set_results)

存在三次编码转换过程:

1)mysql client 使用 character_set_client编码的字符------> character_set_connection 编码字符

------> mysqld :这里需要从 character_set_connection 编码格式二进制流解码成 字符,然后使用 character_set_server/character_set_database 对字符进行再次编码,生成二进制流,存储时,就是存储再次编码的二进制流数据。

2)读取数据时,会使用 character_set_server/character_set_database 对读取到的二级制流进行 解码成 字符,然后使用 character_set_results 对字符进行二次编码,生成二进制流,发给 mysql client.

所以 使用 set names 'xxx' 命令,结合 character_set_server 参数,可以将 整个过程的 字符集设置成相同的,就不会存在编码转换的过程。

1.-

2.-

  在处理客户端和服务器之间的连接的流量时涉及附加的字符集和校对系统变量。

  每个客户端都有特定于会话的连接相关字符集和校对系统变量。

  这些会话系统变量值在连接时初始化,但可以在会话中更改。

3.-

  • 服务器收到语句后应该将语句翻译成什么字符集?

    要确定这一点,服务器使用 character_set_connection 和collation_connection 系统变量:

4.-

  • 在将查询结果发送回客户端之前,服务器应该将哪些字符集转换为结果?

  character_set_results 系统变量指示在其中服务器查询结果返回到客户端的字符集。这包括结果数据,如列值,结果元数据(如列名称)和错误消息。

  要告诉服务器不执行结果集或错误消息的转换,请设置 character_set_results为 NULLbinary

5.-

  • 要查看适用于当前会话的字符集和排序规则系统变量的值,请使用以下语句:
 
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;

6.-

  • C应用程序可以mysql_options()在连接到服务器之前通过以下方式调用,根据操作系统设置使用字符集自动检测 :

    mysql_options(mysql,
    MYSQL_SET_CHARSET_NAME,
    MYSQL_AUTODETECT_CHARSET_NAME);
  • 每个客户端都支持一个 --default-character-set 选项,该选项允许用户显式指定字符集以覆盖客户端否则确定的任何默认值。

7.-

  • 使用mysql客户端,要使用与默认值不同的字符集,SET NAMES每次连接到服务器时都可以显式执行 语句(请参阅客户端程序连接字符集配置)。要更轻松地完成相同的结果,请在选项文件中指定字符集。例如,以下选项文件设置更改koi8r每次调用mysql时设置的三个与连接相关的字符集系统变量:

    [mysql]
    default-character-set=koi8r 8.-
  • 如果您正在使用启用了自动重新连接的mysql客户端(不建议这样做),则最好使用charset命令而不是SET NAMES。例如:
  mysql> charset koi8r
  Charset changed

    该charset命令发出一个 SET NAMES语句,并且还更改mysql 在连接断开后重新连接时使用的默认字符集。

    配置客户端程序时,还必须考虑它们执行的环境。请参见 第10.5节“配置应用程序字符集和排序规则”

9.-

    SET character_set_client = charset_name;
    SET character_set_results = charset_name;
    SET character_set_connection = charset_name;

10.-

  • SET CHARACTER SET 'charset_name' 一个语句相当于这三个语句:
    SET character_set_client = charset_name;
    SET character_set_results = charset_name;
    SET collation_connection = @@collation_database;

11.-

  • utf8mb4MySQL 5.7和8.0之间 的默认排序规则不同(utf8mb4_general_ci对于5.7,utf8mb4_0900_ai_ci对于8.0)。

  • 当8.0客户端请求一个字符集时 utf8mb4,它发送给服务器的是默认的8.0 utf8mb4排序规则; 也就是说utf8mb4_0900_ai_ci

  • utf8mb4_0900_ai_ci 仅在MySQL 8.0中实现,因此5.7服务器无法识别它。

  • 由于5.7服务器无法识别 utf8mb4_0900_ai_ci,因此无法满足客户端字符集请求,并回退到其默认字符集和排序规则(latin1和 latin1_swedish_ci)。

在这种情况下,客户端仍然可以在连接后utf8mb4通过发出SET NAMES 'utf8mb4'语句来使用 。得到的排序规则是5.7默认utf8mb4 排序规则; 就是这样utf8mb4_general_ci。如果客户端另外需要进行整理utf8mb4_0900_ai_ci,则无法实现该目标,因为服务器无法识别该整理。客户端必须愿意使用不同的 utf8mb4排序规则,或者从MySQL 8.0或更高版本连接到服务器。

12.-

在MySQL 4.0版中, 服务器和客户端都有一个“ 全局 ”字符集,并决定服务器管理员使用哪个字符。这从MySQL 4.1版开始改变。现在发生的是“ 握手 ”,如 第10.4节“连接字符集和排序规则”中所述

当客户端连接时,它会向服务器发送它要使用的字符集的名称。服务器使用的名称,设置 character_set_client, character_set_resultscharacter_set_connection 系统变量。实际上,服务器SET NAMES使用字符集名称执行 操作。

这样做的效果是你无法控制的客户端字符由开始设定的mysqld用 --character-set-server=utf8。但是,一些亚洲客户更喜欢MySQL 4.0的行为。为了能够保留这种行为,我们添加了一个 mysqld开关, --character-set-client-handshake可以关闭它 --skip-character-set-client-handshake。如果启动mysqld的使用 --skip-character-set-client-handshake,那么,当客户端连接时,它发送的字符集的名称,它希望使用的服务器。但是,服务器会忽略来自客户端的此请求

举例来说,假设您最喜欢的服务器字符集是latin1(不太可能在CJK区域,但这是默认值)。进一步假设客户端使用, utf8因为这是客户端操作系统支持的内容。现在,使用latin1默认字符集启动服务器 :

mysqld --character-set-server=latin1

然后使用默认字符集启动客户端 utf8

mysql --default-character-set=utf8

通过查看以下输出可以看到生成的设置 SHOW VARIABLES

mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql/share/mysql/charsets/ |
+--------------------------+----------------------------------------+

现在停止客户端,并使用mysqladmin停止服务器 。然后再次启动服务器,但这次告诉它跳过这样的握手:

mysqld --character-set-server=utf8 --skip-character-set-client-handshake

utf8再次 启动客户端作为默认字符集,然后显示结果设置:

mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------------------+
| Variable_name | Value |
+--------------------------+----------------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql/share/mysql/charsets/ |
+--------------------------+----------------------------------------+

通过比较不同的结果可以看出, SHOW VARIABLES如果使用该--skip-character-set-client-handshake 选项,服务器将忽略客户端的初始设置 。

参考: https://dev.mysql.com/doc/refman/8.0/en/faqs-cjk.html

A.11 MySQL 8.0 FAQ:MySQL中文,日文和韩文字符集

MySQL: Connection Character Sets and Collations的更多相关文章

  1. 10.1.5 Connection Character Sets and Collations

    10.1.5 Connection Character Sets and Collations Several character set and collation system variables ...

  2. Firebird Character Sets and Collations

    Firebird Character Sets and Collations Every CHAR or VARCHAR field can (or, better: must) have a cha ...

  3. 彻底解决phpcms v9升级后,文章发布出现: Mysql 1267错误:MySQL Error : Illegal mix of collations 解决办法

    彻底解决phpcms v9升级后,文章发布出现: MySQL Query : SELECT * FROM `withli_a`.`v9_keyword` WHERE `keyword` = '吼吼' ...

  4. 3个问题:MySQL 中 character set 与 collation 的理解;utf8_general_ci 与 utf8_unicode_ci 区别;uft8mb4 默认collation:utf8mb4_0900_ai_ci 的含义

    MySQL 中 character set 与 collation 的理解 出处:https://www.cnblogs.com/EasonJim/p/8128196.html 推荐: 编码使用 uf ...

  5. 02:PostgreSQL Character Sets

    在利用postGIS导入shapefile文件到postgresql数据库的时候,老是提示字符串的问题,或者是乱码,试了好几种都不行,于是度娘之.... 使用默认的UTF8,提示信息是:建议使用LAT ...

  6. MySQL Error: Illegal mix of collations for operation 'concat'

    在使用concat连接字符串时出现错误:MySQL Error: Illegal mix of collations for operation 'concat' 原因:字段操作默认为UTF8的编码, ...

  7. MySQL基础知识:MySQL Connection和Session

    在connection的生命里,会一直有一个user thread(以及user thread对应的THD)陪伴它. Connection和Session概念 来自Stackoverflow的一个回答 ...

  8. Character Sets: Migrating to utf8mb4 with pt_online_schema_change

    David Berube  | June 12, 2018 |  Posted In: MySQL Modern applications often feature the use of data ...

  9. mysql connection refused

    mysql数据库认证的时候和别的服务器不一样,即使mysqld数据库服务器没有启动,使用mysql这种客户端程序去连接,也要先输入密码,从而使人有一种错觉,以会服务器已经正常启动了.是不是密码或是主机 ...

随机推荐

  1. TensorFlow的梯度裁剪

    在较深的网络,如多层CNN或者非常长的RNN,由于求导的链式法则,有可能会出现梯度消失(Gradient Vanishing)或梯度爆炸(Gradient Exploding )的问题. 原理 问题: ...

  2. linux-程序发布脚本

    写了个启动程序, 调优jvm的脚本 #!/bin/bash MEM=`free -m | grep Mem | awk '{print int($2 * 90 / 100)}'` JAVA_OPTS= ...

  3. linux开机自启动设置,自定义开机启动模版,nginx开机自启动服务

    /etc/init.d 目录,我们把shell脚本放在这个目录下来作为启动脚本 都是用来放服务脚本的,当Linux启动时,会寻找这些目录中的服务脚本,并根据脚本的run level确定不同的启动级别. ...

  4. 代码统计工具cloc

    https://sourceforge.net/projects/cloc/files/cloc/v1.64/

  5. CSS学习笔记03 CSS层叠性、继承性、特殊性

    层叠性 所谓层叠性是指多种CSS样式的叠加,也就是说后面设置的样式会层叠(覆盖)之前的样式,层叠性的前提是CSS的选择器的优先级相同,例如,当使用内嵌式CSS样式表定义<p>标记字号大小为 ...

  6. SpringBoot整合SpringData JPA入门到入坟

    首先创建一个SpringBoot项目,目录结构如下: 在pom.xml中添加jpa依赖,其它所需依赖自行添加 <dependency> <groupId>org.springf ...

  7. MySQL锁详解!(转载)

    博客来源于https://baijiahao.baidu.com/s?id=1610581108528334819&wfr=spider&for=pc 一.概述 数据库锁定机制简单来说 ...

  8. 基于std::mutex std::lock_guard std::condition_variable 和std::async实现的简单同步队列

    C++多线程编程中通常会对共享的数据进行写保护,以防止多线程在对共享数据成员进行读写时造成资源争抢导致程序出现未定义的行为.通常的做法是在修改共享数据成员的时候进行加锁--mutex.在使用锁的时候通 ...

  9. C++基于范围的for循环性能测试(针对std::vector)

    1.代码如下: void output1(int x){ if (x == 10000000) { std::cout << x << std::endl; } }const ...

  10. 用MSBuild和Jenkins搭建持续集成环境(1)[收集]

    你或其他人刚刚写完了一段代码,提交到项目的版本仓库里面.但等一下,如果新提交的代码把构建搞坏了怎么办?万一出现编译错误,或者有的测试失败了,或者代码不符合质量标准所要求的底限,你该怎么办? 最不靠谱的 ...