MySQL第一讲-mysql的基本框架和查询命令流程

MYSQL的结构

MySQL 的基本架构示意图
在这里插入图片描述
总体来说,MySQL 可以分为 Server 层存储引擎层两部分。

Server 层包括
连接器、查询缓存、分析器、优化器、执行器等,
涵盖 MySQL 的大多数核心服务功能,以及所有的内置函数(如日期、时间、数学和加密函数等),所有跨存储引擎的功能都
在这一层实现,比如存储过程触发器、视图等。

存储引擎层负责数据的存储和提取
其架构模式是插件式的,支持 InnoDB、MyISAM、Memory 等多个存储引擎。现在最常用的存储引擎是 InnoDB,它从 MySQL 5.5.5 版本开始成为了默认存储引擎

 create table 语句中使用 engine=memory可指定使用memory等其他引擎

1.连接器

连接器负责跟客户端建立连接、获取权限、维持和管理连接。

 mysql -h$ip -P$port -u$user -p

连接命令中的 mysql 是客户端工具,用来跟服务端建立连接。在完成经典的 TCP 握手后,连接器就要开始认证你的身份,这个时候用的就是你输入的用户名和密码。

长连接和短连接

数据库里面,长连接是指连接成功后,如果客户端持续有请求,则一直使用同一个连接。

短连接则是指每次执行完很少的几次查询就断开连接,下次查询再重新建立一个。

但是全部使用长连接后,你可能会发现,有些时候 MySQL 占用内存涨得特别快,这是因为
MySQL 在执行过程中临时使用的内存是管理在连接对象里面的。这些资源会在连接断开的时候
才释放。所以如果长连接累积下来,可能导致内存占用太大,被系统强行杀掉(OOM),从现
象看就是 MySQL 异常重启了。

怎么解决这个问题呢?你可以考虑以下两种方案。
1. 定期断开长连接。使用一段时间,或者程序里面判断执行过一个占用内存的大查询后,断开
连接,之后要查询再重连。

2. 如果你用的是 MySQL 5.7 或更新版本,可以在每次执行一个比较大的操作后,通过执行
mysql_reset_connection 来重新初始化连接资源。这个过程不需要重连和重新做权限验
证,但是会将连接恢复到刚刚创建完时的状态。

2、查询缓存

(8.0版本后已经彻底没有这个功能了。)
MySQL 拿到一个查询请求后,会先到查询缓存看看,之前是不是执行过这条语句。之前执行过
的语句及其结果可能会以 key-value 对的形式,被直接缓存在内存中
。key 是查询的语句,
value 是查询的结果。如果你的查询能够直接在这个缓存中找到 key,那么这个 value 就会被直
接返回给客户端。

但是每次有update操作后,会把全表的查询缓存清理掉,所以经常有缓存失效,导致查询缓存命中率很低,弊大于利

你可以将参数 query_cache_type 设置成
DEMAND,这样对于默认的 SQL 语句都不使用查询缓存。

mysql> select SQL_CACHE * from T where ID=10;

MySQL 8.0 版本直接将查询缓存的整块功能删掉了,也就是说 8.0 开始彻底没有这个功能了。

3、分析器

如果没有命中查询缓存,就要开始真正执行语句了。首先,MySQL 需要知道你要做什么,因此需要对 SQL 语句做解析。

MySQL 从你输入的"select"这个关键字识别出来,这是一个查询语句。它也要把字符串“T”识别成“表名 T”,把字符串“ID”识别成“列 ID”。

做完了这些识别以后,就要做“语法分析”。根据词法分析的结果,语法分析器会根据语法规
则,判断你输入的这个 SQL 语句是否满足 MySQL 语法。不符合则给出错误提示

4、优化器

经过了分析器,MySQL 就知道你要做什么了。在开始执行之前,还要先经过优化器的处理.

优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。比如你执行下面这样的语句,这个语句是执行两个表的join:

 mysql> select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
  • 既可以先从表 t1 里面取出 c=10 的记录的 ID 值,再根据 ID 值关联到表 t2,再判断 t2 里面
    d 的值是否等于 20。
  • 也可以先从表 t2 里面取出 c=20 的记录的 ID 值,再根据 ID 值关联到 t1,再判断 t1 里面 c
    的值是否等于 10。

这两种执行方法的逻辑结果是一样的,但是执行的效率会有不同,而优化器的作用就是决定选择
使用哪一个方案。

5、执行器

MySQL 通过分析器知道了你要做什么,通过优化器知道了该怎么做,于是就进入了执行器阶段,开始执行语句。

mysql> select * from T where ID=10;
  1. 要先判断一下你对这个表 T 有没有执行查询的权限,如果没有,就会返回没有权限的错误,如下所示。
ERROR 1142 (42000): SELECT command denied to user 'b'@'localhost' for table 'T'

2.执行流程

  • a. 调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 10,如果不是则跳过,如果
    是则将这行存在结果集中;
  • b. 调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。
  • c. 执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是示例代码: 1. 添加依赖 在 `pom.xml` 文件中添加以下依赖: ```xml <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.13</version> </dependency> ``` 2. 配置分页插件 在 `application.yml`(或 `application.properties`)文件中添加以下配置: ```yaml mybatis: configuration: # 开启驼峰命名规则 map-underscore-to-camel-case: true # 分页插件配置 plugins: - interceptor: # 指定使用的分页插件 type: com.github.pagehelper.PageInterceptor # 配置分页插件参数 properties: # 分页合理化参数,默认为false,如果设置为true,pageNum<=0时会查询第一页,pageNum>pages(超过总数时),会查询最后一页 reasonable: true # 支持通过Mapper接口参数来传递分页参数,默认为false,如果设置为true,会从Mapper方法的参数中自动根据参数名提取pageNum和pageSize作为分页参数 support-methods-arguments: true ``` 3. 编写Mapper接口 ```java @Mapper public interface UserMapper { @Select("SELECT * FROM user") List<User> findAll(); } ``` 4. 编写Service类 ```java @Service public class UserService { @Autowired private UserMapper userMapper; public PageInfo<User> findUsersByPage(int pageNum, int pageSize) { // 使用PageHelper.startPage方法设置分页参数 PageHelper.startPage(pageNum, pageSize); List<User> userList = userMapper.findAll(); // 使用PageInfo对查询结果进行封装,包括分页信息和查询结果 return new PageInfo<>(userList); } } ``` 5. 编写Controller类 ```java @RestController public class UserController { @Autowired private UserService userService; @GetMapping("/users") public PageInfo<User> findUsersByPage(@RequestParam("pageNum") int pageNum, @RequestParam("pageSize") int pageSize) { return userService.findUsersByPage(pageNum, pageSize); } } ``` 以上代码中,使用了PageHelper插件来进行分页查询。在Mapper接口中,只需要编写普通的SQL语句即可。在Service类中,使用PageHelper.startPage方法设置分页参数,再调用查询方法获取查询结果,最后使用PageInfo对查询结果进行封装。在Controller类中,接收请求参数,调用Service类的分页查询方法,并返回结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值