说到数据库,以前我老师有一句很经典的话 。你可以不会写SQL,但是一定不能不知道ACID 。
在工业领域,SQL可以说是应用最广泛的技术 。从后端到算法,从数据到DBA,再到产品,甚至连一些运营也会基本的SQL 。所以如果你现在还不太会的话,我建议你用一个下午的时间找个网站好好学一下 。
原本我是想直接写些Hbase相关的内容,但是我发现要想讲清楚Hbase,必须要讲noSQL数据库 。如果将noSQL,则又离不开最传统的关系型数据库 。所以我们一步一步来,先从基础的关系型数据库讲起 。或许我这么说并不准确,因为数据库并不基础,相反它十分复杂 。从索引到各种优化和设计原理,再到内部的各种算法和数据结构,涉及到的内容非常多 。我们先把浩如烟海的知识放一放,先从最核心的数据库四大原则开始说起 。
数据库事务ACID四大原则,A代表Atomicity,即原子性 。C表示Consistency,即一致性 。I表示Isolation,即隔离性 。D表示Durability,即持久性 。
这四个原则了解过数据库的应该都如雷贯耳 。可是真正面试的时候被问起来,能一个不落说得上来,并且讲得清楚原委的就不多了 。我觉得主要是因为我们的翻译过于文雅,不像英文那么直观,所以很难顾名思义 。另一个原因是我们在学习的时候理解不够深入,只知道原因,不知道原因的究竟 。所谓知其然,不知其所以然 。
文章插图
原子性
让我们先从其中最简单的原子性开始 。
原子性理解起来最简单,也最常用 。我就在面试当中遇见过不止一次,还有一次让我用JAVA写一个转账的功能,其实就是想看看我知不知道原子性 。
原子两个字看起来一头雾水,其实这里不是指物理学上的基本粒子,而是指的不可分割的意思 。也就是说在一个事务当中的所有操作应该被视为一个不可分割的整体,要么全成功,要么全部失败 。这点用转账这个问题举例最合适 。A将银行卡里的钱转100给B,很明显,数据库需要做两件事情,一件事A账户扣款100,另一件是B账户收入100 。但问题来了,计算机系统并不是100%可靠的,可能会存在极小的可能失败 。如果A扣款之后,发生网络延迟或者系统down机,导致B账户的钱没有增加,那怎么办?A不是白白扣了钱?
文章插图
A白白扣了钱是小事,一个金融系统如此不稳定,显然是不能接受的 。所以,在数据库的事务当中,应该保证原子性 。扣钱和收钱虽然是两个操作,但是应该被视为一个 。要么一起成功,要么一起失败 。失败了还可以重试,如果成功了一半,那都不知道该怎么修复了 。
事务的一种实现方法是在执行的时候先不将最终的结果更新到数据库,而是先写在事务日志上 。等整个事务执行成功之后,再将事务日志上的内容同步到数据库当中 。如果失败了,则将事务日志删除,完成回滚 。
持久性
第二个要介绍的是持久性 。
持久性指的是数据的持久性,指的是事务完成了之后,这个事务对数据库所作出的修改就被持久地保存进了数据库当中,不会再被回滚操作影响 。即使出现了各种事故,比如机房断电、网络故障等等意外情况,数据库当中的数据也不能丢失 。
但是前文当中说了,计算机系统很难做到100%可靠 。如果万一的情况发生了,数据库当中的数据丢了,那么应该怎么办呢?
没关系,之前在介绍原子性的时候介绍过了 。所有的事务操作在执行之前,都会先把数据记录到事务日志当中,再同步到数据库 。即使是数据库里的数据丢失了,那么只要根据事务日志重新执行一遍对应的操作,就可以恢复数据库当中的数据,维持数据库的持久性 。实际上,现在的数据库默认会将所有的操作都当做事务来执行,因此基本上不用担心数据丢失的情况 。
隔离性
然后,介绍的是隔离性 。
在我们理解了原子性之后,隔离性就很好理解了 。当我们同时有多个事务一起执行的时候,如果隔离性做得不好,很有可能导致很多问题 。
以下四种问题最常见:
1. 脏读
推荐阅读
- MySQL数据库下的Explain命令深度解析
- 一文搞懂SQL中的所有JOIN
- MySQL, PostgreSQL CentOS常用数据库安装和python使用
- 程序员该如何进行 SQL 数据库的优化?
- 一条SQL搞定数据库设计文档
- 开源免费的多功能数据库管理软件DBeaver
- 一文读懂Socket通信原理
- 安装MySQL数据库
- 史上最全数据库中间件详解
- PHP操作Redis常用方法总结