数据库的索引和事务

目录

一.索引

 一.索引的作用

二. 索引背后的数据结构 B+ 树

 一.B+树的特点

 二.B+树的优点

三.创建索引的方法

二.事务

 一.什么是事务

 二.事务的概念

 三.事务的四个关键特性

四.并发执行事务可能产生的问题

一.脏读问题:

 二.不可重复读问题:

三.幻读

四.四种隔离级别


一.索引

 一.索引的作用

        索引是为了加快查询的速度

二. 索引背后的数据结构 B+ 树

 一.B+树的特点

1. 一个节点,可以存储N个key,N个key划分出了N个区间~~~而不是(N+1个区间)
2.每个节点中的key的值,都会在子结点中也存在(同时key是子节点的最大值)
3.B+树的叶子节点,是首位相连,类似于一个链表
4. 整个树的所有数据都是包含在 叶子 节点中的!!!(所有的非叶子节点中的key 最终都会出现在叶子节点中)
5. 由于叶子节点是完整的数据集合,只在叶子节点这里存储数据表的每一行数据。
而非叶子节点,只存key值本身即可

 这里不做过多介绍B+树, 只是简单提一下索引的实现, 举个例子来了解B+树

B+树就是在B树的基础上继续改进 (也是N叉搜索树)

        // 例如 根节点给先给两个数据 : 8    15
        // 那么 接下来只会分为两组:
        //  小于8  大于8小于15
        // 注意!!!此处的15相当于最大值~~~没有大于15的元素了!!
        // 接下来继续往下分
        // 例如为 [2 5 8]     [11 15]
        // 注意这时候 8 在父节点中有了 在子节点又来一遍 15也是
        // 等排到最后的时候要把全部的叶子节点连接起来

 

二.B+树的优点

1. 当前一个节点保存更多的key,最终树的高度是相对更矮的,查询的时候减少了IO访问次数。(和B树是一样的)
2. 所有的查询最终都会落到叶子节点上。(查询任何一个数据没经过的IO访问次数,是一样的)
3. B+树的所有的叶子节点,构成链表,此时比较方便进行范围查询 ~ ~
 4.由于数据都在叶子节点上,非叶子节点只存储key,导致非叶子节点占用空间是比较小的~~ 这些非叶子节点就可能在内存中缓存(或者是缓存一部分),又进一步减小了IO的次数

三.创建索引的方法

CREATE INDEX 索引名 ON 表名 (列名[(length)]);
#(列名(length)):length是可选项,下同
#如果忽略 length 的值,则使用整个列的值作为索引
#如果指定使用列前的 length 个字符来创建索引,这样有利于减小索引文件的大小
#索引名建议以“_index”结尾
create index phone_index on member (phone);
#直接创建索引

select phone from member;

show create table member;
#展示表的结构以及创建表的具体语句

二.事务

 一.什么是事务

 

比如两个人要进行转账

 1 给 2 500 (假设 1 里面有 1000 2 里面没有钱)

此时要执行一下sql操作

1. update account set balance = balance - 500 where id = 1;

 2. update account set balance = balance + 500 where id = 2;

要分两步执行

而此时如果再转账的过程中 突然没有信号了 , 数据库炸了或者宕机了

 而1又已经交过钱了

 那么此时只会执行第一条语句 而 第二条语句

 那么此时的结果就是 1 少了500 而 2 还是没有钱

 那么此时用到 事务

事务就是把这两条语句封装一块

那么就是 要么全部执行要么全部不执行

事务的本质就是 把多个sql语句打包成一个整体 <---(事务的原子性)

要么全部执行要么全部不执行 (这里的不执行不是真的没执行,而是执行力执行到一半出错了。出错之后,选择了回复现场,把数据还原成未执行之前的状态) (这个恢复数据的操作叫做”回滚“(rollback));

而不会出现“执行一半“这样的中间件状态

 二.事务的概念

事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。

 在不同的环境中,都可以有事务。对应在数据库中,就是数据库事务

 三.事务的四个关键特性

1. 原子性~【最核心的特性】 初心~

2. 一致性 事务执行前后,数据是靠谱的不能不科学~

3. 持久性 事务修改的内容是写到硬盘的,持久存在的。重启后也不丢失~

4. 隔离性 隔离性 是为了解决”并发“执行事务引起的问题

四.并发执行事务可能产生的问题

一.脏读问题:

比如: 一个事务A正在对数据进行修改的过程中,还没提交之前,另一个事务B,也对同一个数据进行了读取。 此时的B的读操作就成为”脏读“, 读到的数据也成为”脏数据“

解决方法: 

mysql 引入了”写操作加锁“这样的机制 , 写的时候不能用,写完才可以用

 这种操作叫做 写加锁

这个操作降低了并发程度(降低了效率),但是提高了隔离性(提高了数据的准确性)

 二.不可重复读问题:

 (已经定好了 写加锁)

具体情况解释: 事务1 已经提交了数据,此时事务2 开始去读取数据,在读取过程中,事务3又提交了新的数据。此时意味着同一个事务2之内,多次读取数据,读出来的结果是不相同的~~(预期是一个事务中,多次读取到的结果一样, 第二次的读取结果并与能复现第一次的结果 ~)

解决方法:

 进行 ”读加锁“ ; 在事务读取数据的时候进行加锁,不让别人来修改数据

通过这个读加锁 又进一步的降低了事务的并发处理能力(处理效率也降低了)提高了事务的隔离性(数据的准确性又提高了)

三.幻读

当前一定预定了读加锁和写加锁,解决了不可重复读和脏读的问题

幻读的解释: 在读加锁和写加锁的前提下,一个事务两次读取同一个数据,发现读取的数据值是一样的,但是结果不一样~ ~

幻读的两种说法:

说法一:事务 A 根据条件查询得到了 N 条数据,但此时事务 B 删除或者增加了 M 条符合事务 A 查询条件的数据,这样当事务 A 再次进行查询的时候真实的数据集已经发生了变化,但是A却查询不出来这种变化,因此产生了幻读。

 这一种说法强调幻读在于某一个范围内的数据行变多或者是变少了,侧重说明的是数据集不一样导致了产生了幻读。

说法二:幻读并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:A事务select 某记录是否存在,结果为不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。产生这样的原因是因为有另一个事务往表中插入了数据。
 

解决办法就是

数据库使用”串行化“这样的方式来解决幻读,彻底放弃并发处理事务,一个接一个的串行的处理事务。

这样做,并发程度是最低的(效率最慢的)隔离性是最高的(准确性也是最高的)

四.四种隔离级别

针对上述问题 mysql 提供了4种隔离级别

1.read uncommitted (读未提交) 没有进行任何锁限制,并发最高(效率最高),隔离性最低(准确性最低)

2.read committed (不可重复读) 给了写加锁 并发程度降低 , 隔离性提高了

3.repeatable read (可重复读) 给写和读都加锁 并发程度又降低 , 隔离性又提高了

4.serializable (串行化) 串行化 并发程度最低,隔离性最高 

 

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值