MySQL是怎样运行的(三)

3.1 字符集和比较规则

3.1.1 字符集简介

计算机中实际存储的是二进制数据,怎么存储字符串呢?就需要建立字符串与二进制的关系:

  • 要把哪些字符映射成二进制数据?也就是界定字符范围
  • 怎么映射?将字符映射成二进制数据的过程叫做编码,将二进制数据映射到字符的过程叫做解码。

3.1.2 比较规则简介

二进制比较规则:直接比较二进制的大小
但是很多场合下,英文字符不区分大小写,就不能直接用二进制进行比较了,也就是说同一种字符集可以有多种比较规则。稍后将介绍现实生活中使用的各种字符集以及它们的部分比较规则。

3.1.3 一些重要的字符集

  • ASCII字符集:共收录128个字符,包括空格、标点符号、数字、大小写字母和一些不可见的字符。由于总共128个字符,所以可以使用一个字节来进行编码。
  • ISO 8859-1 字符集(别名:Latin1):共收录256个字符,它在ASCII字符集的基础上又扩充了128个西欧常用字符(包括德法两国的字母)。该字符集也可以使用一个字节来进行编码
  • GB2312字符集:收录了汉字以及拉丁字母、希腊字母、日文平假名以及片假名字母、俄语西里尔字母,收录汉字6763个,收录其他文字符号682个。这种字符集同时又兼容ASCII字符集,所以在编码方式上显得有些奇怪:如果该字符在ASCII字符集中,则采用一字节编码;否则采用两字节编码。

这种使用不同字节数来表示一个字符的编码方式称为变长编码方式。比如字符串“爱u”,其中的“爱”需要2个字节进行编码,编码后的十六进制表示0xB0AE;‘u’需要1字节进行编码,编码后的十六进制为0x75,所以拼合起来是0xB0AE75。

ASCII字符集只收录128个字符,使用0127就可以表示全部字符。所以,如果某个字节是在0127之内(该字节的最高位是0),就意味着一个字节代表一个单独的字符,否则(该字节的最高位为1)就是两个字节代表一个字符。

  • GBK 字符集: GBK字符集只是在收录的字符范围上对GB2312 字符集进行了扩充,编码方式兼容GB2312 字符集。
  • UTF-8 字符集:几乎收录了当今世界各个国家/地区使用的字符,而且还在不断地扩充。这种字符集兼容ASCII 字符集,采用变长编码方式,编码一个字符时需要使用1~4字节。

其实准确地说,UTF-8只是Unicode 字符集的一种编码方案,Unicode 字符集可以采用UTF-8、UTF-16、UTF-32这几种编码方案。utf-8使用14字节编码一个字符,utf-16使用24字节编码一个字符,utf-32 使用4个字节编码一个字符。

3.2 Mysql 中支持的字符集和比较规则

3.2.1 Mysql 中的utf8和utf8mb4

  • utf8mb3:“阉割”过的utf-8字符集,只使用1~3字节表示字符。在mysql中utf8是其别名。
  • utf8mb4:正宗的utf-8字符集,使用1~4字节表示字符

3.2.2 字符集的查看

show (character set|charset) [like 匹配模式], 其中character set 和 charset 是同义词,用任意一个都可以。

default collation 列表示这种字符集默认的比较规则;maxlen 列表示这种字符集最多需要几个字节来表示一个字符。

3.2.3 比较规则的查看

show collation [like 匹配模式]

当前版本的数据库查询出来有107条数据。

3.3 字符集和比较规则的应用

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

Mysql有四个级别的字符集和比较规则,分别是服务器级别、数据库级别、表级别、列级别。

  1. 服务器级别
    show variables like 'character_set_server'; show variables like 'collation_server'
    可以在配置文件中进行配置
  2. 数据库级别
    创建和修改数据库是可以指定该数据库的字符集和比较规则
    create database 数据库名 [[default] character set 字符集名称] [[default] collate 比较规则名称];
    如果想当前数据库使用的字符集(使用use语句选择当前的数据库),也可以使用show来查询
    show variables like 'character_set_database');
    如果创建数据库不指定字符集和比较规则时,则默认使用服务器级别的字符集与比较规则。
  3. 表级别
    可以在创建和修改表的时候指定表的字符集和比较规则:
    create table 表名(列的信息) [[default] character set 字符集名称] [collate 比较规则名称];
  4. 列级别
    同一个表中的不同列也可以有不同的字符集和比较规则。
    create table 表名 (列名 字符串类型 [character set 字符集名称] [collate 比较规则], 其他列);

也可以修改列的字符集 和比较规则: alter table t modify col varchar(10) character set gbk collate bk_chinese_ci;如果修改时未指定字符集则默认使用表级别的字符集与规则。但是如果列中存储的数据不能用修改后的字符集进行表示,则会发生错误。例如,uft8转ASCII的话就会出错。

  1. 仅修改字符集或仅修改比较规则
    由于字符集和比较规则之间互相关联,因此如果只修改字符集,比较规则会跟着变化,如果只修改比较规则,字符集也会跟着变化
    • 只修改字符集,则比较规则将变为修改后的字符集默认的比较规则;
    • 只修改比较规则,则字符集将变为修改后的比较规则对应的字符集。
  2. 各级别字符集和比较规则小结
    • 如果创建或修改列没有显式指定字符集和比较规则,则该列默认使用表的字符集和比较规则;
    • 如果创建表时没有显式指定字符集和比较规则,则该表默认使用数据库的字符集和比较规则;
    • 如果创建数据库时没有显式指定字符集和比较规则,则该数据库默认使用服务器的字符集和比较规则。

3.3.2 客户端和服务器通信过程中使用的字符集

  1. 编码和解码使用的字符集不一致

  2. 字符集转换的概念

  3. MySQL中的字符集转换过程
    客户端发送请求

    • 当使用类UNIX操作系统时
      LC_ALL, LC_CTYPE, LANG这3个环境变量的值决定了操作系统当前使用的是哪种字符集。其中LC_ALL的优先级比LC_CTYPE高,LC_CTYPE的优先级比LANG高。也就是说,如果设置了LC_ALL,最终都以LC_ALL为准。
      如果这3个环境变量都没有,那么操作系统使用的字符集就是其默认的字符集。

    • 当使用Windows操作系统时
      在Windows中,字符集称为代码页(code page),一个代码页与一个唯一的数据相关联。比如,936代表GBK字符集,65001代表UTF-8字符集

      在windows操作系统中,如果在启动MySQL客户端程序时携带了default-character-set启动选项,那么Mysql客户端将以该启动选项指定的字符集对请求的字符串进行编码(这一点并不适用于类UNIX操作系统)。

    服务器接收请求
    从本质上来说,服务器接收到的请求就是一个字节序列。服务器将这个字节序列看作是使用系统变量character_set_client代表的字符集进行编码的字节序列(每个客户端与服务器建立连接后,服务器都会为该客户端维护一个单独的character_set_client变量,这个变量是SESSION级别的 )。假如客户端实际使用UTF-8字符集来编码请求的字符串,我们就可以将character_set_client设置为utf-8:set character_set_client = utf8;

    服务器处理请求
    在真正处理请求时,又会转化为使用SESSION级别的系统变量character_set_connection对应的字符集进行编码的字节序列。
    select ‘a’ = ‘A’; 这个返回结果是True还是False?其实仅仅根据这个语句不能进行判断。因为我们并不知道两个字符串使用的是什么字符集编码,也不知道比较规则。
    此时,character_set_connection 系统变量就发挥了作用,它表示这些字符串应该使用哪种字符集进行编码。当然,与之对应的还有collation_connection,这个系统变量表示这些字符串应该使用哪种比较规则。
    create table tt ( c varchar(100)) engine=innodb charset = utf8 , 假设当前的character_set_connection 和collation_connection 分别为gbk和gbk_chinese_ci。然后执行 select * from tt where c = '我';
    字符串“我” 是使用gbk字符集进行编码的,比较规则是 gbk_chinese_ci ;而列c是采用utf8字符集进行编码的,比较规则是utf8_general_ci。这该怎么比较呢?在这种情况下,列的字符集和排序规则的优先级更高。因此,这里需要将请求中的字符串“我” 先从 gbk 字符集转化为utf8字符集, 然后再使用列c的比较规则utf8_general_ci进行比较。

    服务器生成响应
    “我”在列c中的存放格式为 0xE68891 ,执行select * from tt; 时,是直接将该值读出后发给客户端吗?这可不一定,取决于SESSION级别的系统变量 character_set_results 的值。服务器会先将会字符串“我” 从utf8 字符集编码的 0xE68891 转化为 character_set_results 系统变量对应的字符集编码后的字节序列,之后再发送给客户端。

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

    这3个系统变量在服务器中的作用范围都是session级别的。每个客户端在与服务器建立连接后,服务器都会为这个连接维护这3个变量。
    每个Mysql客户端都维护着一个客户端默认字符集,客户端在启动是会自动检测所在操作系统当前使用的字符集,并按照一定的规则映射成Mysql自持的字符集,然后将该字符集作为客户端默认的字符集。如果在启动Mysql客户端时设置了default-character-set启动选项,那么客户端会忽视操作系统当前使用的字符集,直接使用该配置。

    客户端接收到响应
    客户端收到的响应其实也是一个字节序列。对于类UNIX操作系统来说,收到的字节序列基本上相当于直接写到黑框框中,再由黑框框将这个字节序列解释为人类能看懂的字符。对于windows系统来说,客户端会使用客户端的默认字符集来解释这个字节序列。

    • 客户端发送的请求字节序列是采用哪种字符集进行编码的;
    • 服务器收到请求字节序列后会认为它采用哪种字符集进行编码的;
    • 服务器在运行过程中会把请求的字节序列转化为以哪种字符集编码的字节序列;
    • 服务器在向客户端返回字节序列时,是采用哪种字符集进行编码的;
    • 客户端在收到响应字节序列后,是怎么把它们进行转换的。

3.3.3 比较规则的应用

3.4 总结

​ 字符集指的是某个字符范围的编码规则。
​ 比较规则是对某个字符集中的字符比较大小的一种规则。
​ 在MySQL中,一个字符集可以有若干种比较规则,其中有一个默认的比较规则,一个比较规则必须对应的一个字符集。
​ 在MySQL中查看支持的字符集和比较规则在语句如下:

  • show (character set | charset) [like 匹配的模式];

  • show collation [like 匹配的模式];

    MySQL有4个级别的字符集和比较规则,具体如下:

    • 服务器级别
      character_set_server 表示服务器级别的字符集,collation_server表示服务器级别的比较规则。
    • 数据库级别
      创建和修改数据库时可以指定字符集和比较规则:
    • 表级别
      创建和修改表的时候指定表的字符集和比较规则:
    • 列级别
      创建和修改列的时候指定列的字符集和比较规则:

    从发送请求到接收响应的过程中发生的字符集转换如下:

    • 客户端发送的请求字节序列是采用哪种字符集编码的。
      这一步骤主要取决于操作系统当前使用的字符集;对于Windows操作系统来说,还与客户端启动时设置的default-character-set启动项有关;
    • 服务器收到请求字节序列后会认为它是采用哪种字符集进行编码的。
      这一步骤取决于系统变量 character_set_client 的值。
    • 服务器在运行过程中会把请求的字节序列转换为以哪种字符集编码的字节序列。
      这一步骤取决与系统变量character_set_connection 的值
    • 服务器在向客户端返回字节序列时,是采用哪种字符集进行编码的。
      这一步骤取决于系统变量 character_set_results 的值
    • 客户端在收到响应字节序列后,是怎么把它们写到黑框框中的。
      这一步骤主要取决于操作系统当前使用的字符集;对于Windows系统来说,还与客户端启动时设置的default-character-set启动项有关
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MySQL是一个开源的关系型数据库管理系统。它使用SQL语言作为与用户进行交互的基础语言。MySQL运行过程可以简单分为四个步骤:连接、语句处理、结果处理和断开连接。 首先,当用户连接MySQL时,客户端会发送连接请求给MySQL服务器,以建立连接。MySQL在收到请求后,会根据用户名和密码进行验证并建立连接。 其次,当连接建立后,用户可以发送SQL语句给MySQL服务器。MySQL会解析SQL语句,并在执行前进行一系列的检查,例如是否存在语法错误和安全性检查等。当SQL语句验证通过后,MySQL会执行相应的操作,例如插入、更新或查询数据等。在执行操作时,MySQL会根据数据存储引擎的不同,选择使用不同的方式来处理数据请求。 第,当MySQL执行完SQL语句后,会将结果返回给用户。如果执行的SQL语句是一个查询命令,MySQL会将查询结果集返回给用户。返回的结果可能是一个整数值、一个文本字符串或一组数据记录等。 最后,在用户完成操作后,他可以选择断开与MySQL服务器的连接。MySQL会释放资源并清理内存,以便下一次请求时使用。 综上所述,MySQL运行过程是一个相对复杂的过程,它依赖于多个因素,如数据存储引擎、SQL语句的复杂度、连接的负载平衡和网络带宽等。理解MySQL运行过程能帮助我们更好地优化数据库的性能,提高系统的稳定性和可用性。 ### 回答2: MySQL是一种开源的关系型数据库管理系统。它是用来存储和管理数据的软件,可以支持很多不同的应用程序。MySQL运行过程可以分为个部分:连接处理、查询处理和结果返回。 在连接处理阶段,应用程序将与MySQL建立连接。MySQL运行在服务器上,应用程序通过网络访问MySQL服务器。连接处理包括个步骤:身份验证、设置连接信息和处理用户权限。 一旦连接建立,应用程序可以发送SQL查询语句给MySQL,并接收查询结果。在查询处理阶段,MySQL首先对查询进行语法分析和语义检查,然后将其转换为执行计划。执行计划定义了执行查询所需的操作。MySQL就会根据执行计划执行查询,并从数据表中检索所需的数据。 在结果返回阶段,MySQL将查询结果返回给应用程序。如果查询结果比较大,MySQL可以将其分成多个数据块,每块包含一部分查询结果。应用程序可以逐步接收这些数据块直到接收到完整的查询结果。一旦结果返回,应用程序可以根据需要处理查询结果。 总之,MySQL是一个高效的数据库管理系统,它可以通过网络与应用程序通信,并在服务器上存储和管理数据。MySQL运行过程包括连接处理、查询处理和结果返回个阶段,它可以为应用程序提供可靠的数据存储和查询服务。 ### 回答3: MySQL是一种关系型数据库管理系统,它使用SQL语言作为管理和查询数据的工具。MySQL运行方式是客户端/服务器模型,客户端向服务器发送请求,服务器接收到请求后进行处理并返回结果。 在MySQL服务器中,有多个组件用于处理不同的任务。其中最重要的组件是MySQL服务进程,它负责处理所有与客户端的通信。服务进程接收到客户端请求后,会将请求传递给查询处理器进行处理。 查询处理器是MySQL的核心组件,它负责解析SQL语句并执行查询操作。查询处理器首先将SQL语句分解为语法单元,然后将其转换为内部表示形式。查询处理器会根据查询计划生成查询执行计划,该计划指定了如何从数据库中检索所需的数据。 MySQL还有其他一些组件,如存储引擎和缓存管理器。存储引擎是用于管理数据的组件,它们负责将数据存储在磁盘上,以及处理数据的读取和写入。缓存管理器负责管理查询缓存,以确保查询结果能够被快速检索和重用。 总的来说,MySQL运行是基于客户端/服务器模型,通过解析SQL语句、生成查询执行计划和处理数据等组件来实现。MySQL的稳定性和可靠性得到了广泛认可,它被广泛应用于众多网站和应用程序中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值