Interview_数据库_day24

数据库事务

数据库事务是向数据库进行访问或修改的一系列操作序列,要么全部执行,要么全部不执行,是不可分割的工作单位。

数据库事务有四大特性 \(ACID\):原子性\((Atomicity)\)、一致性\((Consistency)\)、隔离性\((Isolation)\)、持久性\((Durability)\)

  • 原子性:一个事务是不可分割的工作单位,事务内操作要么全部执行,要么全部失败回滚。
  • 一致性:事务处理前后,数据都处于一个合法状态。比如 \(A\)\(B\) 转账时,转账前后不能有人金额为负数,\(A\) 金额和 \(B\) 金额保持总和不变。
  • 隔离性:多个事务并发发生时,事务内部的操作和其他事务是隔离的,事务之间是互不干扰的。
  • 持久性:一旦一个事务被提交了,那么对数据库中的数据改变是永久的。即使数据库系统遇到故障也不会影响已经提交的事务所完成的操作。

数据库索引

数据库索引是为了增加查询速度而对表字段附加的一种标识。

默认的查询方式是根据条件进行全表扫描,遇到匹配的结果就加入结果集合。通过索引可以快速定位到特定值的行数,减少遍历时匹配的行数,加快查询速度。

优点:

  • 创建唯一性索引,可以保证数据库中每一行数据的唯一性
  • 大大加快查找速度
  • 加速表和表之间的连接

缺点:

  • 建立和维护索引需要额外的时间
  • 索引实际上也是一种数据结构,需要占用额外的物理空间
  • 对表中数据修改时,索引也要动态维护

索引背后的数据结构

MySQL索引背后的数据结构及算法原理

添加索引原则

对于很少使用的列不应该创建索引,因为很少用到,索引不会明显的提高速度,增加了索引,反而会因为修改数据时要维护索引而花费额外的时间。

对于很少数据值的列也不应该创建索引,比如性别,因为数据值很少,所以通过索引要查找的行数还是很多,并不能提高速度。

当修改性能远远大于查找性能时也不创建索引,因为修改多时必定要带来大量的额外维护索引的时间。

聚集索引和非聚集索引

  • 聚集索引:表中存储的数据按照索引的顺序存储,检索效率比较高。叶子节点保存的就是整行数据。
  • 非聚集所引:数据存储和索引存储在不同的地方,检索效率比较低。叶子节点保存的是聚集索引字段的值,再通过这个值去聚集索引中查找数据。

在一个数据库中,只能有一个聚集索引,可以有多个非聚集索引。

自然连接、外连接左外连接、右外连接

表1:

A B C
a1 b1 5
a1 b2 6
a2 b3 8
a2 b4 12

表2:

B E
b1 3
b2 7
b3 10
b3 2
b3 2

自然连接时比较的必须是同名属性组,并在结果中把重复的属性列去掉。

自然连接:

A B C E
a1 b1 5 3
a1 b2 6 7
a2 b3 8 10
a2 b3 8 2

可以发现在自然连接中有一些 表1 中的元组在 表2 中没有共同的属性,那么就会被舍弃掉,这些舍弃掉的远足称为 悬浮元组

外连接就是把这些悬浮元组都保留在结果关系中,并在空值处填上 NULL。左外连接就是保留 表1 中的悬浮元组,右外连接就是保留 表2 中的悬浮元组。

外连接:

A B C E
a1 b1 5 3
a1 b2 6 7
a2 b3 8 10
a2 b3 8 2
a2 b4 12 NULL
NULL b5 NULL 2

左外连接:

A B C E
a1 b1 5 3
a1 b2 6 7
a2 b3 8 10
a2 b3 8 2
a2 b4 12 NULL

右外连接:

A B C E
a1 b1 5 3
a1 b2 6 7
a2 b3 8 10
a2 b3 8 2
NULL b5 NULL 2

数据库的乐观锁和悲观锁

  • 悲观锁:它认为当某一用户读取某一数据的时候,其他用户也会对该数据进行访问,所以在读取的时候就对数据进行加锁,在该用户读取数据的期间,其他任何用户都不能来修改该数据,但是其他用户是可以读取该数据的,只有当自己读取完毕才释放锁。
    • 优势:能避免冲突的发生。
    • 劣势:开销较大,因为数据库加锁解锁开销大。
  • 乐观锁:它假定当某一个用户去读取某一个数据的时候,其他的用户不会来访问修改这个数据。在最后进行事务提交的时候会进行版本的检查,以判断在该用户的操作过程中,没有其他用户修改了这个数据。开销比较小。
    • 优势:避免了数据库加锁解锁开销,大大提升了大并发量下的系统整体性能表现。适合于多读的情况。
    • 劣势:只能在提交数据时才发现事务将要失败,如果系统的冲突非常的多,乐观锁也会带来很大的问题。而且乐观锁无法解决脏读问题。

不考虑隔离的问题

  • 脏读:事务 \(A\) 对一个 \(data\) 进行了更新,然后事务 \(B\) 读取了 \(data\),然后事务 \(A\) 由于某种情况失败回滚,此时事务 \(B\) 读出来的数据就成了脏数据。
  • 不可重复读:事务 \(A\) 第一次读取了 \(data\),然后事务 \(B\)\(data\) 进行了更新,当事务 \(A\) 第二次读取 \(data\) 的时候发现两次的数据不同,就造成了不可重复读。
  • 幻读:事务 \(A\) 读取记录时,事务 \(B\) 向数据库添加了一条数据,当事务 \(A\) 再次读取记录时,发现了新添加的数据,就造成了幻读。

数据库四种隔离等级

  1. 读未提交:三大问题都不能避免
  2. 读已提交:可以避免 脏读 的发生
  3. 可重复读:可以避免 脏读、不可重复读 的发生
  4. 串行化:可以避免 脏读、不可重复读、幻读 的发生
posted @ 2020-03-13 17:35  Jiaaaaaaaqi  阅读(204)  评论(0编辑  收藏  举报