数据库总结

事务四大特性(ACID)

数据库事务是指作为单个逻辑工作单元执行的一系列操作,这些操作要么全做要么全不做,是一个不可分割的工作单位。

  1. 原子性(Atomicity)
    事务的原子性是指,事务中包含的程序作为数据库的逻辑工作单位,它所做的对数据的修改操作要么全部执行,要么完全不执行。这种特性称为原子性。
  2. 一致性(Consistency)
    事务一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。这种特性称为事务的一致性。假如数据库的状态满足所有的完整性约束,就说该数据库是一致的。例如完整性约束:a + b = 10,一个事物改变了a,那么b也随之改变。
  3. 分离性(也称为独立性,lsolation)
    分离性指并发的事务是相互隔离的。即一个事物内部的操作及正在操作的数据必须封锁起来,不被其他企图进行修改的事务看到。假如并发交叉执行的事务没有任何限制,操纵相关的共享对象的多个并发事务的执行可能引起异常。
  4. 持久性(Durability)
    持久性意味着当系统或介质发生故障时,确保已提交事务的更新不能丢失。即一旦一个事务提交,DBMS保证它对数据库中数据的改变应该是永久性的,即对已提交事务的更新能恢复。持久性通过数据库备份和恢复来保证。

事务隔离性以及在MySQL中的实践

数据库事务是指作为单个逻辑工作单元执行的一系列操作,要么全部执行,要么全部不执行。一方面,当多个应用程序并发访问数据库时,事务可以在应用程序间提供一个隔离方法,防止互相干扰;另一方面,事务为数据库操作序列提供了一个从失败恢复正常的方法。

当多个线程都开启事务操作数据库中的数据时,数据库系统要能进行隔离操作,以保证各个线程获取数据的准确性。

  1. 如果没有隔离,会发生以下情况

    • 脏读:对于两个事务T1、T2,T1读取了已经被T2更新但还没有提交的字段,之后,若T2回滚,T1读取到的内容就是临时无效的内容。
    • 不可重复读:对于事务T1、T2,T1需要读取一个字段两次,在第一次和第二次读取之间,T2更新了该字段,导致T1第二次读取到的内容值不同。
    • 幻读:事务A读取与搜索条件相匹配的若干行。事务B以插入或删除行等方式来修改事务A的结果集,然后再提交。幻读与不可重复读之间的区别是幻读强调的是新增或删除,而不可重复读强调的是修改。比如Mary两次查工资,中间有人改过工资,则两次结果不一样,这就是不可重复读。Mary要查工资一千的人数,第一次查到了10个,中间有人增加了一条工资为一千的人,下次查的时候就变成了11个,好像第一次查询的是幻觉一样。
  2. 事务的四个隔离级别
    读未提交、读已提交、可重复读、串行化。四个级别增强逐渐增强,每个级别解决上个级别的一个问题。

    • 读未提交:另一个事务修改了数据,但尚未提交,而本事务中的select会读到这些未被提交的数据(脏读)。脏读是指另一个事务修改了数据,但尚未提交,而本事务中的select会读到这些未被提交的数据
    • 读已提交:本事务读取到的是最新的数据(其他事务提交后)。问题是,在同一事务里,前后两次相同的select会读到不同的结果(不可重复读)。不可重复读是指同一个事务执行过程中,另外一个事务提交了新数据,因此本事务先后两次读到的数据结果会不一致。
    • 可重复读:在同一个事务里,select的结果是事务开始时间点的状态,同样的select操作读到的结果会是一致的,但是有幻读现象。可重复读保证了同一个事务里,查询的结果都是事务开始时的状态(一致性)。但是,如果另一个事务同时提交了新数据,本事务再更新时,就会发现了这些新数据,貌似之前读到的数据都是幻觉,这就是幻读。
    • 串行化:所有事务只能一个接一个串行执行,不能并行

隔离级别的选择
MySQL支持四种隔离级别,默认的是可重复读

MYSQL的两种存储引擎区别

  • MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持
  • MyISAM表不支持外键,InnoDB支持
  • MyISAM锁的粒度是表级,而InnoDB支持行级锁定
    MyISAM相对简单,所以在效率上要优于InnoDB,小型应用可以考虑使用MyISAM,当你的数据库有大量的写入、更新操作而查询比较少或者数据完整性要求比较高的时候就选择Innodb表。当你的数据库主要以查询为主,相比较而言更新和写入比较少,并且业务方面数据完整性要求不那么严格,就选择mysiam表。

应用场景:

  • MyIASM管理非事务表,提供高速存储和检索以及全文搜索能力,如果在应用中执行大量的select操作,应该选择MyIASM
  • InnoDB用于事务处理,具有ACID事务支持等特性,如果在应用中执行大量的insert和update操作,应该选择InnoDB

数据库的优化(从sql语句优化和索引两个部分回答)

  1. 只返回需要的数据

    • 不要写select * 的语句
    • 合理写where子句,不要写没有where的SQL语句
  2. 尽量少做重复的工作

    • 可以合并一些SQL语句
  3. 适当建立索引(不是越多越好)但以下几点会进行全表扫描

    • 左模糊查询‘%…’
    • 使用了不等操作符!=
    • or使用不当,or两边都必须有索引才行
    • in、not in
    • where子句对字段进行表达式操作
    • 对于创建的复合索引(从最左边开始组合),查询条件用到的列必须从左边开始不能间隔。否则无效,复合索引的结构与电话簿类似
    • 全文索引:当对于文件建立了一个以词库为目录的索引(文件大全文索引比模糊匹配效果好)
  4. 使用join代替子查询

  5. 使用union代替手动创建临时表

乐观锁与悲观锁

当并发事务同时访问一个资源时,有可能导致数据不一致,因此需要一种机制来将数据访问顺序化,以保证数据库数据的一致性。锁就是其中一种机制。在计算机科学中,锁时在执行多线程时用于强行限制资源访问的同步机制,即用于在并发控制保证对互斥要求的满足。在数据库的锁机制中,数据库管理系统中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。

乐观并发控制(乐观锁)和悲观并发控制(悲观锁)是并发控制主要采用的技术手段。

悲观锁是一种并发控制的方法。它可以阻止一个事务以影响其他用户的方式来修改数据。如果一个事务执行的操作对某行数据应用了锁,那只有当这个事务把锁释放,其他事务才能够执行与该锁冲突的操作。主要用于数据争用激烈的环境,以及发生冲突时使用锁保护数据的成本要低于该锁冲突的操作。

悲观锁的流程:在对任意记录进行修改前,先尝试为该记录加上排他锁;如果加锁失败,说明该记录正在被修改,那么当前查询可能要等待或者抛出异常。如果成功加锁,那么就可以对记录做修改,事务完成后就会解锁。期间有任何对该记录做修改或加排他锁的操作,都会等待我们解锁或者直接抛出异常。

悲观锁的缺点:悲观并发控制实际上是“先取锁再访问”的保守策略,为数据处理的安全提供了保证。但是在效率方面,处理加锁的机制会让数据库产生额外的开销,还有增加产生死锁的机会;另外,在只读型事务处理中由于不会产生冲突,也没必要使用锁,这样做只能增加系统负载;还有会降低了并行性,一个事务如果锁定了某行数据,其他事务就必须等待该事务处理完才可以处理那行数据。

乐观锁,它假设多用户并发的事务在处理时不会彼此互相影响,各事务能够在不产生锁的情况下处理各种影响的那部分数据。在提交数据更新之前,每个事务会先检查在该事务读取数据后,在没有其他事务又修改了该数据。如果其他事务有更新的话,正在提交的事务会进行回滚。

相对于悲观锁,在对数据库进行处理的时候,乐观锁并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本。实现数据版本有两种方式,第一种是使用版本号,第二种是使用时间戳

乐观并发控制相信事务之间的数据竞争(data race)的概率是比较小的,因此尽可能直接做下去,直到提交的时候才去锁定,所以不会产生任何锁和死锁。但如果直接简单这么做,还是有可能会遇到不可预期的结果,例如两个事务都读取了数据库的某一行,经过修改以后写回数据库,这时就遇到了问题。

关系型数据库和非关系型数据库区别

一般非关系数据库是基于CAP模型,而传统的关系型数据库是基于ACID模型的

  1. 数据存储结构
    首先关系型数据库一般都有固定的表结构,并且需要通过DDL语句来修改表结构,不是很容易进行扩展,而非关系数据库的存储机制就有很多了,比如基于文档的、K-V键值对的,还有基于图的等,对于数据的格式十分灵活没有固定的表结构,方便扩展,因此如果业务的数据结构并不是固定的或者经常变动比较大的,那么非关系数据库是个好的选择。
  2. 可扩展性
    传统的关系型数据库给人一种横向扩展难,不好对数据进行分片等,而一些非关系型数据库则原生就支持数据的水平扩展,并且这可能也是很多NoSQL的一大卖点,其实像MySQL这种关系型数据库的水平扩展也不是很难,即使NoSQL水平扩展容易但对于向跨分片进行joins没有好的解决办法。不管是关系型还是非关系型数据库,解决水平扩展或者跨分片Joins这种场景,在应用层和数据库层中间加一层中间件来做数据处理也许是个好的办法。
  3. 数据一致性
    非关系型数据库一般强调的是数据最终一致性,而没有像ACID一样强调数据的强一致性,从非关系型数据库中读到的有可能还是处于一个中间态的数据,因此如果你的业务对于数据的一致性要求很高,那么应该选择关系型数据库。非关系型数据库可能更多的偏向于OLAP场景,而关系型数据库更多偏向于OLTP场景。

博客SQL与NoSQL(关系型与非关系型)数据库的区别

聚集索引与非聚集索引以及SQL的查询优化技术

聚集索引:聚集索引的顺序就是数据的物理存储顺序;
非聚集索引:索引顺序与数据物理排列顺序无关。
正因为如此,所以一个表最多只能有一个聚簇索引。简单来说,聚簇索引的叶子节点就是数据节点,非聚簇索引的叶节点仍然为索引节点,只不过有一个指针指向对应的数据块。

Author: Toyan
Link: https://toyan.top/database-summary/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
支付宝打赏
微信打赏