Mysql进阶学习

目录

一.Mysql服务器内部架构(了解)

二.Mysql引擎

2.1 innodb引擎

2.2 myisam引擎

三.索引

3.1索引分类

3.2mysql索引数据结构

3.3聚簇索引和非聚簇索引

3.4回表查询 

3.5索引下推

四.事务

数据库事务特征

事务隔离性,隔离级别

事务实现原理

 五.锁

①全局锁

②表级锁

③行级锁

六.sql优化


一.Mysql服务器内部架构(了解)

连接层负责客户端的链接,验证账号密码等授权认证。
服务层对sql进行解析,优化,调用函数,如果是查询操作,有没有缓存等操作。
引擎层

是真正负责数据存储和提取的地方,mysql中提供多种引擎进行数据处理,可以根据需要进行选择。

物理文件存储层物理存储表数据,以及各种日志文件的地方。


二.Mysql引擎

mysql中的引擎就是实际对数据操作的一种实施者,不同的引擎的所使用的技术不同。

查询引擎种类sql语句:SHOW ENGINES;

主要讲innodb引擎myisam引擎

2.1 innodb引擎

        是一个综合能力比较强的引擎,支持事务,行级锁,外键约束,全文索引,支持数据缓存等功能。

        支持主键自增,不存储表的总行数(统计表的总行数,innodb中默认不存储,需要自己查询)。

适合增删改较多,且数据重要的场景。

2.2 myisam引擎

        不支持事务,只支持表锁,增,删,改操作时会锁定整个表效率低,适合查询较多的情况,支持全文索引,存储表的总行数。


三.索引

什么是索引?

数据库索引是为了实现高效数据查询的一种排好序的数据结构

索引类似于书的目录,通过目录可以快速的定位到想要找到的数据。

因为一张表中的数据会有很多,如果直接去表中检索数据会效率低(逐行查找),所以需要为表中的数据建立索引(一般主键默认会创建索引),这样就会提高查询效率。

索引优势

        通过索引可以快速定位到数据,降低IO次数,提高效率。排序列添加索引,也可以提高排序的效率(因为索引是有序的)

索引劣势

        索引保存也是需要占用空间的。增删改数据时,数据发生变化,索引也需要随之变动,也是需要开销的。

索引创建原则

哪些场景适合

①主键自动创建索引

②查询条件列

③多使用组合索引(多个列用一个索引),减少单值索引

④建议排序和分组使用到的列

⑤对数据量大的表

哪些场景不适合

①表中数据比较少(类型表,菜单表,友情链接,系统信息表)

②查询条件中用不到的列

增删改频率高的表

④重复率高的列(性别:男,女)

3.1索引分类

①主键索引

创建表时,设置哪个列为primary key 就是主键列,主键列默认会自动创建索引。

create table test1(id int  primary key auto_increment,  -- 创建表时直接设置主键account varchar(20) unique    -- 设置唯一约束,  会添加唯一索引
)create table test2(id int
)ALTER TABLE test2 add PRIMARY KEY test2(id);    -- 后来修改表结构,设置主键
ALTER TABLE test2 drop PRIMARY KEY ;     -- 删除主键

②唯一索引

设置某个列数据唯一性,会创建唯一索引。

create table test1(id int primary key auto_increment,  -- 创建表时直接设置主键account varchar(20) unique    -- 设置唯一约束,  会添加唯一索引
)--test2表
CREATE UNIQUE INDEX index_unique_account ON test2(account);  -- 创建表时未添加索引,后面修改表添加唯一索引

③单值索引

一个索引中,只包含一个列。

--对单列添加单一索引
--index_test1_name:索引名
create index index_test1_name on test1(name)  ​
drop index index_test1_name on test1  -- 删除索引sql

④组合索引(复合索引)

一个索引中包含多个列,节省了索引开支。

--给两个列添加组合索引
create index index_test1_name_age on test1(name,age)

!注意: 满足组合索引最左前缀原则

在使用组合索引时, 条件中必须要用到最左侧的列,否则索引失效

例如 a,b,c 3个列,a 和 b 创建组合索引

create index index_test1_a_b on test1(a,b)

由于a在b的左侧,故只有使用a作为查询条件时,索引才会生效。

where a = 1 and b = 2 索引生效

where b = 2 and a= 1 索引生效

where a = 1 and c = 2 索引生效

where b = 1 and c = 2 索引不生效

在查询sql语句前使用explain可查看sql执行计划

explain select * from test3 where b=2 and c=3   --查看sql执行计划

⑤前缀索引

有些列长度比较大,需要只给前面指定的长度区间添加索引即可。

create index 索引名 on 表名(列名(长度))--给test表的title列的前5个字符创建索引名为index_test_title的索引
例:create index index_test_title on test(title(5))

⑥全文索引

模糊查询时,即使列有索引,也会导致索引失效。

可以为列添加全文索引

-- 在test 表的 title 列上创建一个全文索引-- ngram:解析器
CREATE FULLTEXT INDEX index_test_title ON test(title) WITH PARSER ngram;explain SELECT * FROM test WHERE MATCH(title) AGAINST('中国')

3.2mysql索引数据结构

        由于二叉树和平衡二叉树一个节点只能存储一个元素,再加上mysql使用自增主键,导致不适合使用二叉树或平衡二叉树。所以mysql底层使用的是B+树

原因:

①一个节点中可以存储多个索引数据。

②表数据都存储在叶子节点,非叶子节点不存储表数据,只存索引,这样一个节点就可以存储更多的索引。

③叶子节点之间还有指针指向,所以非常适合范围查询

3.3聚簇索引和非聚簇索引

        聚簇索引:数据表的数据会按照聚簇索引的顺序存储。每个表只能有一个聚簇索引,因为数据只能按一种顺序存储。

innodb引擎中主键索引,就是聚簇索引,主键和数据在一个树上。

        非聚簇索引数据表的数据顺序和索引顺序无关,索引是单独存储的,里面存的是索引值和指向数据的地址

        myisam引擎中,由于索引和数据分别在两个不同的文件中存储,找到了索引,还需要重新查找一次才能找到数据,这种称为非聚簇索引。

innodb引擎中,像普通的索引也称为二级索引,他们也是非聚簇索引。

        例如姓名,通过名字查找人的所有信息时,在姓名索引树中找到后,还需要在主键索引树再次进行查找,最终在主键索引树中找到数据,这种称为非聚簇索引。

3.4回表查询

回表查询指的是查询时的次数。

例如:学生有id,学号,姓名三个信息,设定id是主键,学号添加唯一索引。

select * from student where id = 1

        ① 通过id(主键)查询学生所有的信息, 这时只需要查询一次即可。

select * from student where 学号 = 12

        ②通过学号查询学生所有信息,由于学号是普通索引,先通过学号,在学号索引树上找学号,然后再通过id去回表二次查询主键索引树,查询两次, 称为回表查询了。

select 学号 from student where 学号 = 12 

        ③通过学号查询学号自己(判断学号是否存在),由于使用学号只查询学号本身,并不查询其他数据,这种情况下,可以在学号索引树上直接找到学号数据,这种情况不需要回表查询了。

 

3.5索引下推

        mysql5.6版本引入的一项查询优化技术,将条件筛选过程下推到索引树上

        以前没有索引下推,先找具体的数据,然后再对数据进行条件过滤,查询的数据范围就比较大。

        使用索引下推,直接在索引树上进行条件筛选,筛选出符合条件的记录,然后只将满足条件的记录进行回表查询,减少了回表查询的次数。适用的是非主键索引

索引扫描(找索引) - - > 索引条件过滤(过滤索引) - - > 回表操作(查询数据) - - > 剩余条件过滤(查其他数据)

--建立索引
create index index_name on employee(name)-- 使用索引下推
select * from employee where name like "张%" and salary >3000


四.事务

什么是数据库事务?

首先数据库事务是数据库对执行操作的一种管理机制。

数据库事务特征

原子性一次执行的多条sql,是一个不可分割的单元,多条sql要么都执行,要么都不执行,这是事务最基本的特征。
持久性保证事务提交后,数据在数据库是持久保存的,即使操作时,出现宕机。
隔离性

mysql是运行多个并发事务同时对数据进行读和写操作的,这时可以采用不同的隔离级别进行控制。

隔离级别: 读 未提交,读 已提交,可重复读 ,串行化 一次只允许一个事物操作

一致性

数据库事务终极目标,在我们对数据库多次操作的过程中,最终要保证数据和我们预期的结果是一致的。

转账案例:多次对同一个账号的金额进行操作,最终结果不能出现错误的。

MYSQL 事务处理主要有两种方法:
1、用 BEGIN, ROLLBACK, COMMIT 来实现
BEGIN:开始一个事务
ROLLBACK:事务回滚
COMMIT:事务确认
2、直接用 SET 来改变 MySQL 的自动提交模式:
SET GLOBAL (全局)/ SESSION(本次会话) autocommit=0;    --禁止自动提交
SET GLOBAL / SESSION autocommit=1;     --开启自动提交

查看 autocommit 模式

SHOW GLOBAL / SESSION VARIABLES LIKE 'autocommit';

事务隔离性,隔离级别

提供4种隔离级别(读未提交,读已提交,可重复读,串行化,安全级别递增,并发性递减)

        读 未提交 : 一个事务可以读到另一个事务还未提交的数据。虽然并发性是最高的,但也是最不安全的。

        问题: 会出现脏读,不可重复读,幻读问题

        ※ 脏读: A 事物修改了数据,还没提交,这时被B事务读到了,但是A事务有可能出错回滚了,

这种情况下,B事务读到的数据就是垃圾数据。

        读 已提交: 一个事务只能读到另一个事务已提交的数据,能够解决脏读问题,但是没有解决不可重复读和幻读问题。

        不可重复读问题: A事务开启并修改了一个数据,但是并未提交,B事务这时读取到的是未提交的数据,当 A 事务提交事务的时候,B 事务第二次查询的结果与第一次查询的结果不一致,这就是不可重复读。(读取同一个id的数据两次,两次读到的数据不一致)。

        可 重复读:同一个事物读取多次相同数据,多次读取返回的结果是一致的

        可 重复读 解决了 不可重复读问题。

        普通的查询解决了幻读问题,如果在查询语句后面添加了 for update,就会出现幻读问题。

        幻读问题同一个事务中,多次读取数据,读到行数不同。

        mysql中默认隔离级别是可 重复读。 

        串行化相当于加锁了,解决以上所有的问题,当一个事务操作时,其他事务必须等待,即使执行的是查询操作。

事务实现原理

        持久性实现使用到redo log日志文件(重做日志) 保证已提交事务的数据持久保存。

        当事务提交后,先用redo log日志文件进行存储,因为在此过程中,有可能宕机,如果此时宕机,确保操作数据存储记录下来(日志文件中),这样在服务恢复时,可以继续将日志文件中的数据,写入到物理硬盘上。

        原子性实现: 使用到undo log 日志文件(回滚日志),当我们执行一个insert语句时,在undo log 日志文件中记录一个delete语句,执行delete语句,在日志文件中记录insert语句,记录一个操作的反向操作,当事务回滚时,执行undo log 日志中的反向操作。

        隔离性实现:提到了MVCC机制(多版本并发控制),每次事务对数据操作时,都会记录一个历史记录(记录事务id,还会记录上一次操作事务id)。

        还提到了一个readView(读视图),当隔离级别为 读 已提交时:在一个事物中,每次读时,都会从历史版本记录中,获取一个最新的快照,这样,就会导致每次读到的是最新的数据,也就会出现不可重复读问题

        当隔离级别为 可 重复读时,在第一次读时,会获取一个快照,之后再次读取时,还是从第一次生成的快照中读数据。所以,两次读到数据是一样的,解决了不可重复读。

        一致性实现以上是三个都满足,既可实现一致性。


 五.锁

        mysql中读写不互斥(前提是没有使用串行化隔离级别),但是写写操作是互斥的,mysql中使用锁机制来实现写写互斥。

按照锁的粒度分为:

①全局锁

 锁定整个数据库,只允许读操作

一般在备份数据库时使用

FLUSH TABLES WITH READ LOCK  --添加全局锁UNLOCK TABLES;  -- 释放全局锁

备份数据库语句 :(再cmd命令窗口里执行)

mysqldump --single-transaction -uroot -proot 库名> E:/文件名.sql

②表级锁

给整个加锁

myisam引擎只支持表锁,innodb默认支持行锁

③行级锁

加锁的粒度以为单位。

行级锁又可以分为:

行锁: 只锁定操作的那一行数据,使用的主键作为条件(防止同一行数据被多个事务修改或删除)。

间隙锁: 锁定的是一个范围 。如: id>2 and id <6,表里的id有(1,2,4,5,10),那么当开启事务时,id范围(2,4)和id范围(5,10)的数据是不能插入的。因为你的数据库表里根本就没有6这个id数据,只能通过下一个索引的顺序(10)进行加锁。索引的顺序 加锁,而不是按查询条件加锁。     (防止幻读)

临键锁: 是行锁和间隙锁的组合(为了防止幻读并防止数据冲突)。

行锁又分为:

①共享锁:

        主要是为查询语句添加的,为查询语句如果添加了共享锁,那么其他事务可以读,但是其他事务不能写的(指定的是同一条记录)。(其他事务可读不可写)

select * from employees where id = 1 lock in share mode; --为查询语句添加共享锁

读锁,允许多个事务读,不允许读写同时进行。

②排他锁: 就是互斥锁,当一个事务操作时,其他事务就不能进行加共享锁和排他锁操作。

👉其他事务无论是共享锁还是排他锁,排他锁都会阻止任何其他类型的锁。

        insert ,update,delete操作时,自动会添加排他锁。

👉查询操作如果需要添加排他锁,可以在查询语句后面添加 for update 语句

select * from employees where id = 1 for update  --为查询语句添加排他锁

 


六.sql优化

1.查询 SQL 尽量不要使用 select *,而是具体字段。
2 尽量使用数值替代字符串类型。
3. 使用 varchar 代替 char。
4. 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by,group by 涉及的列上建立索引。
5. 应尽量避免索引失效。
6. 提高 group by 语句的效率。
反例:先分组,再过滤
正例:先过滤,后分组
7. 清空表时优先使用 truncate
truncate是以表为单位删除表的所有数据 ,且使用的系统和事务日志资源少。
delete 语句每次删除一行,并在事务日志中为所删除的每行记录一项。
8. 表连接不宜太多,索引不宜太多,一般 5 个以内。
9. 深度分页问题
反例
select id,name from account limit 100000,10;
正例
select id,name FROM account where id > 100000 order by id limit 10;

10. 使用 explain 分析 SQL 执行计划

重点关注:possible_keys(显示可能应用在这张表中的索引,一个或多个),key(实际使用的索引。如果为 NULL,则没有使用索引,或者索引失效)

 感谢你的阅读与关注,如有问题欢迎探讨!💓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/69730.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解锁维特比算法:探寻复杂系统的最优解密码

引言 在复杂的技术世界中&#xff0c;维特比算法以其独特的魅力和广泛的应用&#xff0c;成为通信、自然语言处理、生物信息学等领域的关键技术。今天&#xff0c;让我们一同深入探索维特比算法的奥秘。 一、维特比算法的诞生背景 维特比算法由安德鲁・维特比在 1967 年提出…

使用 postman 测试思源笔记接口

思源笔记 API 权鉴 官方文档-中文&#xff1a;https://github.com/siyuan-note/siyuan/blob/master/API_zh_CN.md 权鉴相关介绍截图&#xff1a; 对应的xxx&#xff0c;在软件中查看 如上图&#xff1a;在每次发送 API 请求时&#xff0c;需要在 Header 中添加 以下键值对&a…

sizeof和strlen的对比与一些杂记

1.sizeof和strlen的对比 1.1sizeof &#xff08;1&#xff09;sizeof是一种操作符 &#xff08;2&#xff09;sizeof计算的是类型或变量所占空间的大小&#xff0c;单位是字节 注意事项&#xff1a; &#xff08;1&#xff09;sizeof 返回的值类型是 size_t&#xff0c;这是一…

实测数据处理(Wk算法处理)——SAR成像算法系列(十二)

系列文章目录 《SAR学习笔记-SAR成像算法系列&#xff08;一&#xff09;》 《wk算法-SAR成像算法系列&#xff08;五&#xff09;》 文章目录 前言 一、算法流程 1.1、回波信号生成 2.2 Stolt插值 2.3 距离脉冲压缩 2.4 方位脉冲压缩 2.5 SAR成像 二、仿真实验 2.1、仿真参数…

FFmpeg rtmp推流直播

文章目录 rtmp协议RTMP协议组成RTMP的握手过程RTMP流的创建RTMP消息格式Chunking(Message 分块) rtmp服务器搭建Nginx服务器配置Nginx服务器 librtmp库编译推流 rtmp协议 RTMP&#xff08;Real Time Messaging Protocol&#xff09;是由Adobe公司基于Flash Player播放器对应的…

docker搭建redis集群(三主三从)

本篇文章不包含理论解释&#xff0c;直接开始集群&#xff08;三主三从&#xff09;搭建 环境 centos7 docker 26.1.4 redis latest &#xff08;7.4.2&#xff09; 服务器搭建以及环境配置 请查看本系列前几篇博客 默认已搭建好三个虚拟机并安装配置好docker 相关博客&#xf…

接口使用实例(2)

大家好&#xff0c;今天我们来解答一下昨天留下的一个问题&#xff0c;并且继续来看一些接口使用实例。 通过String类中重写的方法compareTo来实现我们的比较name的需求&#xff1a; 2,用Comparator接口来实现类的比较(比较器) 了解即可&#xff0c;以后会详细讲。 知识点:C…

基于Springboot的社区药房管理系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业多年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实…

vue框架技术相关概述以及前端框架整合

vue框架技术概述及前端框架整合 1 node.js 介绍&#xff1a;什么是node.js Node.js就是运行在服务端的JavaScript。 Node.js是一个事件驱动I/O服务端JavaScript环境&#xff0c;基于Google的V8引擎。 作用 1 运行java需要安装JDK&#xff0c;而Node.js是JavaScript的运行环…

MATLAB的数据类型和各类数据类型转化示例

一、MATLAB的数据类型 在MATLAB中 &#xff0c;数据类型是非常重要的概念&#xff0c;因为它们决定了如何存储和操作数据。MATLAB支持数值型、字符型、字符串型、逻辑型、结构体、单元数组、数组和矩阵等多种数据类型。MATLAB 是一种动态类型语言&#xff0c;这意味着变量的数…

密码强度验证代码解析:C语言实现与细节剖析

在日常的应用开发中&#xff0c;密码强度验证是保障用户账户安全的重要环节。今天&#xff0c;我们就来深入分析一段用C语言编写的密码强度验证代码&#xff0c;看看它是如何实现对密码强度的多维度检测的。 代码整体结构 这段C语言代码主要实现了对输入密码的一系列规则验证&a…

蓝桥杯模拟算法:多项式输出

P1067 [NOIP2009 普及组] 多项式输出 - 洛谷 | 计算机科学教育新生态 这道题是一道模拟题&#xff0c;我们需要分情况讨论&#xff0c;我们需要做一下分类讨论 #include <iostream> #include <cstdlib> using namespace std;int main() {int n;cin >> n;for…

Pytorch框架从入门到精通

目录 一、Tensors 1.1 初始化一个Tensor 1&#xff09;赋值初始化 2&#xff09;从 NumPy 数组初始化 3&#xff09;从另一个张量 4&#xff09;使用随机值或常量值 1.2 Tensor 的属性 1.3 对 Tensor 的操作 1.3.1 总体介绍 1.3.2 索引和切片 1.3.3 算术运算 矩阵乘…

2024年数据记录

笔者注册时间超过98.06%的用户 CSDN 原力是衡量一个用户在 CSDN 的贡献和影响力的系统&#xff0c;笔者原力值超过99.99%的用户 其他年度数据

【已解决】黑马点评项目Redis版本替换过程的数据迁移

黑马点评项目Redis版本替换过程的数据迁移 【哭哭哭】附近商户中需要用到的GEO功能只在Redis 6.2以上版本生效 如果用的是老版本&#xff0c;美食/KTV的主页能正常返回&#xff0c;但无法显示内容 上次好不容易升到了5.0以上版本&#xff0c;现在又用不了了 Redis 6.2的windo…

Win11下帝国时代2无法启动解决方法

鼠标右键点图标&#xff0c;选择属性 点开始&#xff0c;输入启用和关闭

android主题设置为..DarkActionBar.Bridge时自定义DatePicker选中日期颜色

安卓自定义DatePicker选中日期颜色 背景&#xff1a;解决方案&#xff1a;方案一&#xff1a;方案二&#xff1a;实践效果&#xff1a; 背景&#xff1a; 最近在尝试用原生安卓实现仿element-ui表单校验功能&#xff0c;其中的的选择日期涉及到安卓DatePicker组件的使用&#…

SpringBoot 基础(Spring)

SpringBoot 基础&#xff08;Spring) Bean 注解标记和扫描 (IoC) 配置类概念 SpringBootConfiguration 或者 Configuration 注解标注的类就是配置类配置类本身也会加入 IoC 容器* Configuration public class configuration1 {}SpringBootConfiguration public class configur…

【数据结构与算法】九大排序算法实现详解

文章目录 Ⅰ. 排序的概念及其运用一、排序的概念二、常见的排序算法三、排序算法的接口四、测试算法接口附&#xff1a;Swap接口&#xff08;使用异或的方法实现&#xff09; Ⅱ. 排序算法的实现一、插入排序二、希尔排序( 缩小增量排序 )三、选择排序四、堆排序五、冒泡排序六…

Ansys Maxwell:采用对称性的双转子轴向磁通电机

轴向磁通电机因其功率密度高于相同重量的传统径向磁通电机而变得非常受欢迎&#xff0c;并且在电动汽车和航空应用中非常高效且具有成本效益。功率密度是输出功率与机器体积的比率。对于给定尺寸的机器&#xff0c;轴向磁通电机提供更大的扭矩和功率&#xff0c;或者对于给定的…