宽表的思考

本文探讨了宽表在CRM系统中的应用,详细分析了其带来的一览全貌、查询速度提升等优点,同时也揭示了在ETL过程中遇到的脚本维护困难和字段增删复杂等问题。文章提出了一套宽表使用原则,旨在帮助开发者优雅地利用宽表,并提供了在不同场景下选择宽表或窄表的指导。


一 宽表的优点

1.      宽表浅意上的好处

在当前这个项目中,大量使用了宽表,字段超过一百五十个字段的宽表有五张,分别是客户机构级信息表、客户客户经理级信息表、客户经理信息表、集团客户信息表、战略客户信息表。

从上面的表名中可以猜到,这是个CRM项目,我这里能列举出来的优点也是在项目中体现出来的优点。

大量使用宽表究竟给我们带来了什么好处?


  •  窥一表知全貌
  •  查询速度快(此处我一直保留疑问)


窥一表知全貌:这个好处很明显,尤其是收到报表开发人员的欢迎,他们不关心数据如何存储,只关心这张报表是不是很方便,很快的能开发出来。还有一个就是数据分析人员,银行业大部分数据分析人员很讨厌做表关联,他们喜欢一条记录看到客户的全貌。

查询速度快:大多数情况确实如此,大部分SQL慢都是由于表关联造成的,所以大家都在思考不关联出结果。于是,出现了将一些常用的信息都做成了大宽表,此处让我这种范式强迫症患者很是头疼……

二 宽表的不便

从一个ETL人员角度讲,使用宽表带给我的痛苦远远大于它带给我的快乐,此处描述一下我们目前面对的系统,从系统出发解释宽表带来的问题。

项目是一个CRM系统,以仓库数据(TD)为基础,进行建模、数据加工,作为仓库的一个集市落地后,在将这部分数据,同步到查询服务器(DB2)上,每日从TD到DB2的数据量约为16G,同步数据的方式为TD导出数据生成txt,上传到FTP服务器后在通过SHELL加载到DB2。

了解了项目的背景,就可以列举出在使用宽表时有如下不便

  •  脚本过长,不易维护
  • 字段的增删过于复杂



因为要在两个系统中同步两张表一份数据,增删字段时一定要考虑一致性,同时要考虑历史数据如何处理。每次都需要经过如下步骤:

1.        修改TD表结构

2.        修改TD脚本

3.        修改导出数据脚本

4.        修改DB2表结构

5.        修改DB2加载数据的Shell脚本

每次变动都伴随这大量的工作,同时还需要因为这个字段加载新的历史数据或更新这个字段的内容,此处在项目后期维护中带来了很大的工作量。

三 如何优雅的使用宽表

宽表在仓库的汇总层大量使用,如客户、存款、贷款等通用的实体都被设计为宽表。这些宽表会面临我上面提到的问题吗?

显然不会,仓库的表很少因为个人需求而增减字段,同时仓库大多只负责原始数据的存储,不会涉及到太复杂的字段加工逻辑,故大多数汇总层的表都被设计为宽表。

要想优雅的使用宽表,我认为需要注意以下这一点:

字段是否会频繁增减

对于不涉及到事务的表且字段不会频繁增加,建议设计为宽表,尤其对于BI系统。

当然,这只是一个最简单粗暴的原则,真正做的时候,你要考虑对于不同的数据库产品,宽表中很多字段是否为空等。

针对不用的场景做不同的选择,这句话,听起来很虚,其实很实。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/24816552/viewspace-1735638/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/24816552/viewspace-1735638/

<think>嗯,用户现在想了解预聚合和聚合的定义及作用,特别是在数据库设计中的运用。我要先回顾之前的对话,确保回答的一致性。之前我详细讲解了数据库设计思路、范式以及反范式策略,其中提到了预聚合作为反范式的一种应用场景,比如在数据报生成时用预聚合替代实时计算。用户现在可能希望更深入理解这两个概念的区别和具体应用。 首先,我要明确预聚合和聚合是否是不同的术语,或者是否有细微差别。根据用户提供的引用,特别是引用[2]和[4],Apache Doris的聚合模型和更新模型可能相关。引用[2]提到聚合模型使用预计算的聚合函数来提升查询性能,而引用[4]讨论了Duplicate模型适合没有聚合求的场景,但预聚合可能属于聚合模型的应用。此外,引用[5]提到分层设计数据仓库,预聚合可能在数据仓库的中间层出现,比如汇总层。 用户的问题可能希望区分预聚合和普通聚合,但根据行业术语,这两个可能指同一概念,即提前计算并存储聚合结果的数据。不过要确认是否有不同定义。例如,预聚合可能强调在数据写入时进行聚合,而聚合可能更通用。要结合引用中的内容,如引用[2]中的指标列使用聚合函数,在创建时定义,这可能对应预聚合的结构。 另外,用户之前的问题涉及反范式设计,预聚合作为冗余数据提升查询效率的例子。在回答中要说明预聚合如何通过提前计算SUM、COUNT等指标,减少查询时的计算量,适用于OLAP或数据仓库场景,比如报或大数据分析,而OLTP可能不适合,因为写入频繁会导致维护成本高。 要注意引用中的内容,比如引用[4]提到Duplicate模型适合任意维度的查询,但预聚合可能受限于预定义的维度,这要在优缺中对比。同时,引用[5]的分层架构可能涉及预聚合在中间层的使用,如DWD、DWS层的设计。 要确保回答结构清晰,定义明确,作用分说明,并结合实际案例,比如电商销售报,帮助用户理解。此外,用户可能想知道何时使用预聚合,设计时的注意事项,比如数据一致性、更新策略等,这些也要涵盖。 最后,生成的相关问题要引导用户深入思考,比如与应用场景、设计挑战、与其他模型的比较,以及如何选择的问题。要参考之前的回答风格,保持问题相关且有递进性。</think>#### 预聚合与聚合详解 --- ### **一、核心定义** 1. **预聚合(Pre-Aggregated Wide Table)** 在数据写入阶段**预先计算聚合结果**(如SUM、COUNT、AVG等),将计算结果直接存储为字段的结构。 **数学达**: $$ T_{\text{pre-aggr}} = \bigcup_{i=1}^n \left( \text{group\_by}(D_i), \sum_{k \in K} f_k(D_i) \right) $$ 其中$D_i$为原始数据,$K$为聚合维度,$f_k$为聚合函数[^2][^5]。 2. **聚合(Aggregated Wide Table)** 广义上与预聚合同义,但更强调**多维度的聚合结果集成**,通常包含多个层级或维度的预计算指标。 --- ### **二、核心作用对比** | **场景** | **预聚合** | **聚合** | |-----------------------|---------------------------------------------|-------------------------------------------| | **数据时效性** | 牺牲实时性,适合T+1分析场景[^5] | 可支持近实时更新(如分钟级延迟)[^4] | | **存储成本** | 存储空间增长显著(冗余聚合结果) | 与预聚合类似,但可能包含更多维度组合 | | **查询性能** | 避免实时JOIN和聚合计算,响应时间降低50%-90%[^2] | 通过多版本聚合优化复杂查询(如Apache Doris的聚合模型[^4]) | | **灵活性** | 维度固定,无法动态调整聚合逻辑 | 支持按扩展聚合维度(重新预计算) | --- ### **三、典型设计模式** #### **1. 预聚合实现流程** ```sql -- 示例:电商场景日销量 CREATE TABLE sales_wide ( date DATE, product_id INT, total_sales DECIMAL(10,2), -- 预计算的日销量总和 avg_price DECIMAL(10,2), -- 预计算的平均单价 PRIMARY KEY (date, product_id) ); -- 通过ETL任务每日更新 INSERT INTO sales_wide SELECT order_date, product_id, SUM(quantity * price) AS total_sales, AVG(price) AS avg_price FROM raw_orders GROUP BY order_date, product_id; ``` #### **2. 关键设计原则** - **维度裁剪**:仅保留高频查询维度(如时间、商品类目)[^5] - **存储优化**:列式存储 + 压缩算法(如ZSTD)降低存储开销[^4] - **一致性保障**:通过事务日志或版本控制实现增量更新[^2] --- ### **四、适用场景分析** 1. **推荐使用** - 数据报系统(如BI工具的固定维度看板) - 实时性要求低的OLAP分析(如历史趋势分析) - 高频复杂查询(如跨多的统计计算) 2. **不推荐使用** - 要实时写入的事务系统(如银行核心交易库) - 维度组合动态变化的探索式分析(配合OLAP引擎[^4]) --- ### **五、性能优化实践** 1. **分层设计**(参考数据仓库分层架构) ```mermaid graph TD A[原始数据层DWD] --> B[轻度汇总层DWS] B --> C[预聚合层ADS] ``` 2. **混合存储策略** - 热数据:SSD存储 + 内存缓存(如Redis) - 冷数据:HDD存储 + 列存压缩(如Parquet格式[^4]) 3. **查询加速技术** ```python # 伪代码:利用预聚合优化查询 def query_sales(start_date, end_date): if is_pre_aggregated(start_date, end_date): return read_from_wide_table() # 命中预聚合,响应时间<100ms else: return compute_from_raw_data() # 实时计算,响应时间>2s ``` --- ### **六、与其他模型的对比** | **模型类型** | **查询性能** | **存储效率** | **适用场景** | |--------------------|-------------|-------------|-------------------------| | 范式化模型 | 低(JOIN) | 高 | OLTP事务处理 | | 预聚合 | 极高 | 低 | 固定维度OLAP分析 | | Duplicate模型[^4] | 高 | 中 | 任意维度Ad-hoc查询 | | 聚合模型[^2] | 高 | 中 | 带预计算指标的统计分析 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值