业务建表选型
在数据仓库中,拉链表、流水表、全量表、增量表 和 切片表 是常见的几种表类型,它们的设计和使用旨在满足不同的数据存储和分析需求
1. 拉链表
拉链表用于记录数据的全量历史变化,通过记录每一条数据的有效时间段来实现版本管理(有点类似 mysql 中的 mvcc 机制?)
结构特点
- 包含一个有效开始时间(
start_date
)和结束时间(end_date
)字段。 - 当前有效的数据通常将
end_date
设为9999-12-31
(标记为当前数据)。 - 每次更新数据时,关闭旧版本(设置
end_date
为新版本的start_date
-1),并插入新的数据。
适用场景
- 需要查询数据的历史变化过程,如跟踪客户信息变更、产品价格调整等。
- 数据量不大但变更频率较高的场景。
优点:
- 方便追溯历史,能够完整记录数据的变化过程。
- 能很好地支持时间维度的分析。
缺点: 维护较复杂,查询性能可能会随着数据增长而下降。
2. 流水表
流水表记录的是数据发生的事件或者交易,每一条记录表示一个事件或一次操作,通常是逐条追加的。 一天的数据中,会存放一个用户的每条修改记录,但是在拉链表中只有一条记录
结构特点
- 通常是日志型的数据表,没有更新或删除操作。
- 每条记录表示一次事件,如订单交易记录、账户变动记录等。
- 包含时间戳字段(
timestamp
)或其他序列化字段。
适用场景
- 业务操作的细粒度记录,如订单交易流水、用户行为日志。
- 数据统计、报表生成的原始数据来源。
优点:
- 记录精细,数据完全可追溯。
- 数据写入简单(追加操作),易于维护。
缺点:
- 数据量容易快速膨胀。
- 不适合直接用于复杂查询和聚合分析。
3. 全量表
全量表存储的是某一时刻数据的完整快照,每次导入都替换所有数据。
结构特点
- 表中包含业务系统中某实体的完整数据,每次加载是覆盖式更新。
- 表的设计通常直接对应业务系统的结构。
适用场景
- 不需要保存历史数据,关注的是最新状态的业务场景。
- 数据量适中,更新频率不高的场景。
优点:
- 设计简单,查询效率高。
- 适合小型系统或对历史无特殊要求的场景。
缺点:
- 无法记录数据历史变化。
- 数据量较大时,每次全量更新可能会带来性能压力。
4. 增量表
增量表仅记录自上次加载以来新增或变更的数据。
结构特点
- 包含新增数据和变更数据(有时也包括删除标记)。
- 通常需要借助时间戳(
update_time
)或标识字段来确定增量范围。
适用场景
- 数据更新频繁且增量占比低的场景。
- 分布式系统中跨节点同步数据。
优点:
- 减少数据同步量,提高数据更新效率。
- 易于集成到流式处理或增量加载的场景。
缺点:
- 需要与全量表结合才能查询完整数据。
- 处理不当容易导致数据不一致。
5. 切片表
切片表通过时间、区域、类别等字段将数据分片存储。
结构特点
- 表按照某一维度(如日期、地区)分区存储。
- 每个分区存储的数据独立,分区字段可以是物理分区(存储层)或逻辑分区(查询优化层)。
适用场景
- 数据量极大且可以按照某一维度划分的场景。
- 查询需求主要集中于某些分区,如按日期查询最近一个月数据。
优点:
- 提高查询效率,避免全表扫描。
- 易于数据归档和生命周期管理。
缺点:
- 分区维度的设计需要与业务高度相关。
- 可能导致部分分区热点问题。
总结对比
表类型 | 是否记录历史 | 更新方式 | 数据量管理 | 应用场景 | 优点 | 缺点 |
---|---|---|---|---|---|---|
拉链表 | 记录历史 | 更新闭合旧记录 | 较小 | 数据追溯,时间维度分析 | 能完整记录历史变化,支持时间维度分析 | 查询性能随数据增长下降,维护复杂 |
流水表 | 记录详细事件 | 追加为主 | 较大 | 日志分析,事件流统计 | 数据精细可追溯,写入简单 | 数据量增长快,不适合复杂查询和聚合分析 |
全量表 | 不记录历史 | 覆盖更新 | 中等或较大 | 只需关注最新状态的场景 | 查询效率高,设计简单 | 无法记录历史变化,全量更新对大表性能有压力 |
增量表 | 部分历史 | 追加增量 | 较小 | 高频变更,节省数据传输 | 减少同步量,提高更新效率 | 查询完整数据需要结合全量表,可能导致数据不一致 |
切片表 | 不同分区可控 | 分区更新 | 超大 | 数据分区存储,分段查询 | 提高查询效率,便于归档和生命周期管理 | 分区设计需与业务相关,可能出现分区热点问题 |
场景分析
一张用户表,大约10亿条记录,50个字段,这种表,即使使用ORC压缩,单张表的存储也会超过100G,在HDFS使用双备份或者三备份的话就更大一些。
表中的部分字段会被update更新操作,如用户联系方式,产品的描述信息,订单的状态等等。
需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态。
表中的记录变化的比例和频率不是很大,比如,总共有10亿的用户,每天新增和发生变化的有200万左右,变化的比例占的很小。
对于这种表的设计,可以设计 3 种方案:
-
方案一:每天只留最新的一份,比如我们每天用datax抽取最新的一份全量数据到Hive中。
实现起来很简单,每天drop掉前一天的数据,重新抽一份最新的, 节省空间, 但是没有历史数据,先翻翻旧账只能通过其它方式,比如从流水表里面抽。
-
方案二:每天保留一份全量的切片数据。
每次全量中会保存很多不变的信息,浪费存储
-
方案三:使用拉链表