MySQL索引、事务、与存储引擎
一、索引
1.概念
索引是一个排序的列表,包含索引字段的值和其相对应的行数据所在的物理地址
2.作用
优点
加快表的查询速度
可以对字段排序
缺点
额外占用磁盘空间
更新包含索引的表效率会更慢
3.索引工作模式
没有索引的情况下,要查询某行数据,需要先扫描全表来定位某行数据
有索引后会通过查找条件的字段值找到其索引对应的行数据的物理地址,然后根据物理地址访问相应的数据
4.索引创建条件
1)表中的记录行数较多时,一般超过300行的表建议要有索引
2)建议在 表中的主键字段、外键字段、多表连接使用的字段、唯一性较好的字段,不经常更新的字段、经常出现在where、group by、order by 子语句的字段、小字段 创建索引
3)不建议在 唯一性较差的字段、更新太频繁的字段、大文本字段 上创建索引
5.索引类型
①普通索引
create index 索引名 on 表名 (字段);
alter table 表名 add index 索引名 (字段);
②主键索引
alter table 表名 add primary key (字段);
③唯一索引
create unique index 索引名 on 表名 (字段);
alter table 表名 add unique 索引名 (字段);
④组合索引
create unique index 索引名 on 表名 (字段1, 字段2, 字段3); alter table 表名 add index 索引名 (字段1, 字段2, 字段3);
select ... from 表名 where 字段1=XX and 字段2=xx and 字段3=XX 用 and 做条件逻辑运算符时,要创建组合索引且要满足最左原则
用 or 做条件逻辑运算符时,所有字段都要创建索引
⑤全文索引
create fulltext index 索引名 on 表名 (字段);
alter table 表名 add fulltext 索引名 (字段);
模糊查询: select ... from 表名 where match(字段) against('查询内容');
⑥查看索引
show create table 表名;
show index from 表名;
show keys from 表名;
⑦删除索引
drop index 索引名 on 表名;
alter table 表名 drop index 索引名;
alter table 表名 drop primary key;
⑧索引检测
explain select * from 表名 where 字段=值;
可以用于分析select查询语句,看key字段,确定是否使用了索引或索引使用是否正确
二、事务
1.什么是事务
是一种机制、一个操作序列,包含了一组数据库操作命令,并且把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么都执行,要么都不执行
是一个不可分割的工作逻辑单元,在数据库系统上执行并发操作时,事务是最小的控制单元
事务就是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。
2.事务的ACID特点
2.1原子性(Atomicity)
指事务是一个不可再分割的工作单位,事务中的操作要么都发生,要么都不发生
•事务是一个完整的操作,事务的各元素是不可分割的;
•事务中的所有元素必须作为一个整体提交或回滚;
•如果事务中的任何元素失败,则整个事务将失败。
2.2一致性(Consistency)
指在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
•在事务开始前,数据库中存储的数据处于一致状态;
•当事务完成后,数据也必须处于一致状态。
2.3隔离性(lsolation)
指在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。
•对数据进行修改的所有并发事务是彼此隔离的,表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务;
•修改数据的事务可在另一个使用相同数据的事务开始之前访问这些数据,或者在另一个使用相同数据的事务结束之后访问这些数据,即并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的。
2.4持久性(Durability)
在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。指不管系统是否发生故障,事务处理的结果都是永久的。一旦事务被提交,事务的效果会被永久地保留在数据库中。
3.并发访问表的一致性问题
①脏读
当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。(即一个事务能看到另一个事务未提交的数据)
②不可重复读
指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。(即由于一个事务中途修改使另一个事务多次读取不能读到相同的数据内容)
③幻读
一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,另一个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,操作前一个事务的用户会发现表中还有没有修改的数据行,就好像发生了幻觉一样。(即一个事务明明修改了多行数据记录,但由于另一个数据的影响,却导致发现有数据记录未被修改)
④丢失更新
两个事务同时读取同一条记录,A先修改记录,B也修改记录(B不知道A修改过),B提交数据后B的修改结果覆盖了A的修改结果。
4.事务的隔离级别
(1)未提交读(Read Uncommitted (RU))
允许脏读,即允许一个事务可以看到其他事务未提交的修改。
(2)提交读(Read Committed (RC))
允许一个事务只能看到其他事务已经提交的修改,未提交的修改是不可见的。(防止脏读)
(3)可重复读(Repeatable Read (RR))
确保如果在一个事务中执行两次相同的SELECT语句,都能得到相同的结果,不管其他事务是否提交这些修改。(可以防止脏读和不可重复读)
(4)串行读(serializable)
相当于锁表
完全串行化的读,将一个事务与其他事务完全地隔离。每次读都需要获得表级共享锁,读写相互都会阻塞。(可以防止脏读,不可重复读取和幻读;但事务串行化会降低数据库的效率)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tHjic7x5-1687219432228)(C:\Users\xujixiang\Desktop\云计算学习资料\云计算二阶\MySQL\mysql索引、事务、存储引擎\隔离级别.png)]
Mysql 默认的隔离级别是 Repeatable Read (RR)
Oracle 和 SQL Server 的默认隔离级别是 Read Committed (RC)。
5.隔离级别操作
①查看隔离级别
show global variables like '%isolation%'; //查看全局隔离级别
show session variables like '%isolation%'; //查看会话隔离级别
②设置隔离级别
set global transaction isolation level read committed; //设置全局隔离级别
set session transaction isolation level read committed; //设置会话隔离级别
6.事务操作
begin; //开始事务
.... insert into update XX set delete from //插入数据,更新数据。删除数据
savepoint XX; //设置回滚点
rollback to XX; //回滚到回滚点
commit; rollback; //提交事务;回滚操作
7.设置自动提交事务
set autocommit=0|1; //0为关闭自动提交事务;1为开启自动提交事务
show variables like 'autocommit'; //查看自动提交事务的状态
三、存储引擎
1.概念
存储引擎 是MySQL数据库中的组件,负责执行实际的数据I/O操作,工作在文件系统之上,数据库的数据会先传输到存储引擎,会按照存储引擎的格式保存到文件系统中
2.常用存储引擎
MyISAM InnoDB
3.MyIsam与InnoDB比较
MyIsam | InnoDB |
---|---|
不支持事务,外键约束 | 支持事务操作、外键约束 |
表级锁定 | 行级锁定 |
适合单独的读、写插入操作,并发读写能力弱 | 读写并发能力好 |
支持全文索引,资源占用较小,数据文件(.MYD)和索引文件(.MYI)是分开存储 | 支持全文索引(5.5版本以后的),缓存能力较好可以减少磁盘IO的压力,数据文件也是索引文件 |
适用于不需要事务处理,单独的查询或者插入数据的业务场景 | 适用于需要事务的支持,一致性要求较高,数据会频繁更新,高并发读写的业务场景 |
4.存储引擎管理
①针对于已经存在的表
alter table 表名 engine=MyISAM|InnoDB
②设置新建表的默认存储引擎
vim /etc/my.cnf 修改mysql配置文件设置新建表的默认存储引擎
[mysqld]
default-storage-engine=MyISAM|InnoDB
③新建表时指定存储引擎
create table 表名 (....) engine=MyISAM|InnoDB
④查看存储引擎
show create table 表名;
show table status from 库名 where name='表名';
show engines;
四、死锁
1.概念
是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。由于资源占用是互斥的,当某个进程提出申请资源后,使得有关进程在无外力协助下,永远分配不到必需的资源而无法继续运行,这就产生了一种特殊现象死锁。 一种情形,此时执行程序中两个或多个线程发生永久堵塞(等待),每个线程都在等待被其他线程占用并堵塞了的资源。例如,如果线程A锁住了记录1并等待记录2,而线程B锁住了记录2并等待记录1,这样两个线程就发生了死锁现象。计算机系统中,如果系统的资源分配策略不当,更常见的可能是程序员写的程序有错误等,则会导致进程因竞争资源不当而产生死锁的现象。锁有多种实现方式,比如意向锁,共享-排他锁,锁表,树形协议,时间戳协议等等。锁还有多种粒度,比如可以在表上加锁,也可以在记录上加锁。
2.死锁原因
(1)系统资源不足。
(2) 进程运行推进的顺序不合适。
(3)资源分配不当等。
如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。
3.死锁的必要条件
(1) 互斥条件:一个资源每次只能被一个进程使用。
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
4.如何避免死锁?
1)以固定的顺序访问表和行。
2)大事务拆小。大事务更倾向于死锁,如果业务允许,将大事务拆小。
3)在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概率。
4)降低隔离级别。如果业务允许,将隔离级别调低也是较好的选择,比如将隔离级别从RR调整为RC,可以避免掉很多因为gap锁造成的死锁。
5)为表添加合理的索引。如果不使用索引将会为表的每一行记录添加上锁,死锁的概率大大增大。
### 4.如何避免死锁?
1)以固定的顺序访问表和行。
2)大事务拆小。大事务更倾向于死锁,如果业务允许,将大事务拆小。
3)在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概率。
4)降低隔离级别。如果业务允许,将隔离级别调低也是较好的选择,比如将隔离级别从RR调整为RC,可以避免掉很多因为gap锁造成的死锁。
5)为表添加合理的索引。如果不使用索引将会为表的每一行记录添加上锁,死锁的概率大大增大。