## **字符集**
在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 不支持事务、行级锁、外键 ,有一个毫无疑问的缺陷就是 崩溃后无法安全恢复 。
* 应用场景:只读应用或者以读为主的业务
- 学习地址
- MySQL
- 查询优化
- SQL优化
- 关于or、in、not in、!=等走不走索引的说明
- 千万级数据查询优化
- MySQL 深度分页问题
- 嵌套循环 Block Nested Loop 导致索引查询慢
- MySQL增加日志统计表优化各种日志表的统计功能
- MySQL单机读写QPS(性能)优化
- sqlMode 置 select 的值可以比 group 里的多
- drop、delete、truncate的区别
- 尚硅谷MySQL数据库高级学习笔记
- MySQL架构
- 事务部分
- MySQL知识点
- mysql索引
- Linux docker安装 mysql 8.0.25
- docker 安装mysql 5.7
- mysql Field ‘xxx’ doesn’t have a default value
- mysql多实例
- docker中的sql文件导入
- mysql进阶知识
- mysql字符集
- 连接的原理
- redo日志
- InnoDB存储引擎
- InnoDB的数据存储结构
- B+树索引
- 文件系统-表空间
- Buffer Pool
- 亿级数据导入到es
- MySQL数据复制
- MySQL缺少主键的表数据
- mysql update 其中更新的字段根据另一个更新字段作为条件去更新
- MySQL指定字段值排序(将指定值排在前面)
- 设置MySQL连接数、时区
- Navicat15右键删除数据刷新就又恢复了
- MySQL替换字段部分内容
- Java和MySQL统计本周本月本季和年
- 分页时order by 排序数据重复,丢失
- mysql同一张表根据某个字段删除重复数据
- mysqldump定时全量热备
- 专题总结
- 事务
- MySQL事务
- spring事务
- spring事务本类调用
- spring事务传播行为
- spring事务失效问题
- 锁和Transactional注解一块使用的问题
- 数据安全
- 敏感数据
- SQL注入
- 数据源
- XSS
- 接口设计
- 缓存设计
- 限流
- 自定义注解实现根据用户做QPS限流
- 架构
- 高可用
- Java
- Unsatisfied dependency expressed through field ‘baseMapper‘
- mybatisplus多数据源
- 单个字母前缀的java变量
- spring
- spring循环依赖解决
- 事务@Transactional
- yml 文件配置信息绑定到java工具类的静态变量上
- @Configuration @Component 区别
- springboot启动yml文件报错
- spring方法重试注解Retryable
- spring读取yml集合数据
- spring自定义注解
- 获取resource下的图片资源
- 手机号和电话号的正则验证
- 获取字符串中的数字
- mybatis
- mybatis多参数添加数据并返回主键
- 统一异常处理
- 分组校验
- Java读取Python json.dumps 函数保存的redis数据
- springboot整合springCache
- 若依mybatis值为null的字段没有返回
- 若依
- 接口白名单
- @JsonFormat时区问题
- RequestParam.value() was empty on parameter 0
- jdk8和hutool请求第三方的https报错
- springMVC
- springMVC与vue使用post传数组
- elementUI 时间组件报错问题
- vue具名插槽slot
- springboot配置maven的profiles(配置微服务多环境切换打包)
- resources 配置文件读取顺序
- Windows的cmd部署jar注意事项
- Java基础
- JUC(锁-并发-线程池)
- CAS
- Java 锁简介
- synchronized和Logk有什么区别?用新的ock有什么好处
- synchronized锁介绍
- CompletableFuture
- 多线程
- 线程池
- 集合类
- map见过的小问题
- 退出双层循环
- StringBuilder和StringBuffer核心区别
- 日志打印
- 打印log日志
- log日志文件生成配置
- 日期时间
- 时间戳转为时间
- 并发工具
- 连接池
- http调用
- 内网访问天地图
- 判等问题
- 数值计算
- null问题
- 异常处理
- 文件IO
- 序列化
- 内存溢出OOM
- 子线程的错误, 全局异常处理捕获不到
- vue同一个项目访问多个不同ip地址接口
- Autowired注解导入为null
- shiro
- UnavailableSecurityManagerException错误
- Windows服务器80端口被占用
- java图片增加水印
- springcloud
- Feign方法配置错误导致jar包启动失败
- feign调用超时
- 定时任务quartz
- JavaPOI导出Excel
- 合并行和列
- 设置样式
- 设置背景色
- docker
- Linux 安装
- docker命令
- docker网络
- docker数据卷
- dockerfile
- docker安装ping命令
- docker-compose
- docker-compose文件内容介绍
- Linux关闭docker开机启动
- jar打包为镜像
- 迁移docker容器存储位置
- Nginx
- Linux在线安装Nginx
- nginx.conf 核心配置文件
- vue 和 nginx 刷新页面会报404
- nginx 转发给三个集群的tomcat
- ServerName匹配规则
- Nginx负载均衡策略
- location 匹配规则
- Nginx 搭建前端调用后台接口的集群
- alias与root
- nginx 拦截 post 请求, 带参数转发到前端页面
- 防盗链配置
- Nginx的缓存
- 通用Nginx配置
- nginx配置文件服务器
- 后台jar包得不到正确ip,nginx代理时要处理
- 升级使用websocket协议
- 设置IP黑/白名单
- Redis
- 缓存数据一致性
- 内存淘汰策略
- Redis数据类型
- gmt6
- Linux安装GMT6
- GMT6配置中文
- GMT文件修改Windows版本到Linux版本
- 注意GMT不同字体导致符号不同的问题
- GMT绘制南海诸岛小图
- GMT生成中文图例
- elasticsearch
- 安装配置
- Linux安装配置elasticsearch7.6.2
- Linux 安装 kibana 7.6.2
- 安装7.6.2中文分词器
- docker 安装elasticsearch7.6.2
- 安装Logback7.6.2
- springboot使用
- 0. elasticsearch账号密码模式访问
- 1. 配置连接
- 2. 索引
- 3. 批量保存更新
- Result window is too large 10000
- elasticsearch 分词的字段做排序 fielddata, 设置fielddata=true 无效果
- elasticsearch 完全匹配查询(精确查询)
- 模糊搜索
- 日期区间查询
- 6.x基础知识
- 自定义词库
- elasticsearch集群
- 搜索推荐Suggester
- 查询es保存的数组
- 亿级mysql数据导入到es
- es 报错 ORBIDDEN/12/index read-only
- es核心概念
- es的分布式架构原理
- 优化大数据量时的ES查询性能
- canal
- 1. mysql的Binlog
- 2. Canal 的工作原理
- 3. canal同步es
- JVM
- 1 类的字节码
- 2. 类的加载
- JVM知识点
- Maven
- 依赖冲突
- xxl-job
- docker 安装配置 xxl-job
- idea
- springboot启动报错命令过长
- services统一启动微服务各模块
- 云服务器安装宝塔面板
- 突然出现启动或者运行特别慢
- 有导入依赖但是显示红色同时点击进去也有依赖
- Linux
- sh文件执行报错: command not found
- 使用vagrant安装虚拟机
- Linux 开启端口
- 开放端口
- 复制文件夹及其文件到另一个文件夹
- 两个服务器之间映射端口
- TCP协议
- 分层模型
- TCP概述
- 支撑 TCP 协议的基石 —— 首部字段
- 数据包大小对网络的影响 —— MTU 与 MSS 的奥秘
- 端口号
- 三次握手
- TCP 自连接
- 四次挥手
- TCP 头部时间戳
- 分布式
- 分布式脑裂问题
- 分布式事务
- 基础知识
- 实现分布式事务的方案
- 阿里分布式事务中间件seata
- 幂等性问题
- 其他工具
- webstorm git提交代码后project目录树不显示
- 消息队列
- 如何保证消费的顺序
- 数据结构
- 漫画算法:小灰的算法之旅