1、三范式
范式是什么:
设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。 目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
数据库范式有这么多,但是在工作中常用到的一般是前三个范式。
下面将会围绕一个订单表(假设一个订单中只有一种商品出现)设计的例子来进行介绍。
1.1 第零范式
第零范式满足一个基本条件:无重复数据
如下,是按照无范式设计的一张订单表。虽说该设计将成为一个被挑毛病的坏孩子,但从设计上来看,仍是可被理解的。
给这个表格加几行数据,该设计的一个字段“购买信息”里面包含了两部分内容:商品价格和购买数量。
| 用户ID | 商品ID | 用户地址(省) | 用户地址(市) | 用户地址(县) | 商品名 | 购买信息(价格,数量) | 总金额 | 购买日期 |
|---|---|---|---|---|---|---|---|---|
| user_001 | product_001 | xx省 | xx市 | xx县 | 手机1号 | 200,5 | 1300 | 20221201 |
| order_002 | product_003 | xx省 | xx市 | xx县 | 电脑1号 | 1000,1 | 1000 | 20221202 |
| order_003 | product_002 | xx省 | xx市 | xx县 | 手机2号 | 100,5 | 500 | 20221204 |
1.2 第一范式
第一范式的核心在于 Atomic columns(cells have single value),即属性不可分。
该设计和第零范式的区别在于将“购买信息”这一个字段拆成了“购买单价”和“购买数量”两个字段,新表就满足了第一范式。
1.3 第二范式
第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。即在第一范式的基础上满足属性完全依赖于主键。
以第一范式中的设计为例,商品数量、总金额和购买日期是完全依赖于(用户ID,商品ID)的,但是商品名和商品价格只依赖于商品ID,用户信息只依赖于用户ID,这属于部分依赖。
因此,将用户信息和商品信息单独拎出来后,我们的订单表设计就变成了如下三张表:订单表,商品表和用户表。
直观一点来理解第二范式的话,就是说一个数据表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
1.3 第三范式
第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。即在第二范式的基础上满足属性只直接依赖主键。
以第二范式中的设计为例,现在订单表中的信息已经完全依赖于订单 ID 了,该设计是满足第二范式的。但是在用户表中,用户 ID 和地址信息是存在传递依赖的,即:用户 ID 决定地址 ID,地址 ID 决定(省,市,县),这是传递依赖。
因此,在地址信息表单独拎出来之后就可以设计出如下满足第三范式的表了。
2、数仓和三范式
2.1 范式建模
范式建模是数据仓库之父 Bill lnmon 提出的建模方法,是从全企业的高度设计一个第三范式的模型,用实体关系 ER(Entity Relationship)模型描述企业业务,在范式理论上符合第三范式。
因此在表的设计上,我们可以认为数仓中的范式建模和第三范式基本上一致的,具体到表的设计是可以如下内容。
2.2 维度建模
维度模型是数据仓库领域另一位大师 Ralph Kimball 所倡导,维度建模以分析决策的需求出发构建模型,构建的数据模型为分析需求服务,因此它重点解决用户如何更快速完成分析需求,同时还有较好的大规模复杂查询的响应性能。
维度建模的理论就不细说,只介绍两个主要概念:事实表和维度表。
- 事实表:我们可以简单地将事实理解为现实中发生的一次操作型事件。比如订单表,我们就可以理解为一张事实表,我们每完成一个订单,就会在订单事实表中增加一条记录。
- 维度表:我们可以简单地理解维度表包含了事实表中指定属性的相关详细信息。比如商品维度表表和用户维度表。
那么用维度建模的方式进行设计的话,我们会设计如下三张表:订单事实表、商品维度表和用户维度表。这种设计,在范式理论上符合第二范式。
一般大家也会称维度建模是星星模型,可以将事实表当作是中间最大的一颗星星,维度表围绕在事实表周围。星星模型和雪花模型的主要区别在于维度表是否都和事实表直接相连。如下图,将我们的星星模型转换成了雪花模型,比如年维度表并不是直接连在订单事实表上,而是连在日期维度表上。
2.3 有冗余的事实表
在维度建模中我们聊到了事实表的设计,它其实是符合第二范式的设计,但是在实际工作中我们经常会在事实表中存放更多的信息,以便更好地满足业务需求。
如下图,我们会将用户信息和商品信息都冗余到订单事实表中,在这种情况下,该事实表的设计在范式理论上符合第一范式。
3、数据仓库和数据库的侧重点
在大部分的数据仓库设计中,一般是不怎么考虑是否满足第几范式的,特别是互联网场景下的数据建设就更少考虑数据仓库和范式之间的关系,但是这并不妨碍我们去理解它们设计背后的出发点。至少我们可以搞明白为什么数据仓库设计不用过多关注范式。
我们常用的数据库的设计,可以理解是联机事务处理OLTP(On-Line Transaction Processing),主要是基本的、日常的事务处理。直白点讲,就是各种增删改查,需要对数据进行操作。而数据仓库,我们可以理解为是联机分析处理OLAP(On-Line Analytical Processing),主要是面向日常数据分析,它的数据主要是插入和查询,基本不涉及删除和修改操作。
范式,主要优化的是增删改的问题,比如数据冗余、更新异常、删除异常等。这些也正是数据库设计比较关注的点。而数据仓库对这方面的关注度则比较少,数据仓库更关注的是使用是否方便,查询效率是否高,因此在设计数据仓库的时候不必太多关注范式的设计,一般第一或第二范式就够用。
另外,数据仓库不同层级的设计也会用到不同的建模方式,比如说接近业务数据的层次,会更倾向使用范式建模,接近数据分析的层次则会更倾向于维度建模。
