长期从事数据仓库的你,是否还记得数据库设计中的三大范式?在设计数据仓库的表时,是否考虑过规范化和反规范化之间的区别?是否想过数据仓库和数据库在设计中对范式考虑的侧重点是什么?html
本文,将包含以下几个方面:数据库
全文将会围绕一个订单表(假设一个订单中只有一种商品出现)设计的例子,既有数据库中表的设计,亦有数据仓库中表的设计,一个例子贯穿全文,善始善终,简单易懂。数据库设计
首先回顾一下范式是什么:性能
设计关系数据库时,听从不一样的规范要求,设计出合理的关系型数据库,这些不一样的规范要求被称为不一样的范式,各类范式呈递次规范,越高的范式数据库冗余越小。学习
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。优化
数据库范式有这么多,可是在工做中经常使用到的通常是前三个范式,所以,本文将只举例分享第1、2、三范式。为了方便理解,先上一个关于各个范式核心点的图镇楼,后面的说明会参考该图来进行。设计
咱们暂且将第一种设计称为第零范式,它知足一个基本条件:无重复数据。htm
以下,是咱们按照无范式设计的第一张订单表。虽然说该设计将成为一个被挑毛病的坏孩子,但从设计上来看,还是可被理解的。blog
该设计和第零范式的区别在于咱们将“购买信息”这一个字段拆成了“购买单价”和“购买数量”两个字段,新表知足了第一范式。事件
第二范式在第一范式的基础之上更进一层。第二范式须要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。即在第一范式的基础上知足属性彻底依赖于主键。
以第一范式中的设计为例,商品数量、总金额和购买日期是彻底依赖于(用户ID,商品ID)的,可是商品名和商品价格只依赖于商品ID,用户信息只依赖于用户ID,这属于部分依赖。
所以,将用户信息和商品信息单独拎出来后,咱们的订单表设计就变成了以下三张表:订单表,商品表和用户表。直观一点来理解第二范式的话,就是说一个数据表中只能保存一种数据,不能够把多种数据保存在同一张数据库表中。
第三范式须要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。即在第二范式的基础上知足属性只直接依赖主键。
以第二范式中的设计为例,如今订单表中的信息已经彻底依赖于订单ID了,该设计是知足第二范式的。可是在用户表中,用户ID和地址信息是存在传递依赖的,即:用户ID决定地址ID,地址ID决定(省,市,县),这是传递依赖。
所以,我在地址信息表单独拎出来以后就能够设计出以下知足第三范式的表了。
0x02 数据仓库和三范式
以上,简单回顾了一下三范式的内容,下面将分析一下数据仓库中的数据建模和三范式之间的关系。
范式建模是数据仓库之父 Bill lnmon 提出的建模方法是从全企业的高度设计一个第三范式的模型,用实体关系(Entity Relationship, ER)模型描述企业业务,在范式理论上符合第三范式。
所以咱们能够认为数据仓库中的范式建模,在表的设计上和范式中的第三范式基本上一致的,具体到表的设计是能够以下内容。
维度模型是数据仓库领域另外一位大师 Ralph Kimball 所倡导,维度建模以分析决策的需求出发构建模型,构建的数据模型为分析需求服务,所以它重点解决用户如何更快速完成分析需求,同时还有较好的大规模复杂查询的响应性能。
维度建模的理论就再也不细说,咱们只介绍两个主要概念:事实表和维度表。
事实表:咱们能够简单地将事实理解为现实中发生的一次操做型事件。好比订单表,咱们就能够理解为一张事实表,咱们每完成一个订单,就会在订单事实表中增长一条记录。
维度表:咱们能够简单地理解维度表包含了事实表中指定属性的相关详细信息。好比商品维度表表和用户维度表。
那么用维度建模的方式进行设计的话,咱们会设计以下三张表:订单事实表、商品维度表和用户维度表。这种设计,在范式理论上符合第二范式。
通常你们也会称维度建模是星星模型,能够将事实表看成是中间最大的一颗星星,维度表围绕在事实表周围。星星模型和雪花模型的主要区别在于维度表是否都和事实表直接相连。以下图,将咱们的星星模型转换成了雪花模型,好比年维度表并非直接连在订单事实表上,而是连在日期维度表上。
所以,简单点来说,咱们能够认为星星模型是将同一主题的维度信息冗余在了一张维表中。
在维度建模中咱们聊到了事实表的设计,它实际上是符合第二范式的设计,可是在实际工做中咱们常常会在事实表中存放更多的信息,以便更好地知足业务需求。
以下图,咱们会将用户信息和商品信息都冗余到订单事实表中,在这种状况下,该事实表的设计在范式理论上符合第一范式。
在大部分的数据仓库设计中,通常是不怎么考虑是否知足第几范式的,特别是互联网场景下的数据建设就更少考虑数据仓库和范式之间的关系,可是这并不妨碍咱们去理解它们设计背后的出发点。至少咱们能够搞明白为何数据仓库设计不用过多关注范式。
咱们这里聊到的数据库的设计,能够理解是联机事务处理OLTP(On-Line Transaction Processing),主要是基本的、平常的事务处理,例如银行交易。直白点讲,就是各类增删改查,须要对数据进行操做。而数据仓库,咱们能够理解为是联机分析处理OLAP(On-Line Analytical Processing),主要是面向平常数据分析,它的数据主要是插入和查询,基本不涉及删除和修改操做。
本文的主人公-范式,主要优化的是增删改的问题,好比数据冗余、更新异常、删除异常等。这些也正是数据库设计比较关注的点。而数据仓库对这方面的关注度则比较少,数据仓库更关注的是使用是否方便,查询效率是否高,所以在设计数据仓库的时候没必要太多关注范式的设计,通常第一或者第二范式就够用。
另外,数据仓库不一样层级的设计也会用到不一样的建模方式,好比说接近业务数据的层次,会更倾向使用范式建模,接近数据分析的层次则会更倾向于维度建模,这个话题会在数据分层的文章中有更详细的讲解。
本文主要是聊一聊数据仓库和范式之间的关系,算是对数据仓库相关理论的一种梳理。虽然说对平常工做的影响不大,可是仍能够做为补充知识的学习。