首页 > 数据库 >MySQL的字符集配置

MySQL的字符集配置

时间:2022-12-15 10:05:01浏览次数:67  
标签:ci set utf8mb4 字符集 配置 character general MySQL

 

 

utf8的锅:

场景 : 之前在给客户做微商城时,需要保存微信的授权信息,此时就有一个nickname字段,在设计数据表时,潜意识的将表的存储格式设置为utf8,生产上线一段时间后偶尔出现保存异常。经分析,出现异常的原因是:用户nickname中有email表情符号。utf8格式的数据表存储不下导致。

经验提示: 在设计数据表时,一定要注意该字段存储的内容,如果允许设置表情emoj,则一定不能使用utf8,而是使用utf8mb4

 

 

alter database apple default character set = 'utf8mb4';
alter table iphone convert to character set utf8mb4;

 

 

# 字符集字符序问题:

character-set-server/default-character-set:服务器字符集,默认情况下所采用的。
character-set-database:数据库字符集。
character-set-table:数据库表字符集。

# 优先级依次增加。所以一般情况下只需要设置character-set-server,而在创建数据库和表时不特别指定字符集,这样统一采用character-set-server字符集。
character-set-client:客户端的字符集。客户端默认字符集。当客户端向服务器发送请求时,请求以该字符集进行编码。
character-set-results:结果字符集。服务器向客户端返回结果或者信息时,结果以该字符集进行编码。

在客户端,如果没有定义character-set-results,则采用character-set-client字符集作为默认的字符集。所以只需要设置character-set-client字符集。

最佳方案:

server字符集=数据库字符集=表字符集=会话字符集=客户端显示字符集

 

MySQL在 5.5.3 之后增加了 utf8mb4 字符编码,mb4即 most bytes 4。简单说 utf8mb4 是 utf8 的超集并完全兼容utf8,能够用四个字节存储更多的字符。

而utf8 是 utf8mb3 的别名。标准的 UTF-8 字符集编码是可以用 1~4 个字节去编码21位字符,但是MySQL其实实现的utf8只是使用3个字节而已, ​​utf8mb4才是真正意义上的 utf8​​。

如果数据库表字段设置的字符集不是utf8mb4,却插入类似emjoy表情的时候:

  • 严格模式 下会出现 Incorrect string value: /xF0/xA1/x8B/xBE/xE5/xA2… for column 'name' 这样的错误
  • 非严格模式下此后的数据会被截断

排序字符集

Refer to: ​​Collation Naming Conventions​

Suffix

Meaning

Remark

_ai

Accent insensitive

 

_as

Accent sensitive

 

_ci

Case insensitive

不分区大小写

_cs

case-sensitive

区分大小写

_bin

Binary

二进制存储,区分大小写

utf8mb4_ unicode_ ci VS utf8mb4_ general_ ci

Refer to: ​​What's the difference between utf8_general_ci and utf8_unicode_ci

  • utf8_general_ci校对速度快,但准确度稍差。
  • utf8_unicode_ci准确度高,但校对速度稍慢。

数据库一般默认选择 ​​utf8mb4_general_ci​​​ ;
如果你的应用有德语、法语或者俄语,请一定使用​​​utf8mb4_unicode_ci​

配置

vim /etc/my.cnf
[client] 
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
# character-set-client-handshake = FALSE
character-set-server = utf8mb4

collation-server = utf8mb4_general_ci

init_connect='SET NAMES utf8mb4'

 

检查目前MySQL的字符集

tj1-using-glc-db01.kscn((none)) > SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
+--------------------------+--------------------+
| Variable_name | Value |
+--------------------------+--------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| collation_connection | utf8mb4_general_ci |
| collation_database | utf8mb4_general_ci |
| collation_server | utf8mb4_general_ci |
+--------------------------+--------------------+
10 rows in set (0.01 sec)

Fri Aug 28 17:51:07 2020

 

总结

  • mysql 版本 5.5.3+
  • MySQL Connector/J Java驱动5.1.13+
  • /etc/my.cnf 配置中 添加配置,详见上面
  • 排序字符集选用 utf8mb4_unicode_ci
  • 列(字段)> 表 > 数据库

备注:
其实只要数据库支持utfbmb4(show char set),及时MySQL配置(/etc/my.cnf)中配置的默认字符集是utf8,也可以直接指定数据库、表、字段的字符集为utf8mb4,然后在连接的时候指定字符集为utf8mb4即可。
比如设置Java的连接参数中​​​characterEncoding=utf8mb4​

查看MySQL支持的字符集列表:

tj1-using-glc-db01.kscn((none)) > show char set;
+----------+---------------------------------+---------------------+--------+
| Charset | Description | Default collation | Maxlen |
+----------+---------------------------------+---------------------+--------+
| big5 | Big5 Traditional Chinese | big5_chinese_ci | 2 |
| dec8 | DEC West European | dec8_swedish_ci | 1 |
| cp850 | DOS West European | cp850_general_ci | 1 |
| hp8 | HP West European | hp8_english_ci | 1 |
| koi8r | KOI8-R Relcom Russian | koi8r_general_ci | 1 |
| latin1 | cp1252 West European | latin1_swedish_ci | 1 |
| latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 |
| swe7 | 7bit Swedish | swe7_swedish_ci | 1 |
| ascii | US ASCII | ascii_general_ci | 1 |
| ujis | EUC-JP Japanese | ujis_japanese_ci | 3 |
| sjis | Shift-JIS Japanese | sjis_japanese_ci | 2 |
| hebrew | ISO 8859-8 Hebrew | hebrew_general_ci | 1 |
| tis620 | TIS620 Thai | tis620_thai_ci | 1 |
| euckr | EUC-KR Korean | euckr_korean_ci | 2 |
| koi8u | KOI8-U Ukrainian | koi8u_general_ci | 1 |
| gb2312 | GB2312 Simplified Chinese | gb2312_chinese_ci | 2 |
| greek | ISO 8859-7 Greek | greek_general_ci | 1 |
| cp1250 | Windows Central European | cp1250_general_ci | 1 |
| gbk | GBK Simplified Chinese | gbk_chinese_ci | 2 |
| latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 |
| armscii8 | ARMSCII-8 Armenian | armscii8_general_ci | 1 |
| utf8 | UTF-8 Unicode | utf8_general_ci | 3 |
| ucs2 | UCS-2 Unicode | ucs2_general_ci | 2 |
| cp866 | DOS Russian | cp866_general_ci | 1 |
| keybcs2 | DOS Kamenicky Czech-Slovak | keybcs2_general_ci | 1 |
| macce | Mac Central European | macce_general_ci | 1 |
| macroman | Mac West European | macroman_general_ci | 1 |
| cp852 | DOS Central European | cp852_general_ci | 1 |
| latin7 | ISO 8859-13 Baltic | latin7_general_ci | 1 |
| utf8mb4 | UTF-8 Unicode | utf8mb4_general_ci | 4 |
| cp1251 | Windows Cyrillic | cp1251_general_ci | 1 |
| utf16 | UTF-16 Unicode | utf16_general_ci | 4 |
| utf16le | UTF-16LE Unicode | utf16le_general_ci | 4 |
| cp1256 | Windows Arabic | cp1256_general_ci | 1 |
| cp1257 | Windows Baltic | cp1257_general_ci | 1 |
| utf32 | UTF-32 Unicode | utf32_general_ci | 4 |
| binary | Binary pseudo charset | binary | 1 |
| geostd8 | GEOSTD8 Georgian | geostd8_general_ci | 1 |
| cp932 | SJIS for Windows Japanese | cp932_japanese_ci | 2 |
| eucjpms | UJIS for Windows Japanese | eucjpms_japanese_ci | 3 |
| gb18030 | China National Standard GB18030 | gb18030_chinese_ci | 4 |
+----------+---------------------------------+---------------------+--------+
41 rows in set (0.01 sec)

Fri Aug 28 17:50:06 2020

 

 

建议

数据库在设置字符集的时候,设置成​​utf8mb4​​格式!

 

字符集转化

 ###########################################################################

 

​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.-

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

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

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

ucs2
utf16
utf16le
utf32

 3.-

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

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

 4.-

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

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

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

 

 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.-

  • ​utf8mb4​​​MySQL 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_results​​​和​​character_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

然后使用默认字符集启动客户端 ​​utf8mb4​​:

mysql --default-character-set=utf8mb4

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

mysql> SHOW VARIABLES LIKE 'char%';
+--------------------------+----------------------------------------+
| Variable_name | Value |
+--------------------------+----------------

标签:ci,set,utf8mb4,字符集,配置,character,general,MySQL
From: https://blog.51cto.com/u_13912516/5938620

相关文章

  • 018-DNS解析过程与配置DNS服务
     在开始之前,有必要把域名及dns的相关概念解释一下。域名是什么举个例子,https://www.baidu.com,这个其实并不是域名,其中https是指协议,去掉https后,www.baidu.com.(注意最......
  • mysql参数配置文件
    (1)参数配置文件中的内容以键值对形式存在。(2)如何查看键值对?showvariableslike'%name%';或者查看information_schema库下的global_variables视图; 如何修改呢?  1、innod......
  • golang.mysql
    一、mysql操作基本语法1、创建名称nulige的数据库 ​​CREATEDATABASEnuligeDEFAULTCHARSETutf8COLLATEutf8_general_ci;<br><br>usenulige​​2、建表,Id自增​​c......
  • uniapp打包配置注意事项
    1.使用原生安卓api要在app权限配置中勾选对应功能  2.打包前要在app模块配置中勾选对应模块 ......
  • maven安装和配置
    下载链接链接:https://pan.baidu.com/s/1YBRYbIK9Y5i0Vgr5vBSb8w提取码:p3kr文件解压后放到指定目录  D:\ProgramFiles\maven\apache-maven-3.8.4  ......
  • Ansible 服务器主机配置
    使用ansible来对远程主机进行部署的话。我们需要首先对远程注解进行配置。配置文件路径配置文件位于:/etc/ansible/hosts 路径下面。可以使用vi工具进行打开。配置......
  • 9. 静态配置网卡IP,centos/ubuntu实现
    centos7.9网卡配置静态IP[root@centos7network-scripts]#catifcfg-eth0DEVICE=eth0NAME=eth0BOOTPROTO=staticIPADDR=192.168.100.11PREFIX=24GATEWAY=192.168.10......
  • MySQL锁
       分类 MySQL中的锁,按照锁的粒度分,分为以下三类: 全局锁:锁定数据库中的所有表。表级锁:每次操作锁住整张表。行级锁:每次操作锁住对应的行数据。全局锁全局......
  • Nacos-配置管理,分布式,微服务,集群部署
    Nacos-配置管理目录Nacos-配置管理4Nacos配置管理基础应用4.1Nacos配置管理模型4.2命名空间管理4.2.1namespace隔离设计4.2.2命名空间管理4.3配置管理4.2.1配置......
  • VLAN over bond 正确配置
    今天临下班的时候别组的同事同步过来一个case,客户的vm有一台网络不通。caseinfo:长话短说,已知vlantag和网卡绑定配置如下:[root@VM-48-21~]#vconfigaddteam1192[ro......