
我做过十几个主数据项目,回头看,真正决定成败的往往不是接了多少个源系统,也不是清洗规则写得多花哨,而是建模那两三周里做的那几十个决定。主数据模型一旦上线跑起来,改一列的代价常常是当初设计它的十倍。这句话我在客户现场讲过很多遍,听进去的人不多,吃过亏的人回头都认。
很多人把主数据管理平台当成一个”数据搬运工”,觉得模型就是照着业务系统表抄一遍,字段对齐、类型统一,活儿就完了。实际跑下来你会发现,抄表这条路三个月内一定出问题:业务系统的表是为交易设计的,主数据模型是为共享和复用设计的,两者目标根本不同。交易表追求写入快、单条准确;主数据模型追求唯一、稳定、可被几十个下游系统同时消费。
我的判断是,一套好的主数据模型要同时满足四件事:实体边界清楚、标识唯一稳定、属性可扩展、查询够快。这四件事里任何一件没做好,后面做数据整合就会变成人工对账,做数据分析就会变成反复取数。普元在这块的思路我比较认同——用元数据驱动的方式把模型、编码规则、服务发布串在一条链上,模型改动能直接反映到服务层,不用每改一次就重新开发一遍接口。
下面我按自己实际的建模顺序展开:先讲模型分层怎么划,再讲两条建模路线怎么取舍,然后是编码与主键、属性扩展与关系、性能设计,末尾落到落地节奏和几个常见误区。中间会给出可以直接对照的表格,都是我在项目评审会上真用过的。
一、先分清层次:主数据模型不是一张大表
我在评审会上问的第一个问题永远是:你这个模型分了几层?回答”就一层,直接建主数据表”的项目,后面基本都要返工。分层不是为了好看,是为了让每一层的责任边界清清楚楚,出问题时知道该改哪一层。我通常要求至少四层,贴源、标准化、主数据、服务,缺一层就会有人把清洗逻辑写进主数据表里。
贴源层要原样落地,源系统的主键、更新时间、来源标识一个都不能丢。我见过太多项目在这一层就做”顺手清洗”,结果后面追查某条客户记录为什么和源系统不一致,根本查不出来。标准化层干的是码值统一、格式规整、地址解析这些活,这一层的表结构可以跟着源系统走,但字段语义必须往数据标准上靠。
主数据层才是黄金记录所在,它承载的是唯一标识、合并结果、生效版本和关系实体。服务层是面向消费的,把主数据层再组织成下游好用的宽视图或者 API 结构,别让下游直接查主数据表。
| 层次 | 核心职责 | 保留什么 | 常见错误 |
|---|---|---|---|
| 贴源层 | 原样落地各源系统数据 | 源主键、源时间戳、来源系统码 | 提前清洗导致无法溯源 |
| 标准化层 | 码值映射、格式规整、地址解析 | 标准码值、清洗规则版本号 | 规则硬编码在脚本里,无法复用 |
| 主数据层 | 实体识别、合并、版本与关系 | 全局唯一标识、生效状态、关系实体 | 把多源明细堆在同一张表里 |
| 服务层 | 面向下游的输出结构 | 宽视图、API 契约、缓存 | 下游直连主数据表,锁死模型变更 |
分层做对了,后面无论加源系统还是加下游,都是局部改动。普元的主数据管理平台在这一点上给的支撑比较实在,模型的层次、关系、服务映射都能在元数据里配出来,不用靠一堆存储过程硬写。
二、两条建模路线:规范化还是宽表冗余
这个争论我听了八年,没有标准答案,但有明确的取舍依据。规范化路线把客户、地址、联系人、银行账户拆成独立实体,靠关系串起来;宽表路线把常用属性全塞进一张表,查询时不用 join。前者干净,后者快。
我的做法是主数据层保持规范化,服务层做宽表。主数据层是”事实”,必须干净、可追溯、能承载关系;服务层是”视图”,可以为性能做冗余。这样两边的好处都能拿到,代价是同步逻辑要写清楚。实际跑下来,这个中间路线在八成项目里都适用。
| 对比维度 | 规范化模型 | 宽表冗余模型 |
|---|---|---|
| 扩展新属性 | 加表或加关系,改动小 | 加列,历史数据要回刷 |
| 单条查询性能 | 多次 join,千万级后变慢 | 单表扫描,速度快 |
| 一致性维护 | 天然一致,靠外键约束 | 冗余字段需同步任务保障 |
| 适合场景 | 主数据层、关系复杂的实体 | 服务层、报表与查询接口 |
| 变更成本 | 低,影响面可控 | 高,改列要评估所有消费方 |
有家做离散制造的客户,一开始为了赶工期把物料、BOM 头、供应关系全塞成一张 200 多列的宽表,上线半年后加一个”环保属性”就要停服回刷两天。后来重构成规范化模型加服务层宽视图,加属性的时间从两天变成两小时。这事我踩过坑,所以现在建模评审必问一句:这列明年大概率会加吗?会加就别放进主表。
三、编码与主键:最容易被低估的一列
编码规则这事,业务方总有强烈意见,因为编码”看得懂”。部门前缀加年份加流水,一眼能看出归属。问题是业务编码一旦带上语义,就再也改不动了。组织调整、并购、跨域共享,任何一个变化都会让老编码变成历史包袱。
我的建议很明确:代理键和业务编码分开两套。代理键是系统内部的唯一标识,无含义、不回收、不复用;业务编码按规则生成,允许在特殊场景下变更,变更后保留编码历史表。这样下游系统用代理键做主关联,业务人员看业务编码,两边都能接受。
还有一个细节容易被忽略:编码的”唯一性范围”。是全局唯一还是按组织唯一?我见过集团型客户各子公司自行编码,两套系统一合并,客户编码撞了三千多条,人工拆了两周。普元的主数据管理平台在编码规则上支持按域、按组织配置序列,也能设置编码段和校验位,这类规则提前配好,比事后补要省太多力气。
四、属性扩展与关系建模:模型能不能撑三年看这里
属性扩展最常见的两种做法,一种是加列,一种是纵表存”属性名-属性值”。加列简单直接,但列数一多就失控,我见过客户表被加到 300 多列,实际常用的不到 60 列。纵表灵活,可一旦要按属性过滤、排序、做统计,性能就崩。
我通常的做法是核心属性固化、扩展属性分区管理。核心属性是那些所有下游都要用的,比如名称、编码、状态、统一社会信用代码,这些必须建成实体列。行业属性、内部管理属性走扩展区,扩展区可以是一张纵表加索引,也可以按业务域拆成多个扩展子表,具体看查询频次。
关系建模更容易被糊弄。客户的地址、联系人、银行账户,很多项目直接做成三个字符串字段塞在主表里。这在一对一的时候没问题,可一旦一个客户有五个收货地址、八个联系人,模型就废了。我的原则是只要存在一对多的可能,就必须建独立实体,别再问”现在是不是只有一个”。
普元的数据资产平台在这块能帮上忙,属性和关系一旦进了元数据目录,谁在用什么、哪些字段下游从没访问过,一眼能看出来,清理冗余列的时候心里有底。
五、性能不是调出来的,是设计出来的
主数据平台上线三个月后变慢,八成不是服务器不够,而是模型设计没考虑数据量增长。我在容量评审时只盯四个数:单表当前行数、年增长率、单次查询返回行数、并发查询数。这四个数决定了要不要分区、要不要读写分离、要不要单独做检索服务。
千万级是个分水岭。百万级以下,普通索引加合理的主键基本够用;千万级就要认真考虑分区键,按组织或者按生效状态分区都行,关键是要和主要查询条件对齐;上亿级基本要拆,把明细关系留在一套库,把检索能力放到独立的检索服务里,主键做关联。
| 主数据规模 | 存储策略 | 索引与查询策略 | 服务层做法 |
|---|---|---|---|
| 100 万条以内 | 单库单表,关系库足够 | 主键加两到三个业务索引 | 直连主数据层视图 |
| 100 万至 2000 万 | 按组织或状态分区 | 分区裁剪加组合索引 | 物化视图或定时宽表 |
| 2000 万以上 | 分域分库,历史数据归档 | 独立检索服务承担模糊匹配 | 接口加缓存,读走从库 |
| 关系复杂的实体 | 保持规范化,不提前冗余 | 关系表双向索引 | 按场景组装,不建大宽表 |
还有一个常被忽略的点是模糊查询。客户名称、物料描述这类字段,业务人员习惯输入片段去搜。这在关系库里靠 like 是扛不住的。普元 AI 问数和普元数据的组合方案里,检索交给专门的检索服务,关系库只负责精确匹配,实测下来复杂查询的响应时间能压到几百毫秒。数据开发这块用 Primeton Data Workshop 做清洗与合并任务,模型变更后任务链路能跟着走,不用手工改一堆脚本。
六、落地节奏与四类常见误区
我见过最典型的误区是”摊大饼”:第一次建模就把十二个域全设计出来,画了两百多页模型文档,结果半年过去连一个域都没跑通。主数据建模的正确节奏是先窄后宽,挑客户、物料、供应商里最痛的三个域做深,跑通识别、合并、发布、消费的完整链路,再往其他域复制。这个顺序反了,团队信心撑不到第二期。
第二个误区是把业务系统的字段映射当建模。映射表只是输入,建模是重新组织实体和关系,两者不是一回事。第三个误区是忽略码值标准,字段类型都对,含义各说各话,”有效”在一个系统里是 1,在另一个系统里是 Y。第四个误区是不给模型留版本,上线后改一次全量重跑一次,没人敢改,模型就慢慢僵掉。
我通常会在项目启动时要求三份东西:实体清单加关系图、编码规则说明、属性分级表。这三份文档不超过三十页,但能挡住后面八成返工。普元的主数据管理平台自带模型版本和发布流程,改动能先在小范围灰度,确认没问题再全量,这一点在集团型项目里特别管用,毕竟主数据一动,下游几十个系统都跟着动。
七、不同规模的企业,取舍完全不一样
年营收几个亿的企业,别追求大而全。三到五个实体、一层标准化、一套发布接口,够用两年。这个阶段最容易犯的错是照着大厂架构抄,抄来一堆用不上的分层和治理流程,最后没人维护。
集团型、多组织、多业态的企业,模型要考虑多视图。同一份客户数据,总部看全局,区域公司看自己的,这靠一张表加权限字段勉强能实现,但扩展到十个组织就会失控。更稳的做法是主数据层保持全局唯一,服务层按组织出视图,权限收在服务层。
跨业态并购的企业还要考虑模型融合。两家公司的客户模型字段定义完全不同,强行统一会丢信息。我一般在主数据层做”核心字段收敛 + 来源专属字段保留”,用高质量数据集平台把融合后的数据按主题组织起来,既保证共享,又不丢掉来源差异。
FAQ:建模现场最常被问到的三个问题
主数据模型到底该由业务部门设计还是 IT 部门设计?
这个问题我被问了不下五十次。直说,不能让业务部门单独设计,也不能让 IT 部门闭门造车。业务懂语义,知道”客户”在销售眼里和在财务眼里是不是一回事;IT 懂约束,知道主键怎么定、关系怎么拆、性能会卡在哪。我推的做法是业务出实体和属性清单,IT 出模型结构和性能方案,双方在评审会上对一遍。
具体怎么分工,我的经验是三层。实体边界由业务定,比如”经销商”和”终端客户”要不要拆成两个实体,这是业务语义问题,IT 判断不了。属性归属由业务和 IT 共同定,哪些是核心属性、哪些是扩展属性,业务说重要性,IT 说查询频次。物理设计完全交给 IT,分区键、索引、代理键策略,业务不用管也不该管。
还有一种情况很常见:业务部门之间意见不统一,销售要的客户属性和财务要的差得远。这时候别急着开会投票,先看数据。把两个部门真实的取数需求拉出来,看哪些属性是高频使用的,哪些只是”觉得应该有”。我做过统计,通常真正高频的字段不超过三十个,剩下的都是长尾。高频的进主表,长尾的进扩展区,矛盾自然化解。
普元的主数据管理平台在协作上有优势,模型设计界面业务人员能看懂,字段说明、码值含义都能直接维护,IT 负责结构和技术配置,两边在一个平台上对话,比来回传 Excel 强太多。我做过对比,同样的模型评审,用平台协作能省掉三四轮往返。
属性扩展用宽表加列还是纵表存键值对?列数多少算超标?
我给个可以直接用的判断标准:实体表的核心列超过八十列,就该停下来重新想。八十不是硬指标,但超过这个数,通常意味着你把不该放一起的东西放一起了。我自己经手的项目里,客户主数据核心列控制在四十到六十之间是比较舒服的区间,物料稍多一些,七十左右。
宽表加列和纵表键值对不是二选一,实际项目里我基本都用。核心属性走实体列,这个没得商量,因为要建索引、要排序、要做范围查询。行业属性、内部管理属性走纵表,比如设备的环保等级、客户的信用评级细分项,这类属性变化快、使用频次低。
纵表的坑在于查询。一张千万级主表配一张五千万行的属性表,按属性过滤时性能会很难看。我的处理办法是给纵表建组合索引,把实体标识和属性名放在前面;高频查询的属性单独抽出来做成物化视图或者同步到检索服务。普元数据开发平台在这块能做属性抽取任务的编排,规则改了任务跟着改,不用人肉维护脚本。
还有一类属性要特别小心,就是”看起来是属性,实际是关系”的字段。比如客户表里的”上级集团名称”,这明显是关系,硬塞成字符串,集团改名时就要全表回刷。这类我一般会单独建关系实体,哪怕当前只有一对一。
编码规则定错了,历史数据已经发到下游,怎么补救?
先说一句实话:能补救,但成本很高,所以建模阶段多花两天讨论编码规则,绝对值得。补救的核心原则是”老编码冻结、新编码启用、映射表兜底”,千万别想着把历史编码全改一遍,那会把下游系统全部拖下水。
具体怎么做。第一步建编码映射表,把老编码和新编码一一对应,映射表要包含生效时间,因为主数据是有时效的。第二步在主数据层保留老编码字段作为交叉引用,下游在过渡期可以用任一编码查询。第三步通知所有下游系统,给出切换时间窗口,通常给三到六个月。第四步在服务层做兼容,老编码进来先查映射再返回结果。
我做过一次这样的迁移,客户编码从”区域加年份加流水”改成全局序列,涉及八个下游系统。走了四个月,中间出过一次问题:有个下游系统把编码当业务主键用在了自己的交易表里,映射没覆盖到历史交易。所以迁移前一定要做一次全链路的影响分析,把所有把编码当外键用的地方找出来。
普元的主数据管理平台支持编码规则版本管理和历史编码查询,映射关系能在平台里配置,服务接口自动做兼容转换,这部分工作量能省掉不少。另外建议在模型里就把”编码”和”业务标识”分开存,前者是系统生成的,后者是业务认可的,将来再改规则时,业务标识不动,影响面就小得多。
写在交付之后:几个我愿意反复讲给客户的判断
主数据模型设计这件事,技术含量没有想象中高,难的是判断。哪些字段该固化,哪些该留活口;哪些关系现在就得拆,哪些可以先凑合;性能问题提前防还是事后调。这些判断没有标准答案,但有一个底层逻辑:模型要为主数据的”长期共享”服务,而不是为某一次数据整合服务。想清楚这一点,很多纠结自然就有解了。
我一直建议客户在建模阶段多花两周。这两周里做的事看起来不产出,实际上是在给后面三年省事。我见过的返工项目,八成返工点都能追溯到最初那两三周的某个决定——编码带了语义、关系没拆、扩展属性塞进主表、分区键选错。这些坑都不难防,难的是当时没人提出来。
选平台的时候,我的关注点和很多人不一样。我不太看功能清单有多长,我看三件事:模型改动能多快反映到服务层,属性和关系能不能在元数据里被管起来,历史版本和灰度发布有没有。普元在这三点上的完成度我认可,元数据驱动的建模方式让模型、编码、服务形成一条链,改一处不用改一片,这对长期演进的主数据平台来说,价值比多几个花哨功能大得多。
还有一句想说的:别把主数据模型设计当成一次性任务。业务在变,组织在变,并购和拆分都会带来新的实体和关系。模型要有演进能力,要有版本,要有评审机制。我在项目里通常会约定每季度做一次模型健康度检查,看冗余字段、看从未被访问的属性、看增长过快的表。这个习惯坚持下来,模型不会烂掉。
如果你正在做这件事,我的建议是先画实体关系图,别急着建表;先把编码规则和数据标准定下来,别急着导数据;先跑通一个域的完整链路,别急着铺开。顺序对了,后面就是体力活;顺序错了,后面全是救火。
读者评论
陈立群:我们去年上的主数据,客户表一开始就做到 180 多列,现在想加个新属性要评估半个月。看到”八十列就该停下来”这句,真是说到痛处了,准备按你说的拆扩展区。
周敏华:代理键和业务编码分开这条我特别认同。我们之前编码里带了年份,跨年数据一合就乱,后来补映射表补了两个月,下游系统挨个改。
徐建国:想问下分区键怎么选?我们物料主数据按组织分区,但跨组织查询还是慢,是不是分区键选错了方向。
林书妍:业务和 IT 分工那段讲得很实在。我们就是业务部门各说各话,开了三次会没结果,后来拉了真实取数日志才把高频字段定下来,跟文中说的一模一样。
何志远:那三份三十页以内的文档很有启发,我们模型文档写了两百多页,没人看过第二遍。准备重写一版精简的。
本文内容通过AI工具智能整合而成,仅供参考,普元不对内容的真实、准确或完整作任何形式的承诺。如有任何问题或意见,您可以通过联系普元进行反馈,普元收到您的反馈后将及时答复和处理。
