索引
概念
索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。
索引:目的是为了提高查找的速度,但是拖慢了增、删、改的速度
提高查找数据库的速度,就得先建立索引,也是有额外开销的(时间,空间)本质上就是把数据库中的记录按照一定的规则/数据结构给组织起来
虽然索引会拖慢增删改的速度,但是很多情况下仍然需要索引,相对于增删改来说,查找才是最高频的操作
作用
- 数据库中的表、数据、索引之间的关系,类似于书架上的图书、书籍内容和书籍目录的关系。
- 索引所起的作用类似书籍目录,可用于快速定位、检索数据。
- 索引对于提高数据库的性能有很大的帮助。
使用场景
要考虑对数据库表的某列或某几列创建索引,需要考虑以下几点:
- 数据量较大,且经常对这些列进行条件查询。
- 该数据库表的插入操作,及对这些列的修改操作频率较低。
- 索引会占用额外的磁盘空间。
满足以上条件时,考虑对表中的这些字段创建索引,以提高查询效率。
反之,如果非条件查询列,或经常做插入、修改操作,或磁盘空间不足时,不考虑创建索引。
使用
创建主键约束(primary key)、唯一约束(unique)、外键约束(foreign key)时,会自动创建对应列的索引。
查看索引
show index from 表名;
创建索引
对于非主键、非唯一约束、非外键的字段,可以创建普通索引
create index 索引名 on 表名(字段名);
例:常见班级表中,name 字段的索引
create index idx_classes_name on classes(name);
删除索引
drop index 索引名 on 表名;
事务
事务就是把若干个 sql 语句打包成一个整体,要么全都执行完,要么就一个都不执行,哪怕执行一半,中间出了差错了,数据库也能保证把已经改动过的数据自动还原成最初的样子,用户看起来就好像这些操作一个都没执行的样子
事务的特性:
- 原子性
- 一致性
事务执行完毕之后,数据仍然是合理的(程序员手动定义的) - 持久性
事务执行完毕之后,数据就存到磁盘上,哪怕重启机器,数据仍然存在 - 隔离性
并发执行事务所产生的的问题和解决方案
mysql 并发执行事务可能产生的问题
通过给写加锁解决脏读
通过读加锁不可重复读
通过串行化解决幻读
引入写加锁,脏读解决了,不可重复读和幻读存在
引入读加锁,脏读和不可重复读解决了,幻读存在
引入串行化,三个问题都解决了
脏读
一个事务 A 在修改数据,另一个事务 B 直接读取 A 正在修改的数据,此时 B 读到的就是一个脏数据,因为此时 B 读到的数据很可能就在 A 的后序操作中又进行了修改,相当于 B 读到的数据只是一个“中间的状态”,读到的这个这种数据,就是脏数据,这个动作,叫做脏读。
不可重复读
事务 A 修改数据然后提交,提交完毕后事务 B 开始读取数据
事务 B 中包含了很多次的读操作,如果事务 B 两次读错做得到的结果不一样,就是不可重复读
不一样的原因就是事务 A 肃然把数据已经提交了,但是可能有执行了一次事务 A 。又把这个数据给改了
事务 B 第一次读到的数据是事务 A 提交的,第二次读到的数据是事务 A 又提交了一次
幻读
引入了读加锁和写加锁之后,这个时候
事务 B 正在读取数据,事务 A ,插入了新的数据/删除了某个数据,事务 B 两次读取到的数据集的个数发生变化了
串行化:
彻底的让事务之间串行执行,此时就没有涉及任何并发的事情了,必须要第一个事物执行完,在执行第二个在执行第三个
mysql 中事务的隔离级别
- read uncommitted 没有做出任何隔离性的限制
- read committed 相当于进行了写加锁,并发程度降低了,隔离级别就提高了,此时藏独问题解决了,不可重复读和幻读存在
- repeatable read 相当于读写都加锁,并发程度又降低了,隔离级别又提高了,此时脏读和不可重复读解决了,幻读仍然存在
- Serializable 串行化。并发程度低,隔离级别最高,此时脏读不可重复读幻读就都没有。执行效率最低的方式