|
很多人刚接触数据建模时,最容易被各种“层”绕晕。
-
-
-
真正进入项目以后,还会听到客户主题域、交易主题域、供应链主题域。
于是很容易把它们理解成一套从上到下的层级。
其实不是。
真正需要先分清的是两条线:
主题域、概念模型、逻辑模型、物理模型,解决的是“业务怎样逐步翻译成数据结构”;
ODS、DWD、DWS、ADS,解决的是“数据进入数仓以后怎样逐层加工”。
前者是建模抽象层次,后者是数据加工层次。
把这两条线分开,很多建模问题才真正开始变清楚。
在正式展开之前,我整理了一套《数据仓库建设解决方案》,里面涉及数仓架构、数据集成、数据治理、指标体系以及数据标准等实际建设问题。
如果正在搭数仓、梳理模型或者准备重构现有数据体系,可以结合文章一起看。
需要自取:https://s.fanruan.com/xwgup
很多项目所谓的“建模”,第一步就是把ERP、CRM里的表全部盘出来,再按照来源系统分目录。
ERP一组,CRM一组,WMS一组。
这其实还不是主题建模。
源系统告诉你数据来自哪里,主题域回答的是这些数据在业务上属于什么。
例如一家零售企业可能存在:
这里最重要的不是名称,而是边界怎么划。
销售部、财务部、运营部分别建立主题,看起来清楚,实际很容易制造新的数据孤岛。
因为“订单”并不只属于销售。
销售关心订单金额,运营关心履约,供应链关心发货,财务关心收入确认。
如果每个部门都重新定义一遍订单,最终往往会出现:
销售订单数、运营订单数、财务订单数三个数字。
主题域应该尽量围绕稳定的业务对象和业务过程建立,而不是照搬组织架构。
第一是核心对象。
客户主题围绕客户,商品主题围绕商品,交易主题围绕订单与交易。
第二是业务事件。
下单、支付、退款、发货、入库,本质上都是业务发生过的事件。
第三是主题之间的依赖关系。
订单可以关联客户、商品、门店,但客户和商品不应该因为出现在订单里,就全部塞进交易主题。
所以主题划分的本质,是寻找:
哪些东西应该在一起维护,哪些东西应该通过标准关系连接。
真正实施时还会遇到一个现实问题:主题域是按照业务划的,而底层数据往往按照系统散着放。客户在CRM,订单在ERP,库存又在WMS。
这种情况下,通常会先利用 FineDataLink 5.0 把数据库、接口、文件等不同来源的数据汇入统一的数据环境,再按照客户、交易、库存等主题重新组织。
这样后面讨论的就不再是“ERP里有哪些表”,而是“完成交易主题需要哪些数据”。
二、概念模型:先搞清楚业务里有什么,不急着考虑数据库
主题域确定以后,第二步是建立概念模型。
概念模型回答的是:
这个业务领域里,有哪些关键对象,它们之间是什么关系?
以交易主题为例,可以先识别:
客户、订单、订单明细、商品、支付、优惠、退款。
然后定义关系:
注意,这一阶段一般还不需要纠结:
因为概念模型首先解决的是业务认知统一。
这一步看似简单,实际上非常重要。
例如:
-
-
-
企业客户如果存在多个联系人,是一个客户还是多个客户?
-
如果这些问题没有先统一,后面再精细的数据库设计,也只是把业务分歧固化了下来。
所以好的概念模型,重点不是画得多漂亮,而是把三个东西讲清楚:
业务实体是什么、业务事件是什么、实体之间是什么关系。
它本质上是一张企业的业务对象地图。
到了逻辑模型,建模开始从业务语言进入数据语言。
这一步需要回答:
这些业务对象,怎样组织成可计算的数据结构?
其中最重要的不是字段,而是粒度。
例如销售事实表:
如果定义为:
一行=一张订单
那么它可以直接分析订单数、订单金额、客单价。
但如果要回答:
订单级粒度就不够。
此时更合理的粒度可能是:
一行=一条订单商品明细。
这就是为什么建模时必须先定粒度。
因为粒度一旦混乱,指标就很容易被重复计算。
一张表里既有订单级金额,又有商品明细级数量,一张订单有5条明细,那么订单金额很可能被重复5次。
事实描述的是发生了什么。
例如:
销售金额、购买数量、支付金额、退款金额。
维度描述的是:
这件事是在什么条件下发生的。
例如:
客户、商品、地区、渠道、日期、门店。
因此一个订单明细事实可能最终形成:
时间 × 客户 × 商品 × 门店 × 渠道 → 数量、金额、成本。
这才是分析模型真正的骨架。
现实世界并不是静态的。
客户今天属于华东区,下个月调整到华南区;
商品今天属于A品类,半年以后重新分类;
门店可能更换所属区域。
此时必须决定:
分析历史订单时,是按照当时的归属,还是按照现在的归属?
这就是逻辑模型里经常遇到的缓慢变化维问题。
因此一个完整的逻辑模型,至少应该明确:
业务粒度、事实、维度、主键、关联关系、历史变化以及指标来源。
到了这里,模型已经开始真正进入数据加工阶段。
例如原始订单进入数仓以后,需要先清洗状态、统一客户编码,再关联商品和组织维度,最终生成订单明细事实。
使用 FineDataLink 5.0 时,这类逻辑可以落成ETL或ELT数据开发任务:
来源表负责提供原始数据,加工节点承接清洗、关联、转换和汇总,再把结果写入目标模型。
所以这里最重要的一点是:工具负责执行模型,不能替代模型本身。
如果粒度没有定义清楚,再完整的数据加工流程,也只是稳定地产出错误数据。
四、物理模型:不是“建表”,而是决定模型怎样跑得动
逻辑模型设计完成后,还要继续落到具体数据库中。
这一步才是物理模型。
例如逻辑模型中已经确定:
销售订单明细事实表,一行代表一个订单中的一个商品明细。
进入物理模型以后,需要继续确定:
-
-
-
-
-
-
-
-
-
数据落MySQL、Doris还是ClickHouse。
因此,同一个逻辑模型,在不同数据库中可能会形成完全不同的物理结构。
这也是为什么:
逻辑模型应该尽量保持业务稳定,物理模型则需要适应技术环境。
如果更换一次数据库,连客户、订单、商品之间的关系都需要重新定义,那之前设计的其实并不是真正独立的逻辑模型。
物理模型还有一个经常被忽略的问题:
表建出来,不代表模型已经能够稳定生产。
真正上线以后,还需要处理:
因此落地阶段通常还要把模型、数据任务和调度依赖放在一起看。
在这类场景里,FineDataLink 5.0承接的重点就从“模型设计”转到了“模型运行”:
定时数据开发负责批量加工,实时数据开发可以持续处理变化数据,再根据上下游依赖组织任务运行。
对于需要实时落库的链路,也能够通过实时任务把处理后的数据写入目标数据库。
物理模型真正完成的标志,不是CREATE TABLE成功,而是这张表能够按照业务需要持续、稳定地产出数据。
五、概念、逻辑、物理模型,与ODS/DWD/DWS到底是什么关系?
这是整个数据建模里最容易混淆的问题。
可以直接记住:
概念、逻辑、物理,是模型抽象层次;
ODS、DWD、DWS、ADS,是数据加工层次。
两者不是上下级关系。
举个完整例子。
业务上发生了一件事:
客户购买商品。
在概念模型里,我们识别出:
客户、订单、商品。
到了逻辑模型:
可能设计客户维、商品维、订单明细事实。
到了物理模型:
进一步确定实际表名、字段类型、分区方式和存储引擎。
而同样这批数据进入数仓以后,还会经历:
-
-
DWD:完成清洗、去重、编码统一,形成标准订单明细事实;
-
-
ADS:针对销售分析、经营看板等场景形成应用数据。
所以逻辑模型并不等于DWD,物理模型也不等于ODS。
更准确的理解是:
一个模型可能贯穿多个数仓层,而每个数仓层又会存在自己的物理表。
项目做大以后,真正麻烦的往往也不是建一张表,而是这些层之间形成成百上千条依赖:
这时候,仅靠表名和开发人员记忆已经很难维护。
在 FineDataLink 5.0 中,数据开发任务与库表之间形成的关系还可以继续用于数据血缘分析,向上追来源、向下看影响范围。
这样模型管理就不只是知道“现在有哪些表”,还能够知道“这张表为什么存在,以及改动以后会影响谁”。
如果企业从零开始建模,可以按照下面的顺序推进。
先回答企业到底发生了什么:
获客、下单、支付、采购、生产、发货、回款。
不要从数据库表开始理解业务。
根据稳定的业务对象和业务过程,确定客户、商品、交易、库存等主题及边界。
确认核心实体、业务事件和实体之间的关系。
这一步主要解决:
大家说的是不是同一个东西。
确定:
粒度 → 事实 → 维度 → 主键 → 历史变化 → 指标来源。
其中一定要先定粒度,再讨论字段。
根据数据库和实际数据规模设计:
字段类型、分区、索引、排序、更新方式和存储策略。
通过ODS、DWD、DWS、ADS等层次组织数据采集、清洗、整合、汇总和应用。
最后还要做一次反向验证。
随便拿一个经营指标,例如“销售收入”,尝试往回追:
销售收入 → ADS指标 → DWS汇总 → DWD订单事实 → ODS订单 → ERP源字段。
如果整条链路能够解释清楚,说明模型真正形成了体系。
如果追到中间只能得到一句:
“这张表以前的人建的,不知道怎么算的。”
那企业拥有的只是很多数据表,还不能算真正拥有了一套数据模型。
数据建模真正难的,从来不是背下几个术语。
而是完成一连串翻译:
把企业拆成主题,把业务识别成对象,把对象转成数据关系,再把数据关系落成能够持续运行的物理结构。
ODS、DWD、DWS、ADS再负责让数据按照不同加工阶段逐步流动。
所以评价一个模型设计得好不好,最终不应该只看:
表建得规不规范。
而应该继续问三个问题:
-
-
-
一旦数据或者模型发生变化,能不能快速知道影响在哪里?
做到这三点,数据建模才真正从“画模型图”,变成了企业长期能够复用的数据基础设施。 |