资讯动态

数据模型三层次:从业务抽象到物理落地的实战指南

发布时间:2026/10/15 14:05:59 来源:尧图企业网站定制
1. 数据模型不是画几张表先把这个概念拆清楚我最早对数据模型的理解也很朴素以为是拿工具画几张方框连几条线把表结构摆出来就算完事。直到有一个项目让我吃足了苦头才意识到这玩意儿远不止是图。当时某业务方提需求说要销售金额看板结果交付之后市场部说金额不包含退款财务说金额要看实际到账供应链说金额要区别保税仓和非保税仓——同一个字段三拨人对它的定义完全不一样。后来我回头一看根源就是当初没有一个真正意义上被大家认可的数据模型。数据模型本质上是用一套结构化的方法对现实业务世界做抽象和描述。它不是某个工具里的一张图也不是数据库里的几个表而是把业务是什么、业务规则是什么、数据之间有什么关系这些模糊的认知翻译成精确的、可以被计算机理解和执行的规范。这个翻译过程通常分成三层概念模型、逻辑模型、物理模型。理解这三层才算真正理解数据模型。1.1 第一层概念模型业务世界的简化地图概念模型是最贴近业务、最远离技术的一层。它关心的是这个业务领域里有哪些核心对象它们之间是什么关系比如你做外卖业务核心对象肯定有用户、商家、订单、骑手商品这些用户和订单之间存在下单的关系骑手和订单之间存在配送的关系。这些对象我们叫实体对象的特征叫属性用户有手机号就是属性订单属于某个用户就是关系。概念模型的价值在于它能让业务人员和开发人员在没有技术背景的前提下也能对同一件事达成共识。画概念模型时不讨论主键、不讨论索引、不讨论存储过程只讨论我们业务上到底有哪些事、这些事怎么相互关联。很多项目一开始就跳进数据库建表最后表建得乱七八糟就是因为少了这一步——业务方脑子里想的是客户要能赊账开发听成了客户表要加个信用字段等上线后一跑业务才发现完全对不上。一个合格的概念模型应该能让一个完全不懂技术的新员工在十分钟内看懂公司的核心业务轮廓。如果做不到这一点那这模型大概率只是给技术人员自己看的没有起到沟通介质的作用。1.2 第二层逻辑模型把业务规则翻译成结构化语言逻辑模型是在概念模型的基础上进一步细化成接近数据库结构的形态但仍然不绑定具体的数据库产品。它要考虑的是每个实体应该具备哪些关键属性主键怎么选实体之间的关系如何用外键表达是否满足范式的约束如何去重、拆分或者冗余。比如概念模型里有订单和商品逻辑模型就要回答一个订单里包含多个商品这个关系怎么表达是直接存成一条记录订单ID、商品ID、数量、单价还是拆成订单主表、订单明细表这两个商品如果价格不同、折扣不同、售后规则不同拆成两个表显然更合理。逻辑模型阶段就要通过关系的基数一对一、一对多、多对多、约束规则、键设计把这些业务细节全部定下来。很多人觉得这层太理论其实恰恰相反。逻辑模型是承载业务规则最集中的地方。就拿一个客户能不能有多个账户、一个订单能不能拆成多次发货这些规则来说如果在逻辑模型阶段没有明确开发就会凭自己的理解自由发挥。等系统上线后业务说我当初不是这个意思你再想改表结构代价就非常大了。我见过一个项目就是因为逻辑模型里没有定义会员等级变更历史这个实体后来运营需要查历史等级时系统只能从日志里翻翻不出来的就永远丢了逼着团队做了一年数据回溯。1.3 第三层物理模型决定数据在磁盘上怎么待着物理模型是离技术最近的一层它决定了数据实际存储在数据库里怎么写、怎么存、怎么访问。这一层要关心的东西变成了表引擎选什么、字段类型怎么定、索引怎么建、分区怎么规划、是否做冗余、是否允许 NULL、字符集选什么、读写分离怎么设计。同样一张订单表逻辑模型里就是订单ID、用户ID、金额、时间、状态这么几个字段但到了物理模型你得决定订单ID是用 bigint 自增还是用雪花算法生成的分布式ID金额是用 decimal(10,2) 还是直接用整数分存储订单创建时间要不要按天做分区以便后续跑批量报表更快。这些决策直接影响系统的性能、扩展性和运维成本。我自己做过的某电商项目订单表从逻辑模型看特别清晰但因为物理模型设计时偷懒没给用户ID下单时间建联合索引结果到了促销季一次会员列表查询就把数据库拖垮了。后来加了索引查询时间从四秒降到了二十毫秒。物理模型看似只是实现细节实际上它的好坏直接影响用户对系统快慢的体感。一个再完美的逻辑模型如果物理模型设计不到位最终也会被性能问题打回原形。三层模型各有侧重但很多人容易陷入误区要么只画了概念模型就急着写代码要么直接用数据库客户端反推一个物理模型出来。其实数据模型的完整含义是三层模型层层递进、相互验证的一套体系。概念模型保证做对的事逻辑模型保证把事做对物理模型保证把事做好少了任何一层后面都要还债。2. 为什么非建不可没有数据模型的团队每天都在给未来还债我不止一次被问过我们的项目很小业务也简单就三张表的事还建什么数据模型浪费时间。每次听到这种话我都特别想让他看看那些年因为不建模产生过的破事。我印象最深的是一个内部管理系统最开始只有一张 Excel 落地成的表叫业务信息总表里面既有客户信息又有订单信息还有负责人的姓名和电话。当时开发图省事什么字段都往里塞用起来确实方便。但不到半年问题就集中爆发了。第一个爆发点是数据口径对不上。总表里销售额字段填的是财务确认过的金额但另一个报表里销售额填的是下单时的金额中间差了退款和优惠。两个系统的报表拉出来对不上数业务部门天天找 IT 吵架最后只能临时写脚本人工挑数据修。如果当初建了数据模型把订单金额和实收金额定义成两个不同的指标并在逻辑层面明确每个指标的统计口径根本不会有这种扯皮。第二个爆发点是数据维护变得越来越危险。总表结构要加一个字段听起来很简单但因为这个表已经被十几个上游接口引用大家都往里续字段有的写备注有的写说明实际用途千奇百怪。后来要做数据质量校验发现同一张表里有十几处格式不一致的日期有的存成字符串有的存成时间戳有的带时区有的不带——想统一得同时改十几个系统谁也不敢动。这就是典型的不建模后患系统的结构没有约束任何改动都像在拆一颗不知道哪条线连着炸弹的雷。反过来看建好数据模型的团队长期收益非常清晰。2.1 统一的业务语言让鸡同鸭讲彻底消失有了数据模型实体、属性、口径都是明确定义的。业务说订单所有人体会到的都是同一个逻辑实体技术说订单状态大家都知道这是待支付、已支付、已发货、已签收、已取消里的哪一个。我记得在某团队做过一次数据资产梳理发现客户在系统里有三种称呼CRM 里叫会员订单系统里叫买家售后系统里叫联系人。因为缺乏统一模型同一时间同一个用户三个系统里居然被打印成三种不同 ID。后来建了客户主数据模型统一为客户并分配唯一标识这个问题才彻底根治。2.2 稳定的结构让系统改造不再伤筋动骨业务不是一成不变的这周搞满减下周搞预售再下周又加会员积分。如果数据模型设计得足够合理新增一种玩法往往只需要加一个字段或一张子表而不需要把整张表结构推倒重来。我做过一个活动系统因为前期把活动、活动规则、奖品拆成了三个清晰的概念实体后期业务要叠加几十种活动类型基本只改配置表和规则表主流程代码零改动。这就是建模带来的结构红利。2.3 降低协作成本让新人半天就能上手一个 30 人以上的团队如果没有任何数据模型文档新人光搞清楚某个字段是谁定义的、哪个表跟哪个表能不能 join可能就要一周。而有了清晰的数据模型新同学拿过来花半小时看模型图就知道核心链路长什么样知道订单表跟支付表怎么关联知道哪些表是维度表、哪些是事实表。我见过某团队靠一套建模文档让一个新来的分析师在入职第三天就独立写出了业务部门要的统计报表这在没有模型的团队几乎不可能。2.4 支撑分析和决策让数据真正变成资产当公司的数据分析平台、经营看板、风控模型都建立在一个清晰的数据模型之上时跨主题的数据整合会非常高效。模型定义了统一的粒度、主键和关系后面做宽表、做指标、做数据服务都是在同一套地基上盖楼。反过来如果地基里全是乱建的字段和关系你今天整合一个主题要花三天明天换一个主题又要花三天永远处于救火状态。数据建模本质上是给数据资产打地基地基打得深楼才能盖得高。我承认小项目不建模也能跑起来付出的代价可能半年后才出现。但如果你希望你的系统能活过一年、两年或者你希望未来做数据分析时不用一次次填坑我建议还是老老实实把数据模型建起来。这真的不是流程主义而是为未来省钱的明智选择。3. 从业务到数据库一套可以照抄的建模步骤说了这么多理论接下来聊点实际的。很多人知道建模重要但不知道从哪下手。我带过的实习生常问我是不是应该先打开设计工具画几张图其实不对。建模的第一步永远不在工具里而在你的业务现场。下面这套步骤我不敢说放之四海皆准但在我参与过的十几个中大型项目里反复验证下来确实好使。3.1 第一步和业务方坐下来把名词清单盘出来建模之前先别急着画实体。你要做的是拉上业务代表请他们描述一遍完整的业务流程。比如做电商订购让运营从用户打开 App 浏览商品一直讲到订单送达用户签收之后产生售后和评价。过程中要求他们说出所有名词和动词。名词大概率会变成实体或属性动词大概率会变成关系或状态变化。我当时会用一个简单的三列清单当场记录名词业务方随口说的释义可能的归属商品就是我们要卖的东西实体商品库存每个商品有多少件属性库存数量订单用户买了东西形成一个订单实体订单收货地址用户填的用来发货实体收货地址退款不要了退钱实体退款单这一步的产出不是表格本身而是让业务方感到你在认真理解他们的世界。很多建模项目失败不是因为技术不行而是因为建模的人对业务理解太浅画出来的模型在业务眼里是个四不像。3.2 第二步识别实体分清本质属性和衍生属性把名词清单拿出来逐一判断它是否值得作为一个独立实体存在判断标准很简单——它是否有自己的生命周期和独立性。比如用户有注册、活跃、注销的周期订单有创建、支付、发货、完成的周期都值得成为实体。而收货地址虽然离不开用户但它可能被多个订单复用也有独立的维护逻辑所以也应该单独成为实体而不是塞进用户表里当一串字段。属性也要分类。所谓本质属性是这个对象天生就有的、少一个就描述不了它的特征比如用户的手机号、订单的下单时间所谓衍生属性是从别的数据计算出来的比如订单总金额是从明细行的单价乘数量累加来的累计消费金额是从订单表聚合来的。区分这两类属性的意义在于衍生属性在逻辑模型中完全可以不冗余存储通过计算获得即可如果非要存储也要有一套清晰的同步机制否则很容易出现数据不一致。3.3 第三步画概念模型确定关系尤其是多对多的关系用简单的方框和连线把实体和关系画出来。这是你手上唯一一张业务人员能看懂的图。画的时候重点确认几件事这张关系是 1 对 1、1 对多还是多对多比如一个用户可以有多个订单是 1 对多一个订单可以包含多个商品一个商品可以被多个订单包含就是多对多。多对多关系在逻辑模型里不能直接实现需要引入中间实体比如订单明细它把订单和商品的多对多拆成了两个一对多。这个阶段发现多对多关系是好事情说明业务本质已经浮出水面了。3.4 第四步转逻辑模型定主键、外键和约束概念模型确认无误后把它转成逻辑模型。这步要干的活主要是给每个实体选主键自然主键还是代理主键确定关系的外键放哪边定义字段的取值范围和各种约束。我特别想强调代理主键的问题。很多表有天然的自然主键比如身份证号、手机号、订单号。但实际建模时我更推荐用无业务含义的自增 ID 或雪花 ID 作为代理主键把自然键作为业务唯一键单独加唯一索引。为什么因为自然键可能变化比如手机号会换身份证号虽然稳定但涉及隐私不该作为到处引用的主键订单号虽然稳定但可能从外部系统导入格式无法控制。用代理主键可以让表之间的关系非常单纯不受业务规则变化影响。这个决策做过很多次基本没后悔过。3.5 第五步规范化和反规范化平衡查询效率和更新代价范式是数据建模躲不开的话题。第一范式要求字段不可再分第二范式要求非主属性完全依赖主键第三范式要求非主属性不传递依赖。规范化的好处是消除冗余保证数据的一致性坏处是查询时经常要 join 一大串表性能变差。实际项目里往往会在核心的底层模型严格按照第三范式设计保证数据干净而在面向查询和分析的模型里会有意识地做反规范化比如把客户名称冗余到订单表里减少一次 join。也可以用一个简单口诀来记写入要快就多冗余数据要准就靠规范。订单主表里放一个客户名称字段虽然违反了第三范式但只要由上游统一维护并保证同步带来的查询便利性远大于冗余风险。3.6 第六步做物理模型选类型、定索引、划分区逻辑模型定下来后交给数据库落地时要针对具体的数据库产品做优化。最常见的几个问题金额字段选什么类型我一般用 decimal不用 float。float 是近似值涉及钱的时候一旦精度漂移对账就是灾难。日期字段用什么格式强烈建议用 date / datetime 类型别用字符串。字符串排序和范围查询都会踩坑还会出现2024-3-1和2024-03-01这种格式不统一的问题。索引怎么建先把查询频率最高的 WHERE 条件列出来给高选择性字段建索引。但索引不是越多越好因为每个索引都拖慢写入。我见过一张表上建了二十个索引写入秒等读也没快多少。分区怎么规划像订单这类持续增长的大表建议按日期分区。这样既能快速清理历史分区也能让按时间范围的查询实现分区裁剪。物理模型阶段最好用版本管理工具管理建表脚本不要手动在数据库客户端里 DDL 一把梭。一套脚本走遍开发、测试、生产环境能避免很多环境差异导致的诡异问题。上面六步走完一个可落地的数据模型就完成了。你可能会觉得这么一套流程是不是太重了但相信我这套流程每一步都在逼你回答关键问题与其让这些问题在你上线之后突然冒出来不如在建模阶段就把它们全部逼出来。4. 建模路上那些真实的坑不是模型复杂而是这些细节被忽略就算你按上面的步骤走了一遍也不代表模型就一定能扛住现实考验。下面这些坑我几乎每次评审数据模型时都能遇到。每一个背后都有真实的系统故障和业务事故如果你看完能不犯同样的错就算这篇文章没白看。4.1 实体划分含糊用户和会员到底是不是同一个东西很多系统从一开始就没定义清楚这个概念边界的杀伤力。我接触过一个社区电商项目表里有用户表会员表粉丝表三张表。用户表存的是登录账号和手机号会员表存的是购买会员的用户扩展信息粉丝表存的是关注了店铺的用户。问题来了一个普通用户如果同时是会员又关注了店铺他在三张表里各有一行但三张表里的用户 ID字段体系却不一样——会员表里用的是会员中心分配的一套 ID用户表里用的是注册系统分配的 ID粉丝抓的是微信 OpenID。要统计有多少会员同时买了东西时你甚至不知道该用哪个 ID 去 join。建模时必须先确认某个名词在业务上下文里是不是唯一的实体。如果用户和会员是同一类人在不同阶段的不同属性就应该拆成用户主表和会员扩展信息表用同一个主键关联。如果实在无法统一也要在文档里明确说明两者之间的关系和映射规则。4.2 属性放错位置把值当字段把状态当历史这个坑太经典了。比如订单表里业务想做物流轨迹有人直接在订单表里加了一个物流信息字段里面塞了一长串 JSON存几十个节点。看似方便实际上你根本没法用 SQL 去查询昨天下午三点的物流节点是什么。正确做法是把物流轨迹单独做成一张物流轨迹明细表每条轨迹一行数据。JSON 字段在数据模型里当然可以有但它应该只用于存储无需分析的数据千万不要把需要参与统计和查询的数据塞进一个 JSON 里。另一个经典坑是不记录状态变更历史。很多业务要查看订单什么时候从待发货变成已发货但模型里只在订单表里更新了一个状态字段。旧状态被覆盖历史就丢了。表面上只是少一张表实际上丢失了一整类审计和分析能力。所以凡是有状态变化、且未来可能需要追溯的业务对象一定要建一张状态流转历史表。4.3 多对多关系偷懒处理直接用逗号分隔主键我见过有人设计用户收藏商品时在用户表里加了一个收藏商品 ID 列表字段用逗号分隔多个商品 ID。这样确实减少了一张表但随之而来的问题是想查某个商品被多少人收藏了必须把所有用户表扫一遍然后在应用层 split 字符串统计。数据量小的时候还能凑合一旦数据量大这查询代码就是灾难级别。多对多关系的正解永远是引入中间表中间表可以再加收藏时间来源渠道是否有效等属性。这个看似增表的动作恰恰是在为系统的未来铺路。4.4 外键约束从建模到落地为什么越来越多人选择不用纯理论的数据建模教材一定会要求定义外键约束。但我在大型高并发系统中看到越来越多的团队在物理模型里主动去掉外键约束。原因很简单外键约束会在每次插入和更新时做完整性检查严重拖慢写性能而且一旦分库分表外键根本没法跨库实现。很多团队的做法是在逻辑模型中保留外键关系和完整性规则在物理模型中通过应用层代码或定时任务来保证数据一致性。这个选择没有绝对的对错但如果你在逻辑模型阶段就没定义外键关系应用层又没做检查那数据就会变成一堆无法串联的孤儿。4.5 过度设计为不存在的需求建了八张表建模的另一个极端是设计上瘾。有人为了追求架构完美明明业务方只想要一个简单的商机跟进记录却把客户、联系人、机会、活动、跟进历史、团队分配、审批流全做成独立实体连机会来源都要拉一张字典表。结果项目工期翻了三倍业务方根本等不起。我的经验是模型面向 3 到 6 个月的业务需求设计不要为 3 年后可能不存在的业务提前建表。把核心业务对象建模深入一点把边缘性的、探索性的需求先保持简单等业务验证了再迭代不迟。4.6 命名不统一是一切混乱的起点名字这件事太重要了。我参与过的一个数据仓库项目同一个字段在不同表里叫过amount、amt、total_amount、price_total还有叫金额的后来做指标口径核对时光映射这些字段名就花了两周。更可怕的是有人为了快速区分来源给每个字段加表名前缀customer_user_id、order_user_id、pay_user_id看着是区分了实际上完全不知道哪个才是真正的用户主键。从现在开始我建议你给制定一套命名规范实体名用业务统一叫法属性名采用主题域_修饰词_指标名的格式主键统一叫xxx_id时间字段统一以_time结尾。这样哪怕不看数据字典拿到一张表也能猜个八九不离十。我自己的习惯是每个字段除了名字还要加一行注释说明它的口径和来源。这在别人看来是小事但在团队协作中能省下无数沟通成本。5. 数据模型不是一次性的从建完到用好还有三件要一直做的事很多人以为数据模型画完、表建好、系统上线这事儿就算结束了。但以我多年经验看模型上线那一刻才是它真正开始接受考验的时候。后面业务会变、数据会涨、团队会换人模型如果不跟着活很快又会变成一张没人看得懂的废纸。这里分享三个我认为最重要的事。第一建立模型变更管理流程。数据模型不是不能改是不能乱改。我见过最崩溃的场面是某个团队为了让一个字段快点上线绕过评审流程直接在生产表上删了一列结果下游所有依赖它的报表集体报错业务方一大早就炸锅。后来我们定了规矩任何模型变更先提交变更申请写明变更原因、影响范围、兼容性方案由数据负责人评审通过后再执行。看起来多了一道手续但它能够有效拦住很多我觉得可以这么改的冲动。第二画一张模型血缘图。在大型数据系统里一个字段从业务系统进入数据库经过清洗、加工、汇总最终出现在报表里中间会经历好几层加工。如果不知道这条链路出了问题根本不知道去哪个环节排查。血缘图就是用来记录这种来龙去脉的。你可以用专门的元数据工具来自动解析血缘也可以退而求其次在文档里人工维护。如果没有血缘信息将来做模型升级或字段下架时就跟闭着眼拆弹一样刺激。第三用数据质量反向校验模型质量。一个模型是否合理可以从下游数据质量指标看出来。比如主键重复率是不是经常超过 0空值率是不是异常偏高关键字段值域和字典定义是不是对不上这些异常说明建模时没有把数据的实际生产情况考虑进去。比如某表设计时把客户 ID设为非空但实际业务流程里用户能在未登录状态下下单导致大量 NULL 写入。如果把数据质量监控挂在表上这个问题上线当天就能发现而不是等到数据分析师查不出来数据才来问 DBA。另外我强烈建议每个团队都留一份数据建模规范文档和公共词汇表。前者用来约束新员工后者用来统一口径。公共词汇表最好由业务方和技术方共同维护每次新需求启动时先查词汇表确认已有定义再决定是否需要扩展。久而久之团队对数据的理解会越来越一致很多矛盾在源头就被化解了。最后再分享一个小技巧。如果你接手的是一个已经线上运行多年但一直没建模的烂摊子请不要想着一次推倒重来。先用一个综合性的业务主题切入比如订单或者客户把核心模型建出来把核心指标的采集方式稳定下来然后逐步扩展。建模是迭代式的永远不要幻想一步到位。数据模型就像一栋楼的地基你可以拆旧楼但不必把地基也全炸了更好的方式是加固它再在上面盖新楼。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑