关于数据库的索引和事务

索引:索引是对数据库表中一列或者多列的值进行排序的一个结构

一.索引的优点:

        (1)创建索引可以大幅度的提高系统的性能,可以帮助用户能够更快查询到需要查询数据

        (2)通过索引的唯一性,也可以保证数据库中每一行数据的唯一性

二.索引的缺点:

        (1)当数据库中的数据非常大时,创建索引和维护的代价就非常大,可能会导致数据库的卡死

        (2)创建索引会造成数据库在空间以及增删改的效率降低

索引的核心数据结构为:B+数(在本质上为一个N叉搜索树)-->查找过程和二叉树相似

事务:事务是数据库的操作序列

        事务的特性(原子性,一致性,持久性,隔离性);

        (1)原子性:把多个SQL打包成一个整体,要么执行就执行到底,要么就不执行,抵制半途而废(也不是说真的一个都不执行,而是执行一半了发现出现了问题,那么就可以自动的把前面的SQL执行的效果进行还原 这就叫做回滚)

        (2)一致性:事务在执行的前后,数据必须处于“一致的状态”,类似于银行转账(A账户转给B账户一百元,A账户就减少一百元同时B账户就必须增加一百元,)

        (3)持久性:事务一旦提交过后数据是存放在硬盘的,无论是数据库卡死过后的重启还是故障,数据都不会丢失

        (4)隔离性:多个事务在并发执行的时候,事务之间能够保持‘隔离’,相互不干扰(也就是说一个事务的执行不能被另一个事务而干扰,每个事务都有各自的空间)

脏读问题:脏数是一个临时的数据,不代表最终的数据(一个事务A在修改数据还未提交之前,另外一个事务B读取了数据,此时事务A又修改了数据然后提交上去,那么事务B读到的就是一个“无效数据”也就成为脏读)

解决脏读问题:事务A在写数据还未提交之前,事务B不能读,只有A写完数据过后提交完成,B事务才能读-——>相当于对写操作加锁

在写加锁之前,事务A与事务B就是完全并发的 并发性是最高的,隔离性是最低的 

当写加锁之后,事务A写的时候事务B就不能读了 并发性降低(效率降低)隔离性提高(数据准确性提高)

不可重复读:解决完脏读问题后,又出现了一个不可重复问题,当事务A提交完数据时,事务B在读数据,但是事务A突发奇想的想修改数据,于是修改完成后又提交了,这时事务B读数据读着读着就会发现数据被改变了(也就是在同一个事务中读两次数据应该是两次相同的结果 但是结果不相同这就是不可重复读 原因就是读的过程中被数据被修改了)

解决不可重复读问题:利用读加锁  事务A与事务B约定 在事务A写数据的时候事务B不去读(写加锁) 同时在事务B读数据的时候事务A不去修改(读加锁)

随之读加锁,并发程序又进一步的降低(效率降低)隔离性又提高了(数据准确性也提高了)

幻读(不可重复读的特殊情况):当事务B去读文件A时,事务A去修改文件B/去新增删除文件,只要不影响事务B读的那个文件就好了,但是这样做对事务B直接读取的数据没有影响,但是事务B会发现两次读虽然数据一样,但是结果集会被改变(第一次事务B看到一个.java文件 下次读就突然看见两个.java文件)

解决幻读问题:“串行化”(先执行完成一个再执行下一个)事务B在读数据读代码的时候,事务A就必须不能修改数据,就必须放下电脑,数据不可以动

这时并发程度最低(串行执行的了),效率是最低的,隔离性是最高的,数据的准确性也是最高的了

如果需求对于数据精度要求不高,上述问题就不是bug,因此就可以让并发程度高一些,隔离性低一些,提高效率(例如某手某音的点赞,游戏排位的分数)

如果需求对于数据精度要求很好,上述问题就可能是bug,因此就得让并发程度低一些,隔离性高一些,提高准确度(例如关于钱的)

于是MySQL就提供了‘隔离级别’选项 共有四个档位 当我们根据实际情况而选择

隔离级别:

        1.read uncommitted : 允许读未提交的数据,并发程度最高,隔离性最低,效率最高,可能出现 脏读/不可重复读/幻读 问题

        2.read committed :只能读提交之后的数据,相当于写加锁,并发程度降低,隔离性提高,解决了脏读问题,可能存在不可重复读/幻读 问题

        3.repeatable read(默认) :相当于读和写都加锁,并发程序再降低,隔离性在提高,解决了脏读/不可重复读的问题 可能存在幻读问题

        4.serializable :严格执行串行化,并发程度最低,隔离性最高,解决了脏读/不可重复读/幻读问题,效率最低

补充ArrayList和LinkedList之间的区别

1.ArrayList底层是顺序表 LinkedList底层是链表

2.ArrayList具备了随机访问的能力(根据下标获取元素)

        ArrayList查找并不快,查找的时候要遍历的时间复杂度为O(N) 没有优势

  查找:根据值来获取元素的位置(indexOf)

3.LinkedList增加删除也不快!首位增删可以做到O(1) ,中间位置增删还是O(N) 封装为一个 add(n,value)也是通过下标的方式来查找的,这种封装导致java的链表没有发挥出应有优势,相比之下C++中STL 中 std::list 插入元素的时候需要显式的指定一个迭代器(迭代器就指向了需要插入的位置) 这里的中间位置插入是O(1);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值