数据仓库-数据模型对比
范式建模
该方法主要由Inmon所提倡,主要利用关系型数据库进行数据仓库的建设,且模型的建设方法和业务系统的数据模型比较类似。 经典范式理论中,一个符合第三范式的关系必须具有以下三个条件:
- 1NF 每个属性值维一且不可拆分,不具有多义性。
比如说一张表里面存在如下字段:
姓名 | 地址 |
---|---|
张三 | 湖北省宜昌市 |
那么在第一范式的规定下:
该表违背了不可拆分的条件,所以地址
字段是可以拆成省名、市名两个字段。
姓名 | 省名 | 市名 |
---|---|---|
张三 | 湖北省 | 宜昌市 |
- 2NF
每个非主属性必须完全依赖与整个主键,而非主键的一部分。即每一张表具体只描述一件事。
比如说存在如下一张订单表:
字段名 | 值 | 字段说明 |
---|---|---|
order_id | OID001 | 订单编号 |
order_date | 2020-02-02 | 订单编号 |
product_id | PID001 | 产品编号 |
product_price | 100¥ | 产品价格 |
我们从上面这张表可以看出,该表的product_name
和product_id
并不是完全依赖与订单与order_id
,因此这个表可以拆分成两个表。
- 订单表
字段名 | 值 | 字段说明 |
---|---|---|
order_id | OID001 | 订单编号 |
order_date | 2020-02-02 | 订单编号 |
- 产品表
字段名 | 值 | 字段说明 |
---|---|---|
product_id | PID001 | 产品编号 |
product_price | 100¥ | 产品价格 |
- 3NF
在满足第一范式和第二范式的情况下,每个非主属性不能依赖于其他关系中的属性,即表中的列不存在对非主键列的传递依赖。
比如说存在这样一张订单表:
字段名 | 值 | 字段说明 |
---|---|---|
order_id | OID001 | 订单编号 |
order_date | 2020-02-02 | 订单编号 |
cus_id | CID001 | 顾客编号 |
cus_name | Lany | 顾客名称 |
根据第三范式的规定,除了主键order_id
,cus_name
还依赖与非主键列cus_id
。那么我们就需要将cus_id
从该表中剔除。
优缺点
- 优点
- 节约存储
- 结构清晰
- 易于理解
- 适合关系型数据库
- 缺点
- 构建比较繁琐
- 查询复杂
- 不适合构建在大数据分布式环境下
为什么?
数据仓库的上游有相当一部分数据源是业务数据库,而这些业务数据库,其理论一般基于范式建模 数据源的规范定义需要我们了解范式理论 数据仓库下游系统比如报表系统设计时,可能会用到范式理论。
维度建模
- 选择业务过程
- 声明粒度
- 确认维度
- 确认事实
优点: 方便使用 适合大数据下的数据处理 适合进行OLAP操作 缺点 维度补全造成的数据存储的浪费 维度变化造成的数据更新量大 与范式理论差异很大,是典型的反三范式
思考
- 范式建模里面的范式,具体指的是什么,哪些情况下会使用到范式?
- 第一范式:解决冗余数据组
- 第二范式:解决部分依赖现象
- 第三范式:解决传递型函数依赖现象
- 用范式的目的: 去除冗余并提高灵活性
还有一种复杂情况下的范式讲解:参考文章
- 维度建模理论中的反范式是指的什么,为什么会这样操作?
反范式是试图通过增加冗余数据或通过分组数据来优化数据库性能的过程。
范式化的设计是在不同的有关系的表中存储不同的信息,如果需要查询详细,往往是join多个表,如果join的表很多,将会导致很多随机io,那么查询可能会很慢。
- 维度建模的四个步骤?
- 选择业务过程
业务过程是一系列操作活动,转换为事实表中的事实,例如每个月每个账单快照。
- 声明粒度
粒度是指事实表中的一行代表什么。同一事实表不要混用粒度,最好从最小粒度开始设计维度,因其能承受用户无法预知的查询需求。例如每一条记录代表一个有效订单。
- 确认维度
维度是根据粒度将表分成多个维度表,即从不同维度(角度)去看。例如商户维度、用户维度、支付维度、收货维度。 维度是数据仓库的灵魂,是BI的入口和驱动。
- 确认事实
事实是指一种在某个粒度下的度量,例如在销售维度中,销量和总额是良好的事实,而商店经理的工资则不允许出现在该维度中。例如订单总金额。