当前位置: 首页 > news >正文

MySQL进阶 面试速记

存储过程,自定义函数在现在的数据库使用中,就很少使用了

MySQL 架构

authentication 认证 身份认证 账号密码验证-->token

authorisation 授权 -->分配权限菜单

连接层

在mysql服务中,负责客户端连接,进行身份认证,授权

服务层

在服务层进行sql分析,优化,各种逻辑的处理等.

引擎层

引擎层是实际负责数据存储和提取操作. mysql提供了不同的引擎(处理方式),可以根据需要进行选择

物理文件存储层

实际的文件存储, 包括存储数据的文件,还有各种日志文件

mysql引擎

引擎就是实际的负责数据存储和提取操作的一种实现方式,不同引擎实际处理方式不同,

mysql中提供多种引擎.

mysql中有以下引擎:

InnoDB: 支持事务(安全可靠),支持行级锁(锁的粒度小,并发量高),支持外键约束,支持全文索引,

支持数据缓存,提高查询的效率, 不存储总行数( select count(*) from table 统计总行数 逐行统计)

MyISAM :

myisam不支持事务,不支持外检,不支持行级锁, 支持表锁(并发量低), 适合写少,查询多的场景.

支持全文索引, 存储表的总行数

索引

什么是索引

索引是一种有序的数据结构,可以帮助mysql快速的查找到数据.

如果数据库中的数据量非常大,那么逐页,逐行查询效率就很低.

索引类似于书的目录,可以帮助我们快速的定位到具体的页数.

索引优势/劣势

优点: 可以快速的定位到数据,减少于硬盘的IO成本

由于索引已经排好序了,减少排序成本.

缺点: 索引信息也是需要占用空间的, 当数据发生改变时(新增,删除)那么索引信息也要发生改变.索引虽好,不能乱用.

索引创建原则

哪些情况需要创建索引

主键自动建立唯一(主键)索引

作为查询条件的列 列如姓名,电话

尽量使用联合索引(几个列添加一个索引),减少单列索引

数据量较大的表,

排序和分组使用的字段

哪些情况不要创建索引

如果数据量很小,没必须加索引(例如新闻类型, 数据量很少)

频繁修改的表,不仅要修改数据,还要修改索引

不是查询条件的列就不要加索引了

重复出现很多的数据,例如性别

索引分类

如何在表中加索引

主键索引

把某个列设置为主键后,自动创建主键索引,

-- 创建表时添加注解索引
CREATE TABLE test(
   id INT  PRIMARY KEY
)
-- 修改表结构,添加主键
ALTER TABLE test ADD PRIMARY KEY test(id)
-- 删除主键
ALTER TABLE test DROP PRIMARY KEY ;

唯一索引

CREATE UNIQUE INDEX 索引名 ON 表名(列名);
​
DROP INDEX 索引名 ON test;

单值索引

一般的列多数添加的都是单值索引,用的最多的.

CREATE INDEX 索引名 ON 表名(列名);
​
DROP INDEX 索引名 ON 表名;

组合索引(复合索引):

一个索引中包含多个列,降低索引开销(推荐)

CREATE INDEX 索引名 ON 表名(列 1,列 2...);
​
DROP INDEX 索引名 ON 表名;

组合索引使用时,需要满足组合索引最左前缀原则,

ALTER TABLE test ADD COLUMN a VARCHAR(8);
ALTER TABLE test ADD COLUMN b VARCHAR(8);
ALTER TABLE test ADD COLUMN c VARCHAR(8);
​
​
CREATE INDEX test_a_b_index ON test(a,b);
​
EXPLAIN SELECT * FROM test WHERE a='1' AND b='1'  索引生效
EXPLAIN SELECT * FROM test WHERE a='1' AND c='1'  索引生效
EXPLAIN SELECT * FROM test WHERE b='1' AND c='1'  没有使用最左列,索引失效
​
通过EXPLAIN关键字查看sql执行计划
EXPLAIN SELECT * FROM test WHERE NAME = '1'
EXPLAIN SELECT * FROM test WHERE NAME LIKE '%1%'

前缀索引

有的列中的内容比较长(新闻摘要,内容),如果给该列建立索引,对索引开销就很大,

给指定长度的区间内容建立索引

create index 索引名 on 表名(列名(长度))

全文索引

解决了mysql中模糊查询索引失效的问题

CREATE FULLTEXT INDEX 索引名 ON test(列) WITH PARSER ngram;
SELECT * FROM 表名 WHERE MATCH(列) AGAINST('搜索词')
EXPLAIN SELECT * FROM 表名 WHERE MATCH(列) AGAINST('搜索词')

索引数据结构

索引结构使用的是B+树.

首先b+树也是有序的,而且一个节点可以存储多个数据,非叶子节点只存储索引数据,

所以每个节点可以存储更多的索引数据,

数据存储在叶子节点,叶子节点直接还有指针指向,更方便范围查询 例如 id>2

聚簇索引和非聚簇索引

聚簇索引:

找到了索引就找到了需要的数据,那么就是聚簇索引.

mysql中innodb引擎中的主键索引就是聚簇索引,

因为数据和索引都在一个文件中存储,主键索引是一级索引,直接与数据绑定

还有像name等其他索引是属于二级索引,如果通过name进行查询学生信息,先在name二级索引树上查找,找到了然后再通过name对应的主键去主键索引树上找到数据,那么这些二级索引属于非聚簇索引.

非聚簇索引:

找打了索引但是还没找到数据,需要再次回表查询,才能找到数据.

innodb中的二级索引属于非聚簇索引.

myisam中索引和数据分别存储在不同的文件中,所以是非聚簇的.

回表查询

回表查询就是查询时,一次并没有查询到我们需要的数据,而是需要再次进行查询.

例如学生信息有id(主键),学号(唯一索引 二级索引),姓名(没有加任何索引),

如果我们通过主键查询学生所有信息,那么是直接可以找到数据的,不需要二次回表查询

如果我们通过学号查询学生所有信息,先在学号索引树上找到学号,以及主键,然后再二次上主键索引树上查找,才能找到数据,就是发生了两次查询,称为回表查询了.

如果我们通过学号只查询学号,可以直接在学号索引树上找到数据,不会二次回表.

索引下推

索引下推是mysql中的一项优化技术,尽量在条件查询时,减少回表查询数量.

将部分条件(有索引的条件)查询 下推到索引扫描阶段.

如果我们查询条件添加了索引,使用索引下推,可以直接在索引树上进行条件筛选,把满足条件的数据进行回表查询,

减少了回表查询的条数.

注意索引下推,查询条件必须是有索引的.

数据库事务

什么是事务?

数据库事务就是对一次数据库操作过程的管理.保证一次与数据库交互过程中执行的多条sql要么都成功执行,要么都不执行,保证原子性.

例如转账,一次转账操作有两个sql,一个给A账号减钱, 一个给B账号加钱,保证两个操作都没有问题

例如购物下订单, 一个是卖家下订单,一个付款.

事务的特征

原子性:保证一次操作中的多条sql在没有问题时,提交事务,多条sql都执行,一旦有问题,事务回滚,回滚到事务开始前的状态.

隔离性:数据库为提高读写的并发性,提供4种隔离级别: 读 未提交,读 已提交,可重复 读,串行化(一个一个来)

持久性:当事务一旦提交后,保证数据的持久化.

一致性: 是事务的终极目标, 以上三点都是为了保证一致性,当多个事务同时对一条数据多次操作时,最终结果与我们预期结一致.

隔离级别

读 未提交: A事务可以读取到B事务还未提交的数据. 并发访问量是最高的

产生问题: 脏读,不可重复读,幻读

脏读,读到的是垃圾数据, A查询到了 B事务还未提交的数据,此时一旦B事务撤消回滚了,数据是无效的.

读 已提交: A事务只能读到B事务已提交的数据,

解决了脏读问题, 但是还存在不可重复读问题,幻读

不可重复读问题: A事务在同一个事务中,读取相同的内容两次,而两次的结果不同.

例如: A事务第一次读id=1,拿到的结果是10,

继续还在这次事务中,又读了一次id=1,结果读到是20,两次结果不同,

可重复 读: A事务在同一个事务中,读取相同的数据两次,两次读到的结果是一致的,即使期间其他的事务修改了数据,并提交了,同一个事务读到了同一个数据的结果是一样的.

解决了 不可重复读问题, 一般的查询也解决了幻读问题.

在查询语句后面,如果添加了for update 这样查询语句,拥有了与新增,修改,删除同等的权利,还是会出现幻读问题.

幻读问题: 同一个事务中,读取了两次,而两次读到数量不一致

串行化: 和加锁一样的,不管是查询也好,还是新增,修改,删除也好,一次只能允许一个事务操作.

两个事务都是读,不互斥

读写,写写都是互斥的.

保证数据安全可靠,但是效率也是最低的.

事务实现原理

持久性: 在事务提交后,先把数据写到redo log日志文件中,再向库中去持久化,一旦期间断电宕机,那么服务恢复后,会将redo log文件中的数据再次写入到库中.

原子性:当执行insert操作时,在undo log日志文件中存储一个相反的delete操作,当事务回滚撤消时,执行相反的操作.

隔离性:

MVCC(多版本并发控制 Multi-Version Concurrent Control)

实现不同的事务在写-读,读写操作时,可以同时进行,提高并发访问能力

每次事务在对数据操作 后,都会在表中的隐式字段中记录当前操作者的id,和上一个记录的回滚指针,从而形成一个版本链.

读视图(readView),从版本链上进行的一个快照.

读 已提交: 称为当前读, 每次读取时,都会获取一个最新的快照, 即使是在同一个事务中的两次读取.都是读到最新内容.

可重复 读:称为快照读,在同一个事务中,第一次查询时,生成一个版本快照(readview),下一次再读取时,还是从快照中读,这样就保证可重复读.

一致性: 由其他三个特性来保障

锁机制

锁机制保证了进行数据操作时,保证写操作安全可靠.

锁按照粒度分:

全局锁: 对数据库进行备份时,锁住整个库

 FLUSH TABLES WITH READ LOCK
 
 mysqldump --single-TRANSACTION -uroot -proot test> E:/文件名.sql
 
 UNLOCK TABLES;

表级锁: 表级锁,就在操作时,会锁住整张表,加锁开销小,但是并发量低.

myisam引擎只支持表锁      myiam适合读多写少的场景

行级锁: 行级锁就是只锁住操作的那一行数据

间隙锁: 对与范围操作的 id>1 and id<10 对此区间间隙进行加锁

按照锁的行为分:

排他锁: (写锁)新增,修改,删除操作时,默认加的就是排他锁,锁住操作的那行数据

查询语句如果执行时,需要添加排他锁,需要在查询语句末尾添加for update

共享锁:(读锁) 是用于给查询语句添加的,如果事务1给行1添加了共享锁,那么其他事务只能给行1添加共享锁

其他事务不能给行1添加排他锁

select ... lock in share mode

Sql 优化

目前讲的只是写sql基本的一些注意事项.

物理删除(真删), delete 操作

逻辑删除(假删),update操作 在表中会有一个列,表示删除状态 0-未删除,1-已删除

1.查询时,只查询需要的列

尽量不使用 select *

2.能使用整数的列,不要使用字符

例如mysql主键 使用int 自增

性别, 可以用0/1表示,

还有各种状态 0- 1- 2- 3-

3.

varchar : 变长字符串 varchar(5) 表示最大上限是5个字符, 实际存储2字符,只占两个字符大小

char: 定长 char(5) 固定存储5个字符, 实际存储2个字符,还是占用5个空间

char一般存储的长度固定的内容,varchar用于存储长度不固定的内容

4.清空表数据

truncate table 比 delete 速度快,且使用的系统和事务日志资源少.

delete 语句每次删除一行,并在事务日志中为所删除的每行记录一项。

truncate table 通过释放存储表数据所用的数据页来删除数据.

5.建立索引

where order by group by 涉及的列添加索引, 提高效率 避免全表扫描

注意创建索引原则

6.避免索引失效

模糊查询, 在条件上使用函数, in,not in or 这些语句导致索引失效

  1. order by写法 先条件筛选,再分组 切勿先分组,再条件筛选

  2. 减少表关联查询的数量, 阿里建议3张表. 索引也不宜过多

  3. 避免深度分页问题

    分页是为了减少每次查询过多数据

    selelct * from table limit 1000000,10 深度分页

select id,name FROM account where id > 100000 order by id limit 10; 先条件过滤,然后再取值

10.使用explain关键字查看sql执行计划

explain select * from test where a = 10

possible_keys : 查询中可以使用的索引

key: 本次查询实际使用到的索引 (查看索引是否有效)

相关文章:

  • 基于 docker 的 LLaMA-Factory 全流程部署指南
  • 开发体育直播即时比分系统:赛事收藏功能的技术实现方案
  • vscode集成deepseek实现辅助编程(银河麒麟系统)【详细自用版】
  • Android学习总结之Kotlin 协程
  • presto行转列
  • Vulnhub-zico2靶机打靶记录
  • ML 聚类算法 dbscan|| OPTICS|mean-shift
  • C语言基础系列【32】指针进阶5:指针与常量
  • 上市电子制造企业如何实现合规的质量文件管理?
  • 0301-组件基础-react-仿低代码平台项目
  • 【AI微信小程序开发】AI减脂菜谱小程序项目代码:根据用户身高/体重等信息定制菜谱(含完整前端+后端代码)
  • 爱心计算器:用 Python 创建带有动态爱心效果的计算器
  • Ubuntu20.04安装OpenVINO环境以及YOLOv8 C++部署测试
  • Android里面内存优化
  • 【Redis】基础1:基本概念,基本数据结构
  • Git操作指南
  • Python数据类型-int
  • JavaScript基础-触屏事件
  • 加密钱包助记词丢失后的一天
  • 在MFC中使用Qt(三):通过编辑项目文件(.vcxproj)实现Qt的自动化编译流程
  • 浙商银行一季度净赚超59亿微增0.61%,非息净收入降逾22%
  • 今年一季度全国城镇新增就业308万人,就业形势保持总体稳定
  • 马上评丨又见酒店坐地起价,“老毛病”不能惯着
  • 书业观察|一本书的颜值革命:从毛边皮面到爆火的刷边书
  • 国家核准10台核电新机组,四大核电央企披露新项目进展
  • 找化学的答案,解人类的命题:巴斯夫的“变革者”成长之道