在数据仓库设计中,“宽表”和“窄表”(数表)是两种常见的设计方式,每种方式在不同场景下有不同的优缺点和适用场景。以下是详细解析,以及针对你需求的推荐方案:
宽表和窄表的概念
-
宽表(横表)
- 将多种指标和维度都存储在一张表里,字段很多,行数相对较少。
- 特点:
- 每条记录包含所有维度和指标,减少了查询时的关联操作。
- 存储冗余较高,占用更多存储空间。
- 适用场景:
- 查询性能要求高,主要以读取为主。
- OLAP(在线分析处理)场景,用于直接展示和分析(如报表或看板)。
- 不常变更的历史性数据汇总。
示例:
日期 | 订单ID | 门店ID | 品牌ID | 支付金额 | 优惠金额 | 退款金额 | ... 2024-12-19 | 12345 | 1001 | 2001 | 100.0 | 20.0 | 5.0 | ... 2024-12-19 | 12346 | 1002 | 2002 | 150.0 | 30.0 | 0.0 | ...
-
窄表(竖表/数表)
- 将数据以“指标类型”为行的方式存储,每种类型单独成行,字段较少但行数较多。
- 特点:
- 更灵活,便于扩展(新增指标时不需要修改表结构)。
- 存储效率较高,但查询时需要多次聚合或关联。
- 适用场景:
- 数据采集或存储层,用于灵活扩展和高效存储。
- 需要动态增加指标、类型较多的场景。
- 适合 OLTP(在线事务处理)场景。
示例:
日期 | 订单ID | 门店ID | 品牌ID | 指标类型 | 指标值 2024-12-19 | 12345 | 1001 | 2001 | 支付金额 | 100.0 2024-12-19 | 12345 | 1001 | 2001 | 优惠金额 | 20.0 2024-12-19 | 12345 | 1001 | 2001 | 退款金额 | 5.0
需求分析
需要按 日期、订单、门店、品牌维度,清理出 支付单、优惠单、退款单,并生成 小时级的支付、退款、优惠和应收表。以下是推荐方案的详细分析:
需求特点:
- 维度固定:
- 日期、订单、门店、品牌。
- 指标种类有限:
- 支付金额、优惠金额、退款金额、应收金额等。
- 查询粒度较高:
- 按小时级别,针对固定维度和指标进行查询分析。
- 聚合频繁:
- 需要快速生成报表或看板,查询性能要求较高。
推荐使用宽表
理由:
- 查询性能更优:
- 宽表中指标是直接列存储,不需要在查询时进行多表关联或动态聚合。
- 聚合查询(如小时级汇总)速度快,适合报表或实时看板场景。
- 数据量相对可控:
- 维度(日期、订单、门店、品牌)和指标(支付金额、优惠金额、退款金额)相对固定,宽表不会显著增加存储成本。
- 适合业务逻辑清晰的场景:
- 你的指标和维度是清晰且固定的,不需要灵活扩展额外指标。
- 报表设计的最佳实践:
- 宽表是一种典型的 OLAP 模式,减少了查询时复杂的运算和关联。
宽表设计示例:
日期 | 小时 | 订单ID | 门店ID | 品牌ID | 支付金额 | 优惠金额 | 退款金额 | 应收金额
2024-12-19 | 10:00 | 12345 | 1001 | 2001 | 100.0 | 20.0 | 5.0 | 75.0
2024-12-19 | 11:00 | 12346 | 1002 | 2002 | 150.0 | 30.0 | 0.0 | 120.0
何时使用窄表?
窄表适用于以下场景:
- 指标种类动态增加:
- 如果未来可能频繁增加新的指标(如其他金额类型)。
- 需要存储更大数据量:
- 如果需要支持的维度或数据量特别大,窄表存储效率更高。
窄表示例:
日期 | 小时 | 订单ID | 门店ID | 品牌ID | 指标类型 | 指标值
2024-12-19 | 10:00 | 12345 | 1001 | 2001 | 支付金额 | 100.0
2024-12-19 | 10:00 | 12345 | 1001 | 2001 | 优惠金额 | 20.0
2024-12-19 | 10:00 | 12345 | 1001 | 2001 | 退款金额 | 5.0
2024-12-19 | 11:00 | 12346 | 1002 | 2002 | 支付金额 | 150.0
实现建议
- 选择宽表实现:
- 创建一张宽表,每小时对支付单、优惠单、退款单的数据进行 ETL 清理,汇总后存储。
- 定期清理历史数据,避免宽表过大。
- 保留窄表原始数据(可选):
- 如果后续需求可能变更,可保留窄表作为存储层,用于生成宽表时的补充数据源。
总结
- 推荐使用宽表:满足当前高性能分析和固定维度的需求。
- 宽表优点:查询效率高、结构清晰,适合固定维度的报表生成。
- 窄表适用场景:需要灵活扩展的场景,但查询性能相对较低。