定义
一个数据库事务通常包含了一个序列的对数据库的读/写操作。
它的存在包含有以下两个目的:
1)为数据库操作序列提供了一个从失败中恢复到正常状态的方法,
同时提供了数据库即使在异常状态下仍能保持一致性的方法;
2)当多个应用程序在并发访问数据库时,可以在这些应用程序之间提供一个隔离方法,
以防止彼此的操作互相干扰。
简单来讲,事务的作用至少有两个:
1、保证数据一致性
2、对数据进行隔离
数据库3大范式
第一范式(1NF)无重复的列
第二范式(2NF)属性完全依赖于主键[消除部分子函数依赖]
第三范式(3NF)属性不依赖于其它非主属性[消除传递依赖]
事务4大特性
ACID - 原子性(Atomicity),一致性(Consistency),隔离性(Isolation),持久性(Durability)
1、原子性,指的是一个事务必须被视为一个不可分割的最小工作单元,
整个事务中的操作要么全部提交成功,要么全部失败回滚,
也就是说不可能只执行事务中的部分操作,这就是事务的原子性。
2、一致性,指的是事务应确保数据库的状态从一个一致状态转变为另一个一致状态。
以转账的例子为例,转账后A的账户减少100块钱,B的账户增加100块钱是满足数据一致性的,
事务可以保证事务成功提交之后数据库转化为这个状态,如果事务失败回滚了,则还是保持最初的一致性状态,
而不会出现上述的A的账户减少100块钱,B的账户没有变化的不一致的中间状态。
3、隔离性,指的是多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
比如当A向B转账的过程中,B也可以向A转账,这2个事务互不影响,
而且通常来讲也是互不可见的(注意,是通常来讲“不可见”,后续事务隔离级别的时候再详述)。
4、持久性,指的是已被提交的事务对数据库的修改应该被永久保存在数据库中。
这个比较好理解,就是说已成功提交的事务会被永久地保存下来。
事务的隔离级别
读未提交,读已提交,可重复读,串行化
1、读未提交,指的是事务中未提交的修改,对于其他事务而言是可见的,这是隔离性最低的一种级别了。
在这种隔离级别下,会出现“脏读”的情况。所谓“脏读”指的是读取到了其他事务未提交的数据。
以2个事务同时进行为例,因为事务A可以读到事务B的未提交的修改数据,
假如说事务B在事务A结束之前因为发生异常而回滚了,那么A读到的事务B的未提交的数据就是“过期”的,
如果事务A在这个“过期”数据上进行操作,那势必会造成数据不一致的情况。因此这种隔离级别在实际中很少使用。
2、读已提交,指的是一个事务开始时,只能看到其他已经提交的事务对数据所做的修改。
这种隔离级别可以防止“脏读”的问题出现。但是这种情况可能会出现“不可重复读”的问题。
所谓不可重复读是指,事务A先后2次读到的数据不一致。
举个例子,事务A先读到小明的账户余额为100块钱,然后再做了其他操作(假设这些操作没有改变小明的余额),
这个时候事务B将小明的账户扣了10块钱,变成90块钱了并提交了,
由于事务A可以读到事务B提交的修改数据,所以当事务A执行了其他操作后再读取小明的余额时就变成90块了,
因此前后2次读取的数据不一致,故出现了“不可重复读”的问题。
3、可重复读,指的是可以避免上述“不可重复读”的情况出现,
即它可以保证在同个事务中,先后读到的同一行数据是一致的,然而这种隔离级别下会出现另一个问题,
就是“幻读”。“幻读”指的是事务A读取到了事务B新增的数据,因此出现了“幻行”。
举个例子,事务A一开始查询到小明在1月份一共网购了100次,
然后再进行其他操作(假设这些操作没有改变小明的网购记录数),
然后事务B插入了一条小明新的网购记录并提交了,接下来事务A再统计出小明的网购记录,
变成101次了,出现了“幻行”,也就是出现了“幻象读”。
4、串性化,指的是强制事务串行执行,其可以避免“幻象读”的问题出现,这是最严格的隔离级别了。
因为串行化需要在发生竞争的数据上加锁,所以并发性能不高,
只有在对数据一致性要求非常高且并发度不高的情况下才会考虑使用这种隔离级别。
数据库视图
视图(View)是从一个或多个表(或视图)导出的表。
视图与表(有时为与视图区别,也称表为基本表——Base Table)不同,
视图是一个虚表,即视图所对应的数据不进行实际存储,数据库中只存储视图的定义,
在对视图的数据进行操作时,系统根据视图的定义去操作与视图相关联的基本表。
数据库触发器
一种特殊的存储过程。一般的存储过程是通过存储过程名直接调用,而触发器主要是
通过事件(增、删、改)进行触发而被执行的。其在表中数据发生变化时自动强制执行。
常见的触发器有两种:after(for)、instead of,用于insert、update、delete事件。
after(for) 表示执行代码后,执行触发器
instead of 表示执行代码前,用已经写好的触发器代替你的操作
数据库存储过程
SQL的调用可以分为函数和存储过程
存储过程可以看作是在数据库中的存储t-sql脚本
存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL语句集,
它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参数
(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。
为什么使用存储过程
1、增加性能 本地存储发送的内容少、调用快、预编译、高速缓存
一般语句的执行:检查权限、检查语法,建立执行计划处理语句的要求
存储过程:创建时已经检查了语法;第一次执行的时候执行计划被创建,被编译;
再次执行时不需要重检查语法、不需要重编译、根据已经缓存的计划来决定是否需要重创建执行计划
2、增强安全 加密、分离
(权限设置,用户只需要有执行存储过程的权限,不需要有访问存储过程所使用的对象的权限)