mysql程序相关与字符集

240 阅读6分钟

mysql服务端相关程序

  • mysqld 启动mysql服务端进程
  • mysqld_safe 间接调用mysqld,另外包含监控进程(帮助自动重启),另外将错误日志重定向至文件
  • mysql.server 间接调用mysqld_safe
  • mysql_multi 运行多个mysql进程,对每个进程进行监控

客户端与服务器连接过程

tcp/ip

通过网络协议进行通信,会产生端口号,连接时通过-P参数指定端口(客户端和服务器端都可以指定)

unix域套接字文件

通过监听一个套接字文件的改变进行通信,可以通过--socket指定套接字文件

命名管道和共享内存

windows专属

服务端处理请求的流程

  1. 连接管理 通过三种方式连接后,每一个连接都会创建一个线程专门处理,当客户端退出连接时,服务器不会立刻销毁进程,而是缓存起来。当有新的连接时,将该进程分配给新的客户端,这样可以节省开销,不必频繁创建和销毁进程
  2. 解析优化 包含查询缓存、语法解析和查询优化 查询缓存用来缓存之前的查询结果,但是缓存命中条件很苛刻,只有两次请求任何字符都相同才回命中。请求系统函数、用户自定义变量和函数或者系统表,也不会命中(例如now)。当表的数据或者结构有了改变(CURD、alter、drop等等),缓存也会被删除,mysql8被删除 语法解析是完成对请求的分析,判断语法是否正确,设计词法解释、语法分析等等 查询优化将语句进行优化,会生成一个执行计划,表明应该用哪些索引查询,表的连接顺序,可以使用explain查看执行计划
  3. 存储引擎 物理上表示数据,具体实现从硬盘写入、读取,包含十几个底层函数(像读取索引第一条、插入等等),提供给上层调用

存储引擎相关

  1. 常见的存储引擎
  • MyISAM 非事务处理存储引擎
  • InnoDB 具备外键支持功能的事务存储引擎
  • Memory 存在内存当中
  1. 查看支持的存储引擎 show ENGINES;

字符集和比较规则

字符集是一组描述字符的编码规则,将字符映射成一个二进制形式,称为编码,反之称之为解码。比较规则是将同一种编码类型的字符排序的规则,比方说字符 ‘a' 编码为0x01,'b'为0x02,所以a小于b

重要的字符集

  • ASCII 收录128个字符,占用一个字节
  • ISO 8895-1 收录256个字符,在ASCII上扩充了西欧字符,占用一个字节,别名latin1
  • GB2312 包含汉字、拉丁字母、日文字符等等,兼容ASCII,占用一个字节(在ASCII中的字符)或者两个字节
  • GBK 在GB2312上扩充,兼容GB2312
  • utf8 属于unicode编码方案,占用1-4个字节,utf16占用2或4个字节,utf32占用4个字节

mysql中的utf8其实是阉割版,只使用1-3个字节,utf8mb4才是正宗的utf8

mysql中的比较规则

mysql> SHOW COLLATION LIKE 'utf8\_%';
+--------------------------+---------+-----+---------+----------+---------+
| Collation                | Charset | Id  | Default | Compiled | Sortlen |
+--------------------------+---------+-----+---------+----------+---------+
| utf8_general_ci          | utf8    |  33 | Yes     | Yes      |       1 |
| utf8_bin                 | utf8    |  83 |         | Yes      |       1 |
| utf8_unicode_ci          | utf8    | 192 |         | Yes      |       8 |
| utf8_icelandic_ci        | utf8    | 193 |         | Yes      |       8 |
| utf8_latvian_ci          | utf8    | 194 |         | Yes      |       8 |
| utf8_romanian_ci         | utf8    | 195 |         | Yes      |       8 |
| utf8_slovenian_ci        | utf8    | 196 |         | Yes      |       8 |
| utf8_polish_ci           | utf8    | 197 |         | Yes      |       8 |
| utf8_estonian_ci         | utf8    | 198 |         | Yes      |       8 |
| utf8_spanish_ci          | utf8    | 199 |         | Yes      |       8 |
| utf8_swedish_ci          | utf8    | 200 |         | Yes      |       8 |
| utf8_turkish_ci          | utf8    | 201 |         | Yes      |       8 |
| utf8_czech_ci            | utf8    | 202 |         | Yes      |       8 |
| utf8_danish_ci           | utf8    | 203 |         | Yes      |       8 |
| utf8_lithuanian_ci       | utf8    | 204 |         | Yes      |       8 |
| utf8_slovak_ci           | utf8    | 205 |         | Yes      |       8 |
| utf8_spanish2_ci         | utf8    | 206 |         | Yes      |       8 |
| utf8_roman_ci            | utf8    | 207 |         | Yes      |       8 |
| utf8_persian_ci          | utf8    | 208 |         | Yes      |       8 |
| utf8_esperanto_ci        | utf8    | 209 |         | Yes      |       8 |
| utf8_hungarian_ci        | utf8    | 210 |         | Yes      |       8 |
| utf8_sinhala_ci          | utf8    | 211 |         | Yes      |       8 |
| utf8_german2_ci          | utf8    | 212 |         | Yes      |       8 |
| utf8_croatian_ci         | utf8    | 213 |         | Yes      |       8 |
| utf8_unicode_520_ci      | utf8    | 214 |         | Yes      |       8 |
| utf8_vietnamese_ci       | utf8    | 215 |         | Yes      |       8 |
| utf8_general_mysql500_ci | utf8    | 223 |         | Yes      |       1 |
+--------------------------+---------+-----+---------+----------+---------+
27 rows in set (0.00 sec)

中间的指的是作用于哪种语言,比如utf8_polish_ci表示以波兰语的规则比较,utf8_spanish_ci是以西班牙语的规则比较,utf8_general_ci是一种通用的比较规则。 而后缀页也有着不同的含义

后缀 含义
_ai 不区分重音
_as 区分重音
_ci 不区分大小写
_cs 区分大小写
_bin 以二进制方式比较

如何设置mysql中的字符集和比较规则

mysql有四种级别的字符集和比较规则

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

服务器级别

通过character_set_server指定字符集,通过collation_server指定比较规则

数据库级别

创建或者修改表的时候可以指定,也可以通过character_set_database指定字符集,通过collation_database指定比较规则


  • 如果创建或修改列时没有显式的指定字符集和比较规则,则该列默认用表的字符集和比较规则
  • 如果创建或修改表时没有显式的指定字符集和比较规则,则该表默认用数据库的字符集和比较规则
  • 如果创建或修改数据库时没有显式的指定字符集和比较规则,则该数据库默认用服务器的字符集和比较规则

mysql中的字符集转换

从客户端发一条指令到服务端,到最终服务端返回结果,中间会经历多次转换,过程中会涉及到三个系统变量

系统变量 描述
character_set_client 服务器解码请求使用的字符集
character_set_connecticon 处理请求会从set_client转换成set_connection
character_set_result 服务端返回结果使用的字符集

从发送请求到接收结果过程中发生的字符集转换:

  1. 客户端使用操作系统的字符集编码请求字符串,向服务器发送的是经过编码的一个字节串。

  2. 服务器将客户端发送来的字节串采用character_set_client代表的字符集进行解码,将解码后的字符串再按照character_set_connection代表的字符集进行编码。

  3. 如果character_set_connection代表的字符集和具体操作的列使用的字符集一致,则直接进行相应操作,否则的话需要将请求中的字符串从character_set_connection代表的字符集转换为具体操作的列使用的字符集之后再进行操作。

  4. 将从某个列获取到的字节串从该列使用的字符集转换为character_set_results代表的字符集后发送到客户端。

  5. 客户端使用操作系统的字符集解析收到的结果集字节串

    image

内容来自掘金小册《MySQL 是怎样运行的:从根儿上理解 MySQL》。