一个宽表好还是多个维表好?

本文讨论了数据模型设计中的规范化与反规范化问题,特别是在数据仓库环境中,如何平衡数据冗余与查询便利性。提出通过同时维护规范化和反规范化数据模型,或使用视图创建宽表的方法,以满足不同需求。

前言

本篇的主题是关于数据模型的规范化和反规范化的讨论,其实也是一种常见的维度建模的设计和业务使用便捷性的冲突。

Dimension Table概念多出现于数据仓库里面,维表与事实表想对应,比如一个 “销售统计表” 就是一个 事实表,而 “销售统计表” 里面统计数据的来源离不开 “商品价格表”,“商品价格表” 就是销售统计的一个维度表。事实数据和维度数据的识别必须依据具体的主题问题而定。“事实表” 用来存储事实的度量及指向各个维的外键值。维表用来保存该维的元数据

 讨论

问题:

在设计数据表的时候,是一个宽表好,还是多个维度表好?

回答一:

数据仓库每张表的搭建,主要依赖于这个表在整个数据仓库中的作用和相关意义。首先要清楚这个表的存在是为了解决那些问题,什么角色使用,怎么保证使用者尽可能好的体验解决问题。从以上所提到的角度去看待问题,拆解以下几点因素:

  1. 拆表情况下多张数据表的查询SQL的编写难度有多大,是否会出现为了数据提取需要关联多张表,并且需要提前知道各个表之间的关联关系。如果使用这个数据的人员较多,每个人都需要先了解所需要多张表的关联关系,然后才进行数据查询,这样是不是维度沟通成本较高,查询体验下降,影响使用者的工作效率?
  2. 多表关联查询的使用频次有多高,将重复高频的事情简化,是不是更好?
  3. 查询体验上需要考虑多表关联之后的查询性能问题,如果一张表的内容过度,是否影响查询速度?
  4. 多表关联的合理性,不同的数据维度和内容与订单表关联,是不是会存在违背常理的坑存在。比如,数据字段的对应关系是一对一,还是多对多,是否会让使用者忽略查询数据时候的过滤限制条件。
  5. 数据的安全问题,每张数据表的安全范围不同,合并成同一张表是面临的是更大的权限开放。比如订单表可能仅需要让一部分人员知晓订单信息,并不想让他们知道供应商信息。

回答二:

结合我司的一些经验来说说哈,我司会将数据用于各种各样不同主题和纬度的报表,也会将数据用于数据挖掘做模型的,因此数据分成肯定是必要的,针对报表类的数据根据报表的不同反向划分出不同的纬度表,这种方式其实就是将mysql业务库的数据经过sql语句之后重新生成一张或者多张维度表,在这之中根据经验会抽取出一个经常用的字段作为公共字段放入公共层数据中,一些经常需要用到的度量值也会抽取到度量表中,那么一些非开发人员来看数据的时候只要在页面上简单写几个sql语句就可以统计出数据来,比如月销量,周销量,日销量这些。

若是机器学习模型的同学要数据的话,我们就只需要从维度表,度量表,事实表中抽取数据做成大宽表给他们了,由于模型做的比较少,对于大宽表的经验比较少,暂时只能来一个模型数据的需求,单独写sql语句去抽取。

补充

这个问题,从本质上来讲。想讨论是数据模型设计里面的规范化和反规范化的问题。

从规范化的角度来讲,数据仓库的设计者是希望越规范越好,因为这样会减少数据的冗余,而且也便于模型的扩展。从反规范化的角度来讲,数据仓库的使用者是希望使用越方便越好,他们并不太关系规范不规范冗余不冗余,只要用着方便就好。

这种情况在工作中是十分常见的,那么该怎样来解决它?下面有两个思路:

  1. 两种方式都存。虽然,这样看起来会占用更多的存储空间,但不失为一种合适的解决方案,因为宽表是通过别的表拼接而成的,因此宽表的存储周期是可以短一些。
  2. 只存多个维度表,通过视图来创建宽表。这种方式适合于宽表的查询次数较少的情况。比如在Hive中,宽表其实只是为了计算出来之后导入Es等系统中供其它系统查询,那么久没必要存储一份宽表,直接通过视图来封装就可以。

另外,数据仓库的设计,往往不能是以计算出几张表就结束了,我们更应该提供的是数据服务,让使用方都通过服务的方式来访问我们的数据,而不是简单地将表暴露出去。当我们以数据服务的方式提供数据的时候,不管是易用性还是安全性都更容易得到满足。

<think> 嗯,用户这次的问题聚焦在"建立数据的需求提报方法",结合之前讨论过的数据需求模板和引用的分层设计知识,需要重点解决如何将开发需求结构化达的问题。 用户可能正在参与数据仓库建设项目,角色很可能是业务分析师或数据产品经理。从ta引用[1]对EDW-CDM分层设计的关注来看,项目应该处于数据中台搭建阶段。ta的真实需求不仅是单模板,更想掌握如何让技术团队准确理解业务意图的方法论——毕竟开发成本高,返工代价大。 注意到用户两次都提到引用[1]的分层规范,说明企业已建立数据治理体系。因此需求提报必须紧扣"生产镜像层→中间层→公共层"的加工链路,特别要强调字段溯源和转换规则。之前给的通用模板缺少CDM层特有的度和度量整合要求,这次需要强化三点: 1)字段血缘要追溯到EDW层甚至ODS源 2)明确历史拉链/快照等时态需求 3)标记度退化或冗余字段的处理逻辑 用户隐藏的痛点可能是业务部门和技术团队对""理解不一致:业务认为是万能数据集合,而技术团队关注可护性。所以模板里特意加入"关联度说明"和"数据时效要求"来设定期望值,避免后续争议。 有趣的是引用[3]提到决策树在特定数据集现稳定,这提醒我在"数据质量要求"字段强调业务规则校验——里枚举值统一性可能直接影响下游模型效果,比如用户画像标签的加工。 最后用七步法框架包装建议,既呼应引用[2]的需求分析方法,也帮助用户建立标准化提交流程。特意把"使用场景"放在第一步,是要倒逼需求方想清楚业务目标,减少无效开发。 </think> 基于数据仓库分层设计(ODS→EDW→CDM→ADM)和需求分析框架[^1][^2],建立数据的需求提报需明确目标层级(通常位于CDM层)、字段血缘、数据整合规则。以下是定制化的提报模板和方法: --- ### **数据需求提报模板(CDM层专用)** | 字段 | 说明 | 示例 | |------|------|------| | **名称** | CDM层主题命名<br>(符合企业数据规范) | `cdm_sales_fact_wide` | | **业务目标** | 解决的具体问题(需量化) | “支撑区域销售分析,减少报开发时间30%” | | **来源及层级** | 依赖的EDW/ODS层及字段<br>(需标注名+字段+加工规则) | `edw.sales_order`:<br>• `order_id` (直接引用)<br>• `discount_rate` (ODS原始值×0.85) [^1] | | **整合逻辑** | <li>度退化(如客户→省份)</li><li>度量计算(如`GMV = price*quantity`)</li><li>历史拉链/快照类型</li> | `customer.province` 退化到<br>`monthly_sales = SUM(edw.sales.amount)` | | **数据质量要求** | 完整性/一致性规则 | `province`字段NULL值<1%<br>枚举值匹配行政编码[^1] | | **关联度** | 需绑定的及关联键 | 关联`dim_product`(`product_id`)<br>关联`dim_date`(`order_date`) | | **时效性** | 更新频率与延迟要求 | T+1日凌晨2点前就绪 | | **使用场景** | 下游应用类型 | Power BI报/用户画像标签计算 | --- ### **需求提报四步法(基于五框架[^2])** 1. **定义业务价值** - 明确解决的痛点(例:”当前销售报需关联5张,查询耗时>30s”) - 量化目标:`查询性能提升至<5s`,`支持10个并发分析` 2. **拆解数据链路** ```mermaid graph LR A[ODS订单] -->|清洗异常值| B(EDW销售事实) C[ODS客户] -->|省份映射| D(EDW客户) B -->|关联product_id| E[CDM销售] D -->|关联customer_id| E ``` *需在需求中标注各节点加工规则[^1]* 3. **制定验收标准** - **功能性**:字段覆盖率100% - **非功能性**:查询响应时间$t<5s$,数据延迟$d<1h$[^2] - **数据质量**:关键字段$NULL$值率满足: $$ P_{\text{null}} = \frac{\text{NULL记录数}}{\text{总记录数}} < 0.5\% $$ 4. **标注扩展性要求** - 预留字段:`future_promotion_flag` - 分区策略:按`month`分区存储 --- ### **关键注意事项** 1. **避免EDM层冗余** - 公共层(CDM)需服务多业务场景,禁止将仅ADM层使用的指标下沉(如特定报的KPI计算)[^1] 2. **血缘追溯** - 提需求时需提供字段级血缘文档(如:`cdm_sales_wide.product_name ← edw.dim_product.product_name`) 3. **性能与成本平衡** - 字段数控制在50个以内,避免全字段`SELECT *`拖慢查询 > **案例**:某电商需求示例 > **问题**:”分析促销活动对各省份GMV的影响” > **字段**: > ```sql > activity_id, -- 来自EDW活动 > province, -- 退化自客户度 > gmv, -- SUM(price*quantity) > discount_cost -- 计算规则:CASE WHEN ... > ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值