MYSQL数据库

数据库介绍之ACID

 A(Atomicity):原则性指的是事务是一个不可分割的最小单元,一个事务中的操作要么全部成功对数据库产生影响,要么全部不成功对数据库不产生任何影响,对于一个事务来说,不能只执行成功其中一部分操作,这就是事务的原子性。
 C(Consistency):一致性指的是数据库总是从一个一致性状态转换到另一个一致性状态,一个事务不能同时影响多个状态的数据库,也不能将数据库从一个状态变为多个状态。
 I(Isolation):隔离性是指数据库要确保一个事务在完成前,对其他事务不可见,事务之间是隔离的,即使他们并发的到达数据库在执行完成前他们之间也是互相不感知的。
 D(Durability):持久性指的是数据库保证事务对数据库产生的影响是持久的,一旦事务执行完成,所造成的影响会被永久保存在数据库当中。

事务的隔离级别

 读未提交:事务中的修改,即使没有提交,对其他事务也是可见的。这个情况也被称为(脏读),后续如果事务执行失败,就读取了错误的数据。读未提交会带来很多问题。
 读已提交:事务中的修改,在提交之前对其他事务不可见。这种情况也成为不可重复读,两次执行相同的查询,获取到的结果可能会不一样。
 可重复读: 可重复读,保证了同一个事务多次读取的结果是一样的。但是理论上,会带来另一个问题,幻读。幻读指的是事务在读某个范围内的数据时,因为其他事务插入了一条新的记录,当事务再次操作的时候看到了这一行。Mysql通过MVCC多版本并发控制解决了幻读问题。
 可串行化:该级别强制事务串行执行。简单来说就是事务操作数据库时对被擦操作的数据加锁,这样会浪费大量的资源,所以一般只有非常强调数据一致性的时候才会使用该级别。

数据库范式

 1NF:属性不可分,要求属性具有原子性
 2NF:属性完全依赖主键,每个非主属性由整个主键函数决定,而不是一部分
 3NF:属性不依赖其他非主属性,消除传递依赖
 BCNF:在1NF的基础上,要求任何非主属性,不能依赖主键子集
 4NF:要求把同一个表内多对多的关系删除
 5NF:从最终的机构重新建立原始数据
 总结:2NF要求唯一性,即非主属性依赖且只依赖主属性,3NF是对字段冗余性的要求,即任何字段不能由其他字段派生出来,要求没有冗余。

MYSQL中的MVCC

 多版本并发控制,MVCC是指通过版本号让每个事物到达的时候看到的都是数据库某个时刻的快照,这样会减少很多需要锁的场景。具体而言CAS,每次操作,copy一份操作的数据作为副本,副本之间通过版本号区分,并将副本的版本号加1,如果是更新操作,数据在副本修改完成后,要查看原来记录的版本号是否为副本版本号-1,是则更新,否则失败,重新取数据更新;如果是读操作,则因根据隔离级别读取小于等于当前事务版本号的数据。
 在InnoDB中,mysql会为每一行添加两个字段,分表表示该行的创建版本号和删除版本号,这样
 SELECT时,读取创建版本号小于等于当前事务版本号且删除版本号为空或删除版本号大于当前事务版本号的数据;
 INSERT时,保存当前事务版本号为行的创建版本号;
 DELETE时,保存当前事务版本号为行的删除版本号;
 UPDATE时,插入一条新的记录,保存当前事务版本号作为创建版本号,同时保存当前事务版本号作为旧数据的删除版本号。
 Mysql可以配置清理删除版本号小于等于当前数据库版本号的数据。

mysql中的锁

行级锁和间隙锁

 innodb默认使用next-key锁定记录,具体而言,该锁包含两种类型的锁,行级锁、间隙锁。具体而言,行级锁是指给指定行加锁,锁定的是一条或多条已经存在的行;间隙锁锁定的是范围,比如[2,4]这个区间范围内在锁释放之前不允许修改或插入数据。innodb会视情况默认使用这两种类型的锁(单独或组合使用)。例如update table set keyA=test where id = 1,该事务提交时innodb会锁定id=1这条记录,行锁通过给索引(非主键索引除了给自己加锁也会给记录的主键索引加锁)加锁实现,这里需要注意更新时条件一定要使用索引,不然会使用表锁,影响性能。

读锁和写锁

 读锁和写锁都是应用于"当前读"之上,快照读是不加锁的。使用读锁读取的时候会锁定记录,被锁定的记录不允许修改,但是允许其他事务读取,因此读锁也被称为共享锁。写锁又称为排它锁,被锁定的记录只允许当前事务读取和修改不允许其他事务读取和修改。

快照读和实时读

 快照读是MVCC下的产物,也是一般select语句执行的场景,即select语句一般是读取小于等于当前事务版本号的有效数据,也就是从数据库某个时刻的快照中读取数据。
 实时读,一般而言,涉及到数据库记录的更新都是实时读,实时读一般存在加锁,通过锁锁定记录或者表的当前状态,然后读数据进行更新或者插入新的数据。

mysql中的log

 redolog和undolog,两者是在innodb引擎层面实现的,redolog记录的是事务修改后的值,undolog记录的是事务提交之前记录的值。具体而言,事务提交前会现在undolog中生成一条可用于回滚的记录,如插入记录对应一条删除记录,更新记录对应一条复原的更记录等等。之后innodb会将在内存中修改对应的数据,成功后会将新值记录写入redolog buffer,(innodb定期批量刷入磁盘文件,减少io消耗)。
 binlog是在数据库层面实现的,记录的是整个数据库的更新操作,和引擎无关。也就是在redolog之后mysql会通过binlog记录数据的变化,之后再将这种变化写入缓存区,之后mysql会异步刷新磁盘上的数据分页,刷盘策略支持多种。数据库可以根据binlog恢复和复制。一般mysql的主从复制就是通过binlog实现,mysql主库binlog记录完成后会将变化推送给从库的relaylog,从库会根据这种变化同步。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值