数据库的事务性
事务处理
事务ACID属性
Hello,小伙伴们大家好!我是灰小猿,一个超会写bug的程序猿!
在进行比较正规的项目开发的时候,通常会根据需求设计相应的数据库,而这些数据库则通常需要考虑数据库的冗余性和简洁性,数据库三大范式就是对关系数据库设计结构的一个规定。
什么是范式?
==========
当一个关系中的所有分类都是不可再分的数据项时,该关系是规范化的。不可再分的数据项,即不存在组合数据项和多项数据项。一个低一级的关系模式,通过模式分解可以转换为若干高一级范式的关系模式的集合,这个过程就叫规范化。二维数据表可以分为5级范式为1NF、2NF、3NF、4NF、5NF。第一范式满足最低的要求条件,第五范式满足最高要求的条件。并且在数据库设计中我们要秉承以更高范式设计标准的原则设计和开发数据库。
那么接下来我和小伙伴们简单介绍一下数据库中常用的三大范式:
第一范式(1NF)
=============
概念:数据库中所有元素都是不可再分的,确保元素的原子性
从概念上我们其实也很好理解,第一范式所说的就是每一列中的属性值都是不可再分的。打个比方如下表:
院系 | 人数 | |
男生 | 女生 | |
软件学院 | 1652 | 689 |
计算机学院 | 1264 | 489 |
大数据学院 | 653 | 534 |
人数列中的属性是可以再次分割成男生和女生人数的,这就不满足了数据库设计的第一范式中的“每一列的属性值都是不可再分的”。
那么对于这样的设计,如何使非规范式设计转换为规则的第一范式呢?
其实很简单,只需要将可再分的子属性单独拿出成列即可。
如上表变成第一范式设计:
院系 | 男生 | 女生 |
软件学院 | 1652 | 689 |
计算机学院 | 1264 | 489 |
大数据学院 | 653 | 534 |
第二范式(2NF)
=============
概念:在第一范式的基础上,所有非主属性都完全依赖于主码。
换句话说就是:在满足第一范式的前提下,确保每一个实例或者每一行都可以被唯一的标识,
但是值得注意的是:符合第二范式的关系模型可能还存在数据冗余、更新异常等问题。同时这也是第二范式所存在的一些缺陷和问题。
那么什么样的数据表才是属于满足第一范式而不满足第二范式的呢?
比如这个数据表:
职工号 | 姓名 | 职称 | 项目号 | 项目名 |
1 | 张三 | 程序员 | 111 | C开发 |
2 | 李四 | 软件设计师 | 222 | Java开发 |
3 | 王五 | 高级架构师 | 333 | 大数据开发 |
如表所示:姓名由职工号唯一确定(职工号—>姓名)、职称由职工号唯一确定(职工号—>职称)、但是项目名由项目号唯一确定(项目号—>项目名),这样在该表中,项目名就不能由职工号唯一推出,这样就不满足了第二范式的“所有非主属性完全依赖于主码”
**对于这样的数据表,想要将其转换成满足第二范式,需要将不能够被唯一标识出的属性单独成表,**对于上表,就是将项目信息单独成表,员工信息单独成表。
第三范式(3NF)
=============
概念:关系模型满足第二范式,所有非主属性对任何候选关键字都不存在传递依赖。
也可以说是:属性不依赖于其他非主属性,属性直接依赖于主键
即每个属性都跟主键有直接关系而不是间接关系,像:a–>b–>c。
例如下表所示结构:
学号 | 姓名 | 年龄 | 性别 | 所在院校 | 院校地址 | 院校电话 |
111111 | 张三 | 21 | 男 | 软件学院 | 惠济区 | 123456 |
222222 | 李四 | 22 | 女 | 计算机学院 | 金水区 | 123455 |
333333 | 王五 | 23 | 男 | 大数据学院 | 二七区 | 123444 |
如上表这样一个表结构,就存在上述关系。 学号–> 所在院校 --> (院校地址,院校电话)。我们应该拆开来,如下:
(学号,姓名,年龄,性别,所在院校)–(所在院校,院校地址,院校电话)
所以就满足了属性直接依赖于主键
BC范式(BCNF)
==============
在概念上:BC范式又叫做修改后的第三范式,是在3NF的基础上消除主属性对于码的部分与传递函数依赖
为什么叫修改后的第三范式,由此就可以说明第三范式在某种情况下同样也是存在一定的缺陷的。那么到底存在怎样的缺陷并且如何修改呢?
我们以一个实际的数据表实例来说明:
对于一个仓库管理系统,现有若干个仓库, 每个仓库只能有一名管理员,一名管理员只能在一个仓库中工作;一个仓库中可以存放多种物品,一种物品也可以存放在不同的仓库中。每种物品在每个仓库中都有对应的数量。
仓库名 | 管理员 | 物品名 | 数量 |
一号仓 | 张三 | 手机 | 12 |
一号仓 | 张三 | 电脑 | 20 |
二号仓 | 李四 | 电机 | 35 |
二号仓 | 李四 | 空调 | 26 |
那么关系模式 仓库(仓库名,管理员,物品名,数量) 属于哪一级范式?
我们来对它分析一下:
**已知函数依赖集:**仓库名 → 管理员,管理员 → 仓库名,(仓库名,物品名)→ 数量
码:(管理员,物品名),(仓库名,物品名)
**主属性:**仓库名、管理员、物品名
**非主属性:**数量
由于不存在非主属性对码的部分函数依赖和传递函数依赖。所以此关系模式属于3NF。
现在我们对上述数据表进行一些操作:
1、在一号仓添加一个新的物品“平板”,
那么我们需要输入的数据是(仓库名、管理员名、物品名、数量),这个时候大家会不会有一个发现,我在仓库中存放数据,我只需要知道把该物品放到了哪一个仓库就行了,为什么还要输入管理员名呢?这样是不是就显得有些麻烦了。
2、给二号仓换一个管理员“王五”,
这个时候我们要做的应该是将每一条二号仓的数据中的管理员名这个属性,都要修改成“王五”,这样是不是就很麻烦了。
**造成此问题的原因:**存在着主属性对于码的部分函数依赖与传递函数依赖。(在此例中就是存在主属性【仓库名】对于码【(管理员,物品名)】的部分函数依赖。
解决办法就是要在 3NF 的基础上消除主属性对于码的部分与传递函数依赖。
即将上表拆分成两个表,一个仓库物品表、一个仓库管理员表
仓库物品表
仓库名 | 物品名 | 数量 |
一号仓 | 手机 | 12 |
一号仓 | 电脑 | 20 |
二号仓 | 电机 | 35 |
二号仓 | 空调 | 26 |