业务建表选型

在数据仓库中,拉链表流水表全量表增量表切片表 是常见的几种表类型,它们的设计和使用旨在满足不同的数据存储和分析需求


1. 拉链表

拉链表用于记录数据的全量历史变化,通过记录每一条数据的有效时间段来实现版本管理(有点类似 mysql 中的 mvcc 机制?)

结构特点

  • 包含一个有效开始时间(start_date)和结束时间(end_date)字段。
  • 当前有效的数据通常将 end_date 设为 9999-12-31(标记为当前数据)。
  • 每次更新数据时,关闭旧版本(设置 end_date 为新版本的 start_date -1),并插入新的数据。

datawarehouse-table01

适用场景

  • 需要查询数据的历史变化过程,如跟踪客户信息变更、产品价格调整等。
  • 数据量不大但变更频率较高的场景。

优点:

  • 方便追溯历史,能够完整记录数据的变化过程。
  • 能很好地支持时间维度的分析。

缺点: 维护较复杂,查询性能可能会随着数据增长而下降。


2. 流水表

流水表记录的是数据发生的事件或者交易,每一条记录表示一个事件或一次操作,通常是逐条追加的。 一天的数据中,会存放一个用户的每条修改记录,但是在拉链表中只有一条记录

结构特点

  • 通常是日志型的数据表,没有更新或删除操作。
  • 每条记录表示一次事件,如订单交易记录、账户变动记录等。
  • 包含时间戳字段(timestamp)或其他序列化字段。

适用场景

  • 业务操作的细粒度记录,如订单交易流水、用户行为日志。
  • 数据统计、报表生成的原始数据来源。

优点:

  • 记录精细,数据完全可追溯。
  • 数据写入简单(追加操作),易于维护。

缺点:

  • 数据量容易快速膨胀。
  • 不适合直接用于复杂查询和聚合分析。

3. 全量表

全量表存储的是某一时刻数据的完整快照,每次导入都替换所有数据。

结构特点

  • 表中包含业务系统中某实体的完整数据,每次加载是覆盖式更新。
  • 表的设计通常直接对应业务系统的结构。

适用场景

  • 不需要保存历史数据,关注的是最新状态的业务场景。
  • 数据量适中,更新频率不高的场景。

优点:

  • 设计简单,查询效率高。
  • 适合小型系统或对历史无特殊要求的场景。

缺点:

  • 无法记录数据历史变化。
  • 数据量较大时,每次全量更新可能会带来性能压力。

4. 增量表

增量表仅记录自上次加载以来新增或变更的数据。

结构特点

  • 包含新增数据和变更数据(有时也包括删除标记)。
  • 通常需要借助时间戳(update_time)或标识字段来确定增量范围。

适用场景

  • 数据更新频繁且增量占比低的场景。
  • 分布式系统中跨节点同步数据。

优点:

  • 减少数据同步量,提高数据更新效率。
  • 易于集成到流式处理或增量加载的场景。

缺点:

  • 需要与全量表结合才能查询完整数据。
  • 处理不当容易导致数据不一致。

5. 切片表

切片表通过时间、区域、类别等字段将数据分片存储。

结构特点

  • 表按照某一维度(如日期、地区)分区存储。
  • 每个分区存储的数据独立,分区字段可以是物理分区(存储层)或逻辑分区(查询优化层)。

适用场景

  • 数据量极大且可以按照某一维度划分的场景。
  • 查询需求主要集中于某些分区,如按日期查询最近一个月数据。

优点:

  • 提高查询效率,避免全表扫描。
  • 易于数据归档和生命周期管理。

缺点:

  • 分区维度的设计需要与业务高度相关。
  • 可能导致部分分区热点问题。

总结对比

表类型 是否记录历史 更新方式 数据量管理 应用场景 优点 缺点
拉链表 记录历史 更新闭合旧记录 较小 数据追溯,时间维度分析 能完整记录历史变化,支持时间维度分析 查询性能随数据增长下降,维护复杂
流水表 记录详细事件 追加为主 较大 日志分析,事件流统计 数据精细可追溯,写入简单 数据量增长快,不适合复杂查询和聚合分析
全量表 不记录历史 覆盖更新 中等或较大 只需关注最新状态的场景 查询效率高,设计简单 无法记录历史变化,全量更新对大表性能有压力
增量表 部分历史 追加增量 较小 高频变更,节省数据传输 减少同步量,提高更新效率 查询完整数据需要结合全量表,可能导致数据不一致
切片表 不同分区可控 分区更新 超大 数据分区存储,分段查询 提高查询效率,便于归档和生命周期管理 分区设计需与业务相关,可能出现分区热点问题

场景分析

一张用户表,大约10亿条记录,50个字段,这种表,即使使用ORC压缩,单张表的存储也会超过100G,在HDFS使用双备份或者三备份的话就更大一些。

表中的部分字段会被update更新操作,如用户联系方式,产品的描述信息,订单的状态等等。

需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态。

表中的记录变化的比例和频率不是很大,比如,总共有10亿的用户,每天新增和发生变化的有200万左右,变化的比例占的很小。

对于这种表的设计,可以设计 3 种方案:

  1. 方案一:每天只留最新的一份,比如我们每天用datax抽取最新的一份全量数据到Hive中。

    实现起来很简单,每天drop掉前一天的数据,重新抽一份最新的, 节省空间, 但是没有历史数据,先翻翻旧账只能通过其它方式,比如从流水表里面抽。

  2. 方案二:每天保留一份全量的切片数据。

    每次全量中会保存很多不变的信息,浪费存储

  3. 方案三:使用拉链表