一文带你了解MySQL字符集和比较规则

目录
  • 1. MySQL中的utf8和utf8mb4
  • 2. MySQL中的比较规则
  • 3. 各级别的字符集和比较规则
    • 3.1 服务器级别
    • 3.2 数据库级别
    • 3.3 表级别
    • 3.4 列级别
  • 4. 修改字符集或比较规则
  • 5. MySQL中的字符集转换过程
  • 总结

1. MySQL中的utf8和utf8mb4

在MySQL中,我经常会看见utf8和utf8mb4这两种编码格式,但是这两种格式我并不了解,一般创建数据库的时候,如果让我选,我默认会选择utf8,但是这个和UTF-8长得最像。

但是实际上,这两种是有区别的。

  • utf8:utf8实际上是utf8mb3的别名,它是割版的UTF-8字符集,只使用1-3字节表示字符。
  • utf8mb4:这个才是正宗的UTF-8字符集,使用1-4字节表示字符。

所以,如果想要在程序中存储emoji表情的话,是需要使用utf8mb4字符集的,因为emoji表情是需要使用4字节编码一个字符。

在MySQL8.0中,已经极大程度优化了utf8mb4字符集的性能,并将其设置为默认字符集

2. MySQL中的比较规则

比较规则是指对于某种字符集来说,制定用来比较字符大小的多种规则,一种字符集多种规则,一个默认规则

在MySQL中,可以通过以下命令查看比较规则

show collation [like 匹配的模式];

这些命名是有规律的。

  • 比较规则的名称与其关联的字符集的名称开头,比如上述比较规则有些以utf8mb3开头
  • 后面紧接着该比较规则所应用的语言。比如utf8mb3_roman_ci表示罗马语的比较规则
  • 名称的后缀意味这该比较规则是否区分语言中的重音、大小写等
后缀 描述
_ai 不区分重音
_as 区分重音
_ci 不区分大小写
_cs 区分大小写
_bin 以二进制方式进行比较

3. 各级别的字符集和比较规则

在MySQL中有四个级别的字符集和比较规则。

  • 服务器级别
  • 数据库级别
  • 表级别
  • 列级别

3.1 服务器级别

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

系统变量 描述
character_set_server 服务器级别的字符集
collation_server 服务器级别的比较规则

可以通过SET语句来改变这两个系统变量。

也可以通过修改配置文件来修改

3.2 数据库级别

在创建和修改数据库时候可以指定数据库的字符集和比较规则

如果想要查看当前数据库的字符集和比较规则,可以查看下面两个系统变量的值

系统变量 描述
character_set_database 当前数据库的字符集
collation_database 当前数据库的比较规则

需要注意的是,这两个系统变量并不同与描述服务器级别的字符集和比较规则的那两个比较规则,这两个系统变量只是用来告诉用户当前数据库的字符集和比较规则是什么,并不能通过修改两个变量的值来修改档期按数据库的字符集和比较规则。

如果在创建数据库的时候不指定字符集和比较规则,那么将会使用服务器级别的字符集和比较规则来作为数据库的字符集和比较规则。

3.3 表级别

可以在创建和修改表的时候指定表的字符集和比较规则

如果创建表的语句没有指定字符集和比较规则,则会使用该表所在数据库的字符集和比较规则作为该表的字符集和比较规则。

3.4 列级别

可以在创建和修改列的时候指定该列的字符集和比较规则

对于某一列来说,如果创建和修改表的语句没有指定字符集和比较规则,则会使用该列所在的表的字符集和比较规则作为其字符集和比较规则。

注意:如果在修改列的字符集的时候,如果存储的数据不能使用修改后的字符集进行表示,则会报错

4. 修改字符集或比较规则

字符集和比较规则之间是相互联系的,只修改其一需要遵循以下规则:

  • 只修改字符集,则比较规则将变为修改后的字符集的默认比较规则。
  • 只修改比较规则,则字符集将变为修改后的比较规则对应的字符集。

5. MySQL中的字符集转换过程

在客户端发送请求的时候,一般来说,客户端编码请求字符串时使用的字符集与操作系统当前使用的字符集一致

但是如果MySQL客户端设置了default-character-set启动选项的时候,那么服务器就会忽视操作系统当前使用的字符集。

而在服务器接收请求的时候,服务器接收到的请求实际上就是一个字节序列。服务器会将这个字节序列看作是使用系统变量character_set_client表示的字符集编码的字节序列。

注意的是,这个系统变量character_set_client是session级别的

客户端发送请求的字符集和服务器接收请求的字符集是两个独立的字符集,一般来说,客户端发送请求所用字符集应和服务器接收请求的字符集应保持一致,但是也会出现不一致的时候

如果服务器的character_set_client对应的字符集不能解释请求的字节序列,那么服务器就会发出警告

在服务器处理请求的时候,会将服务器接收请求的character_set_client对应的字符集进行编码的字节序列转换成session级别的系统变量character_set_connection对应的字符集进行编码的字节序列。

对于character_set_connection我们可以通过SET命令单独修改此系统变量,除了character_set_connection,还有一个与其对应的系统变量collation_connection,这个系统变量表示了这些字符串应使用哪种比较规则。

同样这个系统变量collation_connection可以通过SET命令进行修改。

如果客户端发送请求、服务器接收请求和服务器处理请求这一过程中,字符集和比较规则不一样,会出现什么情况呢?

就这个表来说

向客户端发送一条查询语句

由于当前操作系统使用的是gbk字符集,所以字符串‘我’是使用GBK字符集进行编码的,比较规则为gbk_chinese_ci,而列C使用的是utf8字符集编码的,比较规则为utf8_general_ci。

那么在这种情况下,列的字符集和排序规则的优先级更高,也就是说这里需要将‘我’从GBK字符集转换成utf8字符集,然后使用列c的比较规则进行比较

当服务器生成响应的时候,是不是直接将列c也就是utf8字符集进行编码的结果发送回客户端呢?

答案是不一定,这取决与SESSION级别的系统变量character_set_results的值,结果会从utf8字符集编码的转换成

character_set_results对应的字符编码后的字节序列

系统变量 描述
character_set_client 服务器认为请求是按照系统变量指定的字符集进行编码的
character_set_connection 服务器在处理请求时,会将请求字符序列从character_set_client转换成character_set_connection
character_set_results 服务器采用该系统变量指定的字符集对返回客户端的字符串进行编码

由于三个变量均为SESSION级别,因此每个客户端与服务器建立连接的时候都会维护这三个变量。

最后就是客户端接收响应了,响应也就是一个字节序列,收到的字节序列会直接写进黑框框中,再由黑框框将字节序列接受成人类能懂的字符(如果没有特殊设置,一般使用操作系统当前使用的字符集进行解释)

参考:《MySQL是怎样运行的:从根儿上理解 MySQL》

总结

到此这篇关于MySQ字符集和比较规则的文章就介绍到这了,更多相关MySQ字符集和比较规则内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • PHP 设置MySQL连接字符集的方法

    mysql_set_charset(). 这个函数是这样用的: mysql_set_charset('utf8', $link); 成功返回 TRUE,失败返回 FALSE. 就这么简单. 下面是PHP手册原文 This is the preferred way to change the charset. Using mysql_query() to execute SET NAMES .. is not recommended.

  • 深入Mysql字符集设置分析

    基本概念 • 字符(Character)是指人类语言中最小的表义符号.例如'A'.'B'等: • 给定一系列字符,对每个字符赋予一个数值,用数值来代表对应的字符,这一数值就是字符的编码(Encoding).例如,我们给字符'A'赋予数值0,给字符'B'赋予数值1,则0就是字符'A'的编码: • 给定一系列字符并赋予对应的编码后,所有这些字符和编码对组成的集合就是字符集(Character Set).例如,给定字符列表为{'A','B'}时,{'A'=>0, 'B'=>1}就是一个字符集: •

  • 修改mysql默认字符集的两种方法详细解析

    (1) 最简单的修改方法,就是修改mysql的my.ini文件中的字符集键值,如 default-character-set = utf8    character_set_server = utf8 修改完后,重启mysql的服务,service mysql restart使用 mysql> SHOW VARIABLES LIKE 'character%';查看,发现数据库编码均已改成utf8 复制代码 代码如下: +--------------------------+-----------

  • mysql字符集和校对规则(Mysql校对集)

    简要说明 字符集和校对规则 字符集是一套符号和编码.校对规则是在字符集内用于比较字符的一套规则. MySql在collation提供较强的支持,oracel在这方面没查到相应的资料. 不同字符集有不同的校对规则,命名约定:以其相关的字符集名开始,通常包括一个语言名,并且以_ci(大小写不敏感)._cs(大小写敏感)或_bin(二元)结束 校对规则一般分为两类: binary collation,二元法,直接比较字符的编码,可以认为是区分大小写的,因为字符集中'A'和'a'的编码显然不同. 字符集

  • 深入Mysql字符集设置[精华结合]

    基本概念 • 字符(Character)是指人类语言中最小的表义符号.例如'A'.'B'等: • 给定一系列字符,对每个字符赋予一个数值,用数值来代表对应的字符,这一数值就是字符的编码(Encoding).例如,我们给字符'A'赋予数值0,给字符'B'赋予数值1,则0就是字符'A'的编码: • 给定一系列字符并赋予对应的编码后,所有这些字符和编码对组成的集合就是字符集(Character Set).例如,给定字符列表为{'A','B'}时,{'A'=>0, 'B'=>1}就是一个字符集: •

  • 一文带你了解MySQL字符集和比较规则

    目录 1. MySQL中的utf8和utf8mb4 2. MySQL中的比较规则 3. 各级别的字符集和比较规则 3.1 服务器级别 3.2 数据库级别 3.3 表级别 3.4 列级别 4. 修改字符集或比较规则 5. MySQL中的字符集转换过程 总结 1. MySQL中的utf8和utf8mb4 在MySQL中,我经常会看见utf8和utf8mb4这两种编码格式,但是这两种格式我并不了解,一般创建数据库的时候,如果让我选,我默认会选择utf8,但是这个和UTF-8长得最像. 但是实际上,这两

  • Mysql字符集和排序规则详解

    目录 前言 什么是字符集 什么是比较规则 常用字符集 ASCII字符集 ISO8859-1 GB2312 GBK字符集 Unicode字符集 注意点 Mysql中查询字符集和比较规则 查询字符集 查询比较规则 前言 计算机存储数据的方式都是二进制数据,但是我们在mysql中存储的是字符串数据,那么这些数据到底在Mysql中如何存储呢?这就涉及到字符集的概念. 什么是字符集 举例如下,假设存在编码集test,只能识别a,b,A,B这几项,同时编码规则如下: a---->00000001(0x01)

  • 一文带你了解Mysql主从同步原理

    目录 Mysql 主从同步原理简析 1.什么是主从 2.为什么要搞主从呢? 3.如何实现主从同步呢? 4.mysql 主从同步的原理 Mysql 主从同步原理简析 在开始讲述原理的情况下,我们先来做个知识汇总, 究竟什么是主从,为什么要搞主从,可以怎么实现主从,mysql主从同步的原理 1.什么是主从 其实主从这个概念非常简单 主机就是我们平常主要用来读写的服务,我们称之为master(主人.主宰) 从机就是主机进行的一个扩展,他一般不会主动用来读写,我们称之为slave( [sleɪv] 奴隶

  • 一文带你了解MySQL中触发器的操作

    目录 概述 介绍 触发器的特性 操作—创建触发器 操作—new和old 操作—查看触发器 操作—删除触发器 注意事项 概述 介绍 触发器,就是一种特殊的存储过程.触发器和存储过程一样是一个能够完成特定功能.存储在数据库服务器上的SQL片段,但是触发器无需调用,当对数据库表中的数据执行DML操作时自动触发这个SQL片段的执行,无需手动条用. 在MySQL中,只有执行insert,delete,update操作时才能触发触发器的执行 触发器的这种特性可以协助应用在数据库端确保数据的完整性,日志记录,

  • mysql字符集和数据库引擎修改方法分享

    MySQL字符集:cp1252 West European (latin1) ,解决乱码问题 使用虚拟主机空间上的phpmyadmin操作数据库的时候,如果看到phpmyadmin首页上显示的MySQL 字符集为cp1252 West European (latin1),当我们导入数据时就会出现乱码,解决的方法是: 在phpmyadmin首页的右边有个Language选项,把默认的中文 - Chinese simplified-gb2312改成 中文 - Chinese simplified,则

  • 一文带你探究MySQL中的NULL

    目录 前言 1 MySQL 中的NULL 2 NULL占用的长度 3 对NULL值的比较 4 SQL对NULL值进行处理 5 值为NULL 对查询条件的影响 6 值为NULL对索引的影响 7 值为NULL对排序的影响 8 NULL和空值区别 总结 前言 不知道大家有没有遇到这样的问题,当我们在对MySQL数据库进行查询操作时,条件写的是status!=1,理论上会将所有不符合条件的查询出来,但奇怪的是结果为NULL的就查不出来,必须得拼接上条件or status IS NULL.本篇文章我们就一

  • 一文带你学会MySQL的select语句

    目录 SQL概述 SQL背景知识 SQL语言排行榜 SQL 分类 SQL语言的规则与规范 基本规则 SQL大小写规范 (建议遵守) 注释 命名规则(暂时了解) 数据导入指令 基本的SELECT语句 SELECT... SELECT ... FROM 列的别名 去除重复行 空值参与运算 着重号 查询常数 总结 SQL概述 SQL背景知识 1946 年,世界上第一台电脑诞生,如今,借由这台电脑发展起来的互联网已经自成江湖.在这几十年里,无数的技术.产业在这片江湖里沉浮,有的方兴未艾,有的已经几幕兴衰

  • 一文带你理解MySql中explain结果filtered

    MySql explain语句的返回结果中,filtered字段要怎么理解? MySql5.7官方文档中描述如下: The filtered column indicates an estimated percentage of table rows filtered by the table condition. The maximum value is 100, which means no filtering of rows occurred. Values decreasing from

  • 一文带你了解C++中的字符替换方法

    目录 一.单个字符替换 1.1 std::replace 1.2 使用循环手动替换 1.3 使用正则表达式库(例如,std::regex_replace) 二.字符串替换 2.1 实用字符串流 2.2 使用字符数组 2.3 使用 STL 的算法:std::replace 2.4 使用正则表达式 三.总结 一.单个字符替换 1.1 std::replace 代码示例: #include <algorithm> // ... std::string str = "Hello, World

随机推荐