MYSQL的索引和事务~

一、MYSQL的索引(是指按照值进行查找的)

索引相当于一本书的目录(用于进行查找的

之所以有索引这个操作,是因为如果单纯的遍历表进行查找,比较低效,而使用索引这种特殊的数据结构来表示一些记录的特征,通过这些特征来减少比较次数,可以提高查找的效率 

虽然索引能使查找的效率提高,但同时也会付出一些代价~(就像书的目录一样,虽然提高了查找效率,但同时也是废纸的~),数据库的索引,也需要消耗一定的额外存储空间~

数据量越大,索引消耗的额外空间就越多~

同样,书的目录如果确定了,后面每次对书的内容进行调整,都可能会影响到目录的准确性,需要重新调整目录~

数据库的索引也是一样,当进行增删改的时候,往往也需要同步的调整索引的结构~


索引带来的好处:提高了查找的速度

索引带来的坏处:占用了更多的空间,拖慢了增删改的速度


和索引相关的操作:

1、查看索引    show index from 表名;    查看一个表上有哪些索引

如果没有设置索引,但查看索引时能查到索引,可能是之前提供了primary key或者是unique这两个约束,因为 primary 和 unique 是自带索引的

2、 给一个表中的某一列来创建索引    create index 索引名字 on 表名(列名);

 注意:创建索引是一个非常低效的事情,尤其是当表中有很多数据的时候,如果数据库表中              本身没有索引,不要轻易去创建索引容易将数据库崩掉,一般创建索引都是在刚开              始创建表的时候,就把索引规划好

3、删除索引    drop index 索引名字 on 表名

drop index name_index on student;-- 删除student表中名为name_index的索引

注意:删除索引和创建索引一样,都是非常低效的事情,也容易将数据库搞挂~


补充:

顺序表按照下标的访问速度O(1),因为顺序表是在连续内存空间上,内存支持随机访问操作,访问任意地址上的数据,速度都是极快的,因为是按照下标进行查找的,不是按照值进行查找的,是按照下标进行遍历的,不适合作为索引

二叉搜索树查找的时间复杂度是:(最坏情况下:单情况下分支)O( N ) 时间复杂度太高,不适合作为索引

二叉树最大的问题,就是当元素多了的时候,高度就高了,(高度对应着比较次数),对于数据库来说,每次比较都意味着磁盘IO

哈希表也不适合作为索引,虽然哈希表的查找速度很快O(1),但哈希表只能针对“相等”进行判定,不能对“大于小于”,以及范围查找进行判定

堆更不适合作为索引,堆只能找最大或者最小

 B树作为索引:

查找过程和二叉搜索树相似,先从根节点出发,根据带比较的元素确定一个区间,根据区间向下查找

 B树作为索引相比于二叉搜索树的优势:二叉搜索树是每个节点比较一次,比较的次数和高度有关,而B树是多叉树,而且每个节点存储不止一个数据,高度明显减少了,虽然每个节点比较多次,但相比比较次数来说,IO次数是更关键的,因为是以节点为单位进行磁盘IO的,因为访问磁盘速度慢,应用B树可以大大减小磁盘IO,所以索引应用B树可以加快查找速度


重点!!!

索引背后的数据结构:B+树   一个N叉搜索树


二、MYSQL的事务

事务诞生的目的:为了把若干个独立的操作打包成一个整体

打包之后的整体,要想执行必须全部执行,不执行就全部不执行,不存在只执行一个不执行另外一个的中间情况事务的原子性

适用于:在SQL中,有复杂的任务需要多个SQL来一起执行,前一个SQL是为了给后一个SQL提供支持,如果后一个SQL不执行了或者出问题了,前一个SQL也就失去意义了~,这种情况可以利用事务来将其打包成一个整体

例如:就像转账一样,不能只转一半,造成一方钱少了,另外一方还没收到钱,像这种情况就需要利用事务(原子性:必须两个操作同时执行,不能只操作一半

 事务原子性是如何保证的呢?

因为无法预知失败,该执行还是要执行,当出现失败之后,由数据库自动执行一些还原性的操作,来消除前面SQL带来的影响,像这种操作也成为回滚


事务的使用:

(1)开启事务:start transaction;

(2)执行多条SQL语句
(3)回滚或提交:rollback/commit;
说明:rollback即是全部失败,commit即是全部成功。

  重点!!!

  事务的基本特性:

(1)原子性:要想执行必须全部执行,不执行就全部不执行,

(2)一致性:在事务执行之前和执行之后,数据库中的数据都得是合理合法的

                        例如:你转账完了之后,不能够出现账户为负数的情况

(3)持久性:事务一旦提交了之后,数据就持久化存储起来了(数据就写入硬盘了)

(4)隔离性:隔离和并发是对立的,要想隔离性高,并发性就会降低


关于提高隔离性会出现的问题及其解决方法:

并发:是指同时执行多个任务,并发执行事务是指一个数据库服务器同时来执行多个事务

并发执行事务可能会带来的问题:会出现脏读问题
1、脏读问题:就像事务A在对某个数据进行修改,修改的同时,事务B去读取了这个数据,此时,事务B读到的很可能是一个“脏数据”(这个数据是一个临时的结果,而不是最终的结果,可能随时被修改)
出现脏读问题的原因:是事务和事务之间没有进行任何的隔离,加上一些约束限制就可以有效的避免脏读问题
处理脏读:给写操作枷锁
                  在修改的过程中,别人不能再读了(加锁状态)
                  等修改完了之后,别人才能读(解除加锁状态)

2、但是同时又出现了一个不可重复读问题(不同时间读数据会出现读取数据不同的问题)

因为虽然已经给写加锁了,在写的时候不能读,但是有可能在读的过程中写入数据,此时有可能出现不同时间读数据会出现读取数据不同的情况。

处理不可重复读:给写操作也加锁

                             保证读的时候也不能去写

 此时会导致隔离性提高,并发性降低,速度变慢了,但是数据更准了

事务虽然在提交隔离性的时候要进行一系列的加锁,但是这个锁也不是把整个数据库都给锁定了,还可以改其他的表,甚至可以改其他的行

3、此时还会出现另外一个问题,就是当同学读代码的过程中,发现代码的数量变了,本来只有一个A.java,现在又多了一个B.java,像这种问题叫做幻读问题

幻读问题:一个事务执行过程中进行多次查询,多次查询的结果集不一样(多了一条或者少                    了一条),和重复读问题不同于,重复读问题是,多次查询的结果发生了内容的                    改变,幻读问题也算是一种特殊的不可重复读~

解决幻读问题:彻底串行化执行

                         要求在读的过程中坚决不可以再写代码~

                        (写别的不是学生正在读的代码也不行)

这样操作会使隔离性最高,并发性最低,速度最慢,数据最可靠


由于并发(快)和隔离(准)是不可兼得的,可以根据实际需要来调整数据库的隔离级别,通过不同的隔离级别,也就控制了事务之间的隔离性,也就控制了并发程度~


MYSQL中事务的隔离级别:

1、read uncommitted:允许读取未提交的数据,并发程度最高,隔离程度最低,会引入脏读

                                      +不可重复读+幻读问题

2、read committed:允许读取提交之后的数据,相当于写加锁,并发程度降低了一些,隔离                                    程度提高了一些,解决了脏读,会引入不可重复读+幻读

3、repeatable read:相当于给读和写都加锁,并发程度又降低了,隔离程度又提高了,解决                                   了脏读和不可重复读问题,会引入幻读

4、serializable:串行化。并发程度最低(串行执行),隔离程度最高,解决了脏读,不可                               重复读,幻读问题,但是执行速度最慢

可以通过修改my.ini这个配置文件,来设置当前的隔离级别,根据实际的需求场景来决定使用哪种隔离级别~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值