mysql服务端相关程序
- mysqld 启动mysql服务端进程
- mysqld_safe 间接调用mysqld,另外包含监控进程(帮助自动重启),另外将错误日志重定向至文件
- mysql.server 间接调用mysqld_safe
- mysql_multi 运行多个mysql进程,对每个进程进行监控
客户端与服务器连接过程
tcp/ip
通过网络协议进行通信,会产生端口号,连接时通过-P参数指定端口(客户端和服务器端都可以指定)
unix域套接字文件
通过监听一个套接字文件的改变进行通信,可以通过--socket指定套接字文件
命名管道和共享内存
windows专属
服务端处理请求的流程
- 连接管理 通过三种方式连接后,每一个连接都会创建一个线程专门处理,当客户端退出连接时,服务器不会立刻销毁进程,而是缓存起来。当有新的连接时,将该进程分配给新的客户端,这样可以节省开销,不必频繁创建和销毁进程
- 解析优化 包含查询缓存、语法解析和查询优化 查询缓存用来缓存之前的查询结果,但是缓存命中条件很苛刻,只有两次请求任何字符都相同才回命中。请求系统函数、用户自定义变量和函数或者系统表,也不会命中(例如now)。当表的数据或者结构有了改变(CURD、alter、drop等等),缓存也会被删除,mysql8被删除 语法解析是完成对请求的分析,判断语法是否正确,设计词法解释、语法分析等等 查询优化将语句进行优化,会生成一个执行计划,表明应该用哪些索引查询,表的连接顺序,可以使用explain查看执行计划
- 存储引擎 物理上表示数据,具体实现从硬盘写入、读取,包含十几个底层函数(像读取索引第一条、插入等等),提供给上层调用
存储引擎相关
- 常见的存储引擎
- MyISAM 非事务处理存储引擎
- InnoDB 具备外键支持功能的事务存储引擎
- Memory 存在内存当中
- 查看支持的存储引擎 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 | 服务端返回结果使用的字符集 |
从发送请求到接收结果过程中发生的字符集转换:
-
客户端使用操作系统的字符集编码请求字符串,向服务器发送的是经过编码的一个字节串。
-
服务器将客户端发送来的字节串采用character_set_client代表的字符集进行解码,将解码后的字符串再按照character_set_connection代表的字符集进行编码。
-
如果character_set_connection代表的字符集和具体操作的列使用的字符集一致,则直接进行相应操作,否则的话需要将请求中的字符串从character_set_connection代表的字符集转换为具体操作的列使用的字符集之后再进行操作。
-
将从某个列获取到的字节串从该列使用的字符集转换为character_set_results代表的字符集后发送到客户端。
-
客户端使用操作系统的字符集解析收到的结果集字节串
内容来自掘金小册《MySQL 是怎样运行的:从根儿上理解 MySQL》。