目录
1.索引
1.1优点和缺点
1.2查看索引
1.3创建索引
1.4删除索引
1.5索引的使用
1.6索引的数据结构:B+树
1.6.1B+树的特点
1.6.2B+树的好处
1.6.3多个索引的B+树
2.事务
2.1.回滚
2.2事务的使用
2.3事务的特性
2.4隔离性
2.4.1"脏读"问题
2.4.2"不可重复读"
2.4.3"幻读"问题
2.5隔离级别
2.5.1 read uncommitted
2.5.2 read committed
2.5.3 repeatable read
2.5.4 serializable
索引本质就相当于"书的目录",通过目录可以快速找到某个章节的位置
优点:索引加快了查找速度,进行数据库操作查询的情况更多,所以,大多数情况下,引入索引是有好处的
缺点:索引的引入也增大了开销,进行增删改查时,要调整已经创建好的索引,索引也增加了空间的开销,构造索引要额外的硬盘空间来保存
show index from 表名;
如果之前没有创建过索引,但是他会自带一个索引.
表里如果有主键,主键这一列就会自动创建索引(自带的索引),unique和foreign key也会自带创建索引.
create index 索引名 on 表名(字段名);
对于非主键、非唯一约束、非外键的字段,可以创建普通索引
创建索引,最好在表创建之初就把索引创建好,否则,如果是针对一个有很多记录的表,来创建索引,也是一个危险操作. 这个时候就会吃掉大量的磁盘IO,花很长的时间,在这段时间里,数据库无法被正常使用.
索引是为了加快查询的速度,也不是所有的情况加上索引就一定快,如果名字有重复,索引也是可以加上的,只要重名不是很多,这个时候还是可以大大提高查询速度的.
drop index 索引名 on 表名;
删除索引也有可能会吃掉大量的磁盘IO,也是危险操作!
最开始设计数据库的时候,创建表的时候就要规划好,要是已经有大量数据,再进行操作,就要慎重!
把索引创建好了之后,不需要手动使用,直接查询的时候,会自动进行索引
B+树是一种树数据结构,通常用于数据库和操作系统的文件系统中。B+树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。B+树元素自底向上插入,这与二叉树恰好相反。
索引的数据结构是B+树(N叉搜索树的一种),B+树就是为了索引这个场景,量身定做的数据结构.
1.B+树也是一个N叉搜索树,每个节点上可能包含N个key,N个key划分出N个区间,最后一个key就相当于最大值.
2.父元素的key会在子元素中重复出现,并且以最大值的姿态出现.这样的重复出现,导致叶子结点就包含了所有数据的全集,非叶子结点的所有值都会在叶子结点中体现出来.
3.会把叶子结点,用类似链表的方式,首尾相连.
1.作为一个N叉搜索树,高度降低下来,硬盘IO次数就比较少了
2.更适合进行范围查询
3.所有的查询,都是要落在叶子结点上的,无论查询哪个元素,中间的比较的次数是差不多的.
(对于B树来说,可能有的值查的快,有的值查的慢,可能就不均衡了,在根节点,或者深度不深的位置,都查的快,而B+树,无论查哪个元素,都是一样的速度)
4.由于所有的key都会在叶子结点中体现,因此非叶子结点,不必存表的真实记录(不必存数据行)
只要把所有的数据行给放到叶子结点上即可,非叶子结点只需要存索引列的值(比如存个id),数据库里的一条记录,十一行(有很多列,甚至几十列)
由于非叶子结点只存了简单id,没有存一整行,这就意味着,非叶子结点占用的空间,是大大降低的,就有可能在内存中可以放进去缓存,更进一步降低了硬盘IO.(提高查询速度,本质上就是在减少硬盘IO次数!).
对于带有主键的表,就是按照主键索引的B+树来组织的,有的表,不只是主键索引,还有别的非主键列,也有索引,这个情况会构造另一个B+树.B+树非叶子结点里面存的是这一列里面的key(比如一堆学生姓名),而到了叶子结点这一层,不是存完整的数据行,而是主键列的值(比如主键id).
使用主键列来查询,只要查一次B+树就可以了.
如果是使用非主键列的索引来查询,则需要先查一遍索引列的B+树,在查一遍主键列的B+树.("回表")
事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。
在不同的环境中,都可以有事务。对应在数据库中,就是数据库事务。
执行中间出错了,就让一条都不执行,注意:这里并不是真的一条都没执行,而是自动恢复成执行之前的样子,看起来就像没有执行一样!!这里涉及到一个关键操作,"回滚"(rollback).回滚就是把执行过的操作逆向恢复回去.(类似于ctrl+z).
数据库会把执行的每个操作都记录下来,如果某个操作出错,就会把事务中前面的操作进行回滚,根据之前的操作进行逆操作.(前面是插入,现在就删除;前面是删除,现在就插入;前面是修改,现在就改回去).
这些操作是有很大开销的,可以保存,但不可能无限保存,最多就是把正在执行的事务保存下来,额外的东西就不好在保存了.
1 )开启事务: start transaction;
2 )执行多条 SQL 语句
3 )回滚或提交: rollback/commit;
rollback 即是全部失败, commit 即是全部成功。
1.原子性:最核心(初心)
2.一致性:事务执行先后,数据是合法的
3.持久性:事务修改的内容写在硬盘上,持久存在.重启不会丢.(表示永久性的改变。)
4.隔离性:为了解决并发执行事务(同时执行多个事务),引起的问题
并发:服务器同时处理多个客户端请求
问题:如果并发的事务修改的是同一个表/同一个数据
隔离性的意义是为了数据库并发处理事务时,不会有问题
一个事务A 对数据修改时,未提交前,另一个事务b,也对同一个数据进行读取,b的操作为'脏读',读到是数据为'脏数据',可能无效,A可能把数据改了
解决:给写操作加锁
事务1提交数据,事务2开始读数据,读取过程中,事务3提交了新的数据,此时同一个事务2之内多次读取结果不同(第二次读取结果不能重现第一次结果)
解决:给读加锁,读时不能修改
在读加锁和写加锁的前提下,一个事务两次读取同一个数据,数据值一样,结果集不一样
(student.java内容不变),第一次看到只有student.java,第二次看到student.java和teacher.java..)
解决:'串行化',彻底放弃并发处理,一个一个串行处理
并发程度最低(效率最慢),隔离性最高(准确性最高)
不做任何限制,事务之间都是随意并发执行的.并发程度高,隔离性最低.会产生"脏读"+"不可重复读"+"幻读"问题
对写操作加锁了.并发程度降低了,隔离性提高了. 解决了脏读问题,仍然存在不可重复读+幻读问题
对读和写都加锁了.并发程度又降低了,隔离性又提高了. 解决了脏读+不可重复读,可能存在幻读问题
严格串行化.并发程度最低(串行执行的),隔离性最高.解决了脏读+不可重复读+幻读问题,执行速度是最慢的.
注:mysql的默认挡位是repeatable read,第三挡.