登录/注册
张三
2681
占位
0
占位
0
浏览量
占位
粉丝
占位
关注
数据库.markdown
张三
2020-11-26 15:34:53 2020-11-26
142
0

数据库三范式

第一范式(1NF)

强调的是列的原子性,即列不能够再分成其他几列。
考虑这样一个表:【联系人】(姓名,性别,电话)
如果在实际场景中,一个联系人有家庭电话和公司电话,那么这种表结构设计就没有达到 1NF。要符合 1NF 我们只需把列(电话)拆分,即:【联系人】(姓名,性别,家庭电话,公司电话)。1NF 很好辨别,但是 2NF 和 3NF 就容易搞混淆。

说明:在任何一个关系数据库中,第一范式(1NF)是对关系模式的设计基本要求,一般设计中都必须满足第一范式(1NF)。不过有些关系模型中突破了1NF的限制,这种称为非1NF的关系模型。换句话说,是否必须满足1NF的最低要求,主要依赖于所使用的关系模型。

第二范式(2NF)

首先是 1NF,另外包含两部分内容,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。

考虑一个订单明细表:【OrderDetail】(OrderID,ProductID,UnitPrice,Discount,Quantity,ProductName)。

因为我们知道在一个订单中可以订购多种产品,所以单单一个 OrderID 是不足以成为主键的,主键应该是(OrderID,ProductID)。显而易见 Discount(折扣),Quantity(数量)完全依赖(取决)于主键(OderID,ProductID),而 UnitPrice,ProductName 只依赖于 ProductID。所以 OrderDetail 表不符合 2NF。不符合 2NF 的设计容易产生冗余数据。
可以把【OrderDetail】表拆分为【OrderDetail】(OrderID,ProductID,Discount,Quantity)和【Product】(ProductID,UnitPrice,ProductName)来消除原订单表中UnitPrice,ProductName多次重复的情况。

第二范式(2NF)要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。简而言之,第二范式就是在第一范式的基础上属性完全依赖于主键。

第三范式(3NF)

在1NF基础上,任何非主属性不依赖于其它非主属性[在2NF基础上消除传递依赖]。

第三范式(3NF)是第二范式(2NF)的一个子集,即满足第三范式(3NF)必须满足第二范式(2NF)。

首先是 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。 考虑一个订单表【Order】(OrderID,OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity)主键是(OrderID)。

其中 OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity 等非主键列都完全依赖于主键(OrderID),所以符合 2NF。不过问题是 CustomerName,CustomerAddr,CustomerCity 直接依赖的是 CustomerID(非主键列),而不是直接依赖于主键,它是通过传递才依赖于主键,所以不符合 3NF。

通过拆分【Order】为【Order】(OrderID,OrderDate,CustomerID)和【Customer】(CustomerID,CustomerName,CustomerAddr,CustomerCity)从而达到 3NF。

第二范式(2NF)和第三范式(3NF)的概念很容易混淆,区分它们的关键点在于,2NF:非主键列是否完全依赖于主键,还是依赖于主键的一部分;3NF:非主键列是直接依赖于主键,还是直接依赖于非主键列。

读写锁

为了解决并发控制问题,数据库通过共享锁(读锁)和排它锁(写锁)来控制。

锁粒度

MySQL提供了多种选择。每种存储引擎都可以实现自己的锁策略和锁粒度。下面介绍两种最重要的锁策略:

表锁:

表锁是MySQL 中最基本的锁策略,并且是开销最小的策略。他会锁住整张表。一个用户在对表进行写操作的时候必须要获得写锁,这回阻塞其他用户对该表的所有读写操作。只在没有写锁的时候,其他读取的用户才能获得读锁,读锁之间是不相互阻塞的。

在特定的场景中,表锁也能有良好的性能。例如,READ LOCAL 表锁支持某些类型的并发写操作。另外,写锁也比读锁具有更高的优先级,因此,一个写锁请求可能插入到读锁请求队列的前面(写锁可以插入到读锁前面,但是读锁不能插入到写锁前面)

尽管存储引擎可以自己管理自己的锁,MySQL 本身还是会提供不同的表锁来实现不同的目的。例如:服务器会为诸如 ALERT TABLE 之类的语句提供表锁,而忽略存储引擎的锁机制。

行级锁:

行级锁可以最大程度的支持并发处理(同时带来的最大的锁开销)。在InnoDB和XtraDB,以及一些其他存储引擎中实现了行级锁。行级锁只在存储引擎层中实现,而MySQL 服务器层没有实现。服务器层完全不了解存储引擎中锁的实现。

事物:

数组库必须的四个特性

  1. 原子性(atomicity):事务包含的所有操作要么全部成功,要么全部失败回滚;成功必须要完全应用到数据库,失败则不能对数据库产生影响
  2. 一致性 (consistency): 事务执行前和执行后必须处于一致性状态 例:用户A和用户B的前加起来一共是5000; 无论AB用户之间是如何相互转换的,事务结束后两个用户的钱加起来还是5000,这就是事务的一致性。
  3. 隔离性 (isolation): 当多个用户并发访问数据库时,数据库为每一个用户开启的事务,不被其他事务的操作所干扰,多个并发事务之间要相互隔离;
  4. 持久性 (durability): 一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便在数据库系统遇到故障的情况下也不会丢失事物的操作。

隔离性:当多个线程都开启事务来操作数据库中的数据时,数据库系统要进行隔离操作,以保证各个线程获取数据的准确性。 不考虑事务的隔离性,会产生的几种问题:

01:脏读

A 在一个事物中,正在访问数据,并且对数据进行了修改,而这种修改还没有提交。但是这期间B读取并使用了这个未提交的数据

例:用户A向用户B转账100元,A通知B查看账户,B发现前确实已到账,而之后无论第二条SQL是否执行,只要该事务不提交,则所有操作都将回滚,当B再次查看账户时就会发现前其实并没有到账。

02:不可重复读

A在一个事物中多次读取数据的过程中,由于B也读取并修改了这个数据,导致了A在同一个事物中读取到的数据不同。

不可重复读是指在一个事务内,多次读取同一个数据,在这个事务还没有结束 ,另一个事

暂无评论