💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## **字符集** 在MysQL8.0版本之前,默认字符集为 latin1 (ISO-8859-1), utf8字符集指向的是utf8mb3。网站开发人员在数据库设计的时候往往会将编码修改为utf8字符集。如果遗忘修改默认的编码,就会出现乱码的问题。从MySQL 8.0开始,数据库的默认编码将改为utf8mb4 ,从而避免上述乱码的问题。 **MySQL 的 utf8 编码是 3 字节,无法存储 一些表情符号,要用 utf8mb4才行, 4字节的。** ``` 查看默认使用的字符集 show variables like 'character%' # 或者 show variables like 'char%' ``` 设置默认字符集为 utf8mb4 Windows 是 my.ini 文件 Linux 是 /etc/my.cnf `character_set_server = utf8mb4` 修改已创建数据库的字符集 ``` alter database 数据库名称 character set 'utf8mb4' ``` 修改已创建数据表的字符集 ``` alter table 表名 convert to character set 'utf8mb4' ``` ## 字母大小写 在 SQL 中,关键字和函数名是不用区分字母大小写的,比如 SELECT、WHERE、ORDER、GROUP BY 等关 键字,以及 ABS、MOD、ROUND、MAX 等函数名。 **但是数据库名、表名、别名、字段名等数据 在 windows系统默认大小写不敏感 1 , linux系统是大小写敏感的 0。** 命令查看: ``` SHOW VARIABLES LIKE '%lower_case_table_names%' ``` lower\_case\_table\_names参数值的设置: * 默认为0,大小写敏感 。 * 设置1,大小写不敏感。创建的表,数据库都是以小写形式存放在磁盘上,对于sql语句都是转 换为小写对表和数据库进行查找。 * 设置2,创建的表和数据库依据语句上格式存放,凡是查找都是转换为小写进行 ## SQL编写建议 1. 关键字和函数名称全部大写; 2. 数据库名、表名、表别名、字段名、字段别名等全部小写; 3. SQL 语句必须以分号结尾。 虽然关键字和函数名称在 SQL 中不区分大小写,也就是如果小写的话同样可以执行。但是同时将关键词 和函数名称全部大写,以便于区分数据库名、表名、字段名。 ## MySQL的数据目录 ### 查看默认数据库 * **mysql ** MySQL 系统自带的核心数据库,它存储了MySQL的用户账户和权限信息,一些存储过程、事件的定 义信息,一些运行过程中产生的日志信息,一些帮助信息以及时区信息等。 * **information_schema** 库保存着MySQL服务器 维护的所有其他数据库的信息 ,比如有 哪些表、哪些视图、哪些触发器、哪些列、哪些索引。 * **performance_schema **这个数据库里主要保存MySQL服务器运行过程中的一些状态信息,可以 用来 监控 MySQL 服务的各类性能指标 。包括统计最近执行了哪些语句,在执行过程的每个阶段都 花费了多长时间,内存的使用情况等信息。 * **sys **这个数据库主要是通过 视图 的形式把 information_schema 和 performance_schema 结合起来,帮助系统管理员和开发人员监控 MySQL 的技术性能。 ## InnoDB存储引擎模式 ### **表结构** 为了保存表结构, InnoDB 在 数据目录 下对应的数据库子目录下创建了一个专门用于描述表结构的文件 ,文件名是这样:**表名.frm** ### 表中数据和索引 **系统表空间(system tablespace)**:默认情况下,InnoDB会在数据目录下创建一个名为 ibdata1 、大小为 12M 的文件,这个文件就是对应 的 系统表空间 在文件系统上的表示。怎么才12M?注意这个文件是 自扩展文件 ,当不够用的时候它会自 己增加文件大小。 **独立表空间(file-per-table tablespace)**: 每 一个表建立一个独立表空间 ,也就是说我们创建了多少个表,就有多少个独立表空间。使用 独立表空间 来 存储表数据的话,会在该表所属数据库对应的子目录下创建一个表示该独立表空间的文件,文件名和表 名相同,只不过添加了一个 .ibd 的扩展名而已,所以完整的文件名称长这样:**表名.ibd** ## 1 逻辑架构剖析 ### 1.1 服务器处理客户端请求 ![](https://img.kancloud.cn/3c/08/3c086f3b4cbe6b77d38461e40e2181ce_1363x1061.png) ### 1.3 第1层:连接层 1. 系统(客户端)访问 MySQL 服务器前,做的第一件事就是建立 **TCP 连接。** 2. 经过**三次握手**建立连接成功后, MySQL 服务器对 TCP 传输过来的账号密码做**身份认证**、**权限获取**。 * 用户名或密码不对,会收到一个Access denied for user错误,客户端程序结束执行 * 用户名密码认证通过,会从权限表查出账号拥有的权限与连接关联,之后的权限判断逻辑,都将依 赖于此时读到的权限 3. TCP 连接收到请求后,必须要分配给一个线程专门与这个客户端的交互。所以还会有个线程池,去走后面的流程。每一个连接从线程池中获取线程,省去了创建和销毁线程的开销 ### 1.4 第2层:服务层 * SQL Interface: SQL接口 * 接收用户的SQL命令,并且返回用户需要查询的结果。比如SELECT ... FROM就是调用SQL Interface * MySQL支持DML(数据操作语言)、DDL(数据定义语言)、存储过程、视图、触发器、自定 义函数等多种SQL语言接口。 * Parser: 解析器 * 在解析器中对 SQL 语句进行语法分析、语义分析。将SQL语句分解成数据结构,并将这个结构 传递到后续步骤,以后SQL语句的传递和处理就是基于这个结构的。如果在分解构成中遇到错 误,那么就说明这个SQL语句是不合理的。 * 在SQL命令传递到解析器的时候会被解析器验证和解析,并为其创建 语法树 ,并根据数据字 典丰富查询语法树,会 验证该客户端是否具有执行该查询的权限 。创建好语法树后,MySQL还 会对SQl查询进行语法上的优化,进行查询重写。 * Optimizer: 查询优化器 * SQL语句在语法解析之后、查询之前会使用查询优化器确定 SQL 语句的执行路径,生成一个 执行计划 。 * 这个执行计划表明应该 使用哪些索引 进行查询(全表检索还是使用索引检索),表之间的连 接顺序如何,最后会按照执行计划中的步骤调用存储引擎提供的方法来真正的执行查询,并将 查询结果返回给用户。 * 它使用“ 选取-投影-连接 ”策略进行查询。例如:SELECT id,name FROM student WHERE gender = '女'; 这个SELECT查询先根据WHERE语句进行 选取 ,而不是将表全部查询出来以后再进行gender过 滤。 这个SELECT查询先根据id和name进行属性 投影 ,而不是将属性全部取出以后再进行过 滤,将这两个查询条件 连接 起来生成最终查询结果。 * Caches & Buffers: 查询缓存组件 * MySQL内部维持着一些Cache和Buffer,比如Query Cache用来缓存一条SELECT语句的执行结 果,如果能够在其中找到对应的查询结果,那么就不必再进行查询解析、优化和执行的整个过 程了,直接将结果反馈给客户端。 * 这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等 * 这个查询缓存可以在 不同客户端之间共享 。 * 从MySQL 5.7.20开始,不推荐使用查询缓存,并在 MySQL 8.0中删除 ## 1.5 第3层:引擎层 插件式存储引擎层( Storage Engines),真正的负责了MySQL中数据的存储和提取,对物理服务器级别 维护的底层数据执行操作,服务器通过API与存储引擎进行通信。不同的存储引擎具有的功能不同,这样 我们可以根据自己的实际需要进行选取。 MySQL 8.0.25默认支持的存储引擎如下: ![](https://img.kancloud.cn/93/18/931830b3e38ecbba217e7f4edd406b3f_1582x388.png) 1.6 存储层 所有的数据,数据库、表的定义,表的每一行的内容,索引,都是存在 文件系统 上,以 文件 的方式存 在的,并完成与存储引擎的交互。当然有些存储引擎比如InnoDB,也支持不使用文件系统直接管理裸设 备,但现代文件系统的实现使得这样做没有必要了。在文件系统之下,可以使用本地磁盘,可以使用 DAS、NAS、SAN等各种存储系统。 ## 2. SQL执行流程 ### 2.1 MySQL 的SQL执行流程 ![](https://img.kancloud.cn/44/06/4406a2d88b019433293fb06c14b085a1_1523x850.png) MySQL的查询流程: 1. **查询缓存:不推荐使用**,因为查询缓存往往效率不高,所以在 MySQL8.0 之后就抛弃 了这个功能。查询缓存是提前把查询结果缓存起来,只要该表的 结构或者数据被修改,缓存就会删除 * 如果在查询缓存中发现了这条 SQL 语句的执行结果,就会直接将结果返回给客户端。 * 如果没 有,就进入到解析器阶段。 **2. 解析器:在解析器中对 SQL 语句进行语法分析、语义分析。** * 分析器先做“ 词法分析 ”,识别出输入 的字符串分别是什么,代表什么。 * 然后做“ 语法分析 ”。语法分析器(比如:Bison)会根据语法规则,判断输 入的这个 SQL 语句是否 满足 MySQL 语法,如果正确就生成语法树。 ![](https://img.kancloud.cn/73/d1/73d11d422d03759393ffa353d0caa198_1596x775.png) 3. **优化器**:在优化器中会确定 SQL 语句的执行路径,比如是根据 全表检索 ,还是根据 索引检索 等。在查询优化器中,可以分为 逻辑查询 优化阶段和 物理查询 优化阶段。 4.** 执行器:** 在执行之前需要判断该用户是否具备权限 。如果没有,就会返回权限错误。如果具备权限,就执行 SQL 查询并返回结果。在 MySQL8.0 以前的版本,如果设置了查询缓存,这时会将查询结果进行缓存。 至此,这个语句就执行完成了。对于有索引的表,执行的逻辑也差不多。 SQL 语句在 MySQL 中的流程是: SQL语句→查询缓存→解析器→优化器→执行器 ![](https://img.kancloud.cn/85/a2/85a2d8b62f28aaa07d8b8fed59734add_1526x231.png) ## 3. 数据库缓冲池 ### 1. 缓冲池(Buffer Pool) 在 InnoDB 存储引擎中有一部分数据会放到内存中,缓冲池则占了这部分内存的大部分,它用来存储各种 数据的缓存,如下图所示: ![](https://img.kancloud.cn/6e/b4/6eb49e7ebf4d572a8e487ed479216292_1406x864.png) 从图中,能看到** InnoDB 缓冲池包括了数据页、索引页、插入缓冲、锁信息、自适应 Hash 和数据字典 信息等。** ## 4. 存储引擎 ### 4.1. 查看存储引擎 ``` show engines; show engines \G; ``` ### 4.2. 设置系统默认的存储引擎 查看默认的存储引擎 ``` show variables like '%storage_engine%'; #或 SELECT @@default_storage_engine; ``` 修改默认的存储引擎 ``` SET DEFAULT_STORAGE_ENGINE=MyISAM; ``` 或者修改 my.cnf 文件 Windows 是 my.ini ``` default-storage-engine=MyISAM # 重启服务 systemctl restart mysqld.service ``` ### 4.3 设置表的存储引擎 用默认的存储引擎 InnoDB 存储引擎是负责对表中的数据进行提取和写入工作的,我们可以为 不同的表设置不同的存储引擎 ,也就是 说不同的表可以有不同的物理存储结构,不同的提取和写入方式。 #### 4.3.1 创建表时显示指定存储引擎 ``` CREATE TABLE 表名( 建表语句; ) ENGINE = 存储引擎名称; ``` 4.3.2 修改表的存储引擎 ``` ALTER TABLE 表名 ENGINE = 存储引擎名称; ``` ### 4.4 引擎介绍 InnoDB 引擎:具备外键支持功能的事务存储引擎 * InnoDB是MySQL的 默认事务型引擎 ,它被设计用来处理大量的短期(short-lived)事务。可以确保事务 * 的完整提交(Commit)和回滚(Rollback)。 * 除了增加和查询外,还需要更新、删除操作,那么,应优先选择InnoDB存储引擎。 * 除非有非常特别的原因需要使用其他的存储引擎,否则应该优先考虑InnoDB引擎。 * InnoDB是 为处理巨大数据量的最大性能设计 。 * MyISAM只缓存索引,不缓存真实数据;InnoDB不仅缓存索引还要缓存真实数据, 对内存要求较 高 ,而且内存大小对性能有决定性的影响。 MyISAM 引擎:主要的非事务处理存储引擎 * MyISAM提供了大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM 不支持事务、行级锁、外键 ,有一个毫无疑问的缺陷就是 崩溃后无法安全恢复 。 * 应用场景:只读应用或者以读为主的业务