在数据库系统实践的半个多世纪里,“建模”(modeling)一词的含义已演变出截然不同的内涵。本开篇章节旨在为全书定下基调:揭开建模的神秘面纱,并介绍其应用、方法论与收益。贯穿本书,建模这一概念将逐步展开为一套帮助组织设计与管理数据——更重要的是帮助组织理解自身——的方法与术语。
从最宽泛的角度看,建模是一种有选择的简化,用以帮助我们驾驭或设计更复杂的事物。任何系统都可以被拆分为更小、更易管理的部分。单独操控其中任一部分也许并不难,但如果缺乏整体策略,这种做法往往会在规模化与后续维护上埋下隐患。
虽然建模通常被视为与具体数据库无关,但诸如 Snowflake 的现代云数据平台,凭借其创新架构与按用量计费,为用户带来诸多独特能力。一个清晰且具前瞻性的设计,能充分利用所依托平台的原生特性,这是构建具成本效益且能够满足并预见业务需求的解决方案的关键。
数据驱动型组织的分析需求复杂且动态变化是出了名的,因此建模必须与时俱进,伴随数据团队从理念到落地。要做到这一点,建模必须超越只关注表结构与关系,同时拥抱改造底层数据的转换逻辑。唯有充分利用 Snowflake 的特性与架构细节,才能高效地从头到尾构建一个模型。
本章将涵盖以下主题:
- 认识模型在日常生活中的用途
- 直观了解建模约定的实际运用
- 熟悉建模工具箱中的各类工具
- 发掘建模对企业团队的收益
- 将建模纳入战略规划
- 理解建模在事务型与分析型系统中的应用
技术要求
本书聚焦 Snowflake Data Cloud 的数据建模。尽管建模包含许多与系统无关的术语与约定,但在构建物理模型与 SQL 转换时,我们将借力 Snowflake 架构、数据类型与函数的独特能力。
要跟随后续章节的练习,你需要一个 Snowflake 账号,并能访问用于创建模式(schema) 、对象与装载数据的沙箱环境。
如果你尚无访问权限,可注册 Snowflake 30 天免费试用(signup.snowflake.com/)。
本书在建模过程中会频繁使用可视化建模图。虽然可以手绘,或用 PowerPoint / Lucidchart 绘制,但我们推荐使用支持常见数据库建模功能的工具。本书的练习会带领读者从与数据库无关的概念图一路走到可部署、可运行的 Snowflake 代码。因此,推荐使用支持多种建模类型且能**正向工程(forward engineer)**生成 Snowflake 语法的工具。
书中的图示使用在线数据库建模工具 SqlDBM(sqldbm.com/Home/)生成。该工具支持上述能力,并提供两周免费试用。
有目的的建模(Modeling with purpose)
模型用于简化复杂系统。以现代城市为例,你会看到其中包含紧密关联的系统:高速路网、电网与公共交通等。尽管它们共享同一片物理空间,却需要不同的模型来帮助我们理解。比如,地铁系统在城市多变的地形下蜿蜒穿行,但我们使用的地铁线路图采用直线并把站点绘成近似等距。线路图并不是城市本身——它是对城市的选择性简化,让乘客更容易可视化自己的旅程。如此普及的交通图,今天看似理所当然,但它也经历了演化。
我们熟悉的地铁线路图由 Harry Beck 于 1931 年在重新设计伦敦地铁线路图时发明。旧版地图之所以让乘客困惑,是因为它关注了错误的目标——地理精确。下图展示了 Beck 之前的样式:
图 1.1 – Beck 之前的伦敦地铁图(Legacy Tube map)
幸运的是,Beck 不是制图师——他是工程师。通过牺牲地形细节,Beck 的设计让乘客能够快速数清旅程所需的站数,同时保有方向感。这个故事字面意义地重申了那句名言:地图不是领土(the map is not the territory)。
与地图类似,组织中的不同团队也需要不同类型的模型,来理解其运营版图的多重层次。同样与地图类似,模型也帮助组织为未来的旅程做好准备。但问题来了:如何用一个模型来穿行数据库,甚至规划其未来?
用好建模工具箱(Leveraging the modeling toolkit)
继续之前,我们需要正式区分三类常被一并使用的概念,方便在后文将其作为建模工具箱中的具体工具来指代。理解每一项在数据库设计与管理的广域中所处的位置,有助于你在后文深入技术概念时更有意义且更易消化。
三大组件如下:
- 自然语言语义——词(words)
- 技术语义——SQL
- 可视语义——图(diagrams)
分别说明如下:
自然语言语义(Natural language semantics)
用于人与人之间沟通模型细节的术语。这些是约定俗成的词汇,借助预定义约定把复杂概念封装为更简单的表达。比如,当交流双方都理解代理键(surrogate key)的概念时,就无需解释“它是对表记录的无业务含义的唯一标识,如自增整数或哈希值”。
要确保技术交流有效,掌握建模语义的“流利度”很有帮助。它不仅能简洁传达复杂概念,还能避免误传而节省更多时间。就像在伦敦与洛杉矶点“chips”,端上来的食物会不同;而一个恰当建模的数据库绝不会对同一代理键返回不同记录。
技术语义(Technical semantics)
SQL 是一门用于在关系型数据库管理系统(RDBMS)中管理数据的领域专用语言(DSL) 。与通用语言(如 YAML、Python)不同,DSL 的适用范围更狭窄,但在其领域内具有更丰富的细节与精度。它不会帮你排版网站或发邮件,但 SQL 允许我们创建数据库结构并操作其内容。
SQL 是把建模概念(以文字或图示表达)与数据库物理定义衔接起来的桥梁。Snowflake 采用 ANSI 兼容的 SQL 语法,这意味着其基本命令(如 SELECT/UPDATE/DELETE/INSERT/WHERE)与采用该标准的其他厂商互通。此外,Snowflake 还提供大量超出 ANSI 标准的函数、子句与约定,赋予用户更大灵活性来管理数据库。
但由于其领域专用特性,SQL 也有显著限制:它只能表达数据库明确理解的内容。SQL 能定义表结构并精确操作数据,却过于细节,难以直接表达底层业务需求。
可视语义(Visual semantics)
图像凭借其简洁性,能传达其他语言形式难以承载的信息密度。在建模中,图把 SQL 的领域精度与自然语言的语义细腻结合起来,从而有足够表现力去捕捉数据模型的业务含义与技术细节。
从呈现粒度上,图可以分层展示细节——给观察者恰到好处的信息,既不淹没也不不足。更重要的是,图中的语义约定具有普适性,不仅数据分析师和工程师,非技术角色也能读懂。是的,建模图是技术绘图,通过约定俗成的视觉符号来表达严格的技术概念;但在最简单的层次上,模型几乎可以直观理解,无需先验知识;即便是更高级的逻辑/物理模型,学会读图也远比学会 SQL 要简单。
当上述三种语义融合并为全组织所理解时,它们便形成一种通用语言(ubiquitous language) ——这一概念最早由 Eric Evans 在领域驱动设计(DDD)中提出。此时,建模成为组织普遍共享的词汇的一部分,用于描述其业务以及承载这些业务的数据资产。而这,仍只是建模所带来的诸多益处之一。
数据库建模的收益(The benefits of database modeling)
没有战略的战术,只是失败前的噪音。 ——孙子(Sun Tzu)
对许多人而言,数据库建模让人想到的是陈旧的图表、晦涩的符号,或是项目末尾的额外负担。就在十年前,伴随 2000 年代初分布式计算兴起(并普及了“大数据”概念), “建模已死”的说法甚嚣尘上。更准确地说,人们以为廉价且近乎无限的算力让规划与设计变得多余;灵活的半结构化数据格式与现读现解析(schema-on-read)能力似乎让建模不再必要。
最终,运维成本把人们拉回现实,暴露了 schema-on-read 的两大缺陷。其一,无论数据如何组织,它都必须与所支撑的业务****功能性绑定。换言之,半结构化并非灵丹妙药,更不是绕过业务校验流程的借口。其二(也是更重要的一点),模型不只是数据进库后呈现的形状,而是业务运营的蓝图;没有它,就不可能构建可持续的架构。
可持续的解决方案需要长期战略,以确保设计契合其业务模型。没有这一点,schema-on-read(见第 15 章《半结构化数据建模》)、星型模型(见第 17 章《以现代技术扩展数据模型》)或任何其他模式,都只是目光短浅的战术,难以为继。相反,若正确地开展建模,它会让数据库架构的开发更敏捷,并帮助项目从想法阶段走向落地。在开发的每个阶段,模型都充当指引:支撑推进设计所需的对话,并提供额外的业务背景;一旦落地,模型会成为活文档,帮助用户理解、穿行并演进它所帮助创建的系统。
几乎所有组织在技术层面都会“做建模”——创建表、转换数据;但并非所有组织都在广义上端到端地“做建模”,也因此错过了长期收益。这些收益包括但不限于:
- 对更广义的业务模型达成一致并具备可见性
- 与业务团队展开更高效的对话
- 更高质量的需求
- 技术讨论中信号更强、噪音更少
- 跨平台、跨领域且广泛可懂的约定
- 面向业务与其数据库版图的整体可视化全貌
- 初步设计可沉淀为实施蓝图
- 加速新成员的入职与融入
- 让数据更易用,开启组织内的自助服务
- 在规模化下保持数据库版图可管理
- 更好地驾驭复杂数据管道
为说明缺乏正式建模工作的困难,我们以 Snowflake 共享的 TPC-H 数据集(位于共享数据库 SNOWFLAKE_SAMPLE_DATA)为例,一个简单的 schema 乍看如下:
图 1.2 – Snowsight UI 中的表清单
尽管这些表在严格意义上已经“被建模”,而且也有数据,但我们几乎无法知道这些数据代表什么、与其他表如何关联,或在业务运营的大背景中处于何处。
直觉会让我们认为 SALES_ORDER 与 CUSTOMER 存在关系,但这一断言需要验证。即便在这个只有八张表的微小示例中,要彻底摸清上下文也要花费相当时间。
讽刺的是,我们想找的许多细节其实早已烙在物理表的设计里——它们在过去的某个时点被建模过。只是我们看不见。没有地图,地形就从视野中消失。
把同样的一组表用一种称为**实体-关系图(ERD)**的建模约定来可视化,结果如下:
图 1.3 – 使用“乌鸦脚(crow’s foot)”标记法的概念模型
只需一眼,全貌便清晰可见。类似的图表让我们理解数据背后的业务概念并确保其一致。拥有一份可视模型还能让我们从单表视角拉远,理解业务的语义:有哪些组成部分,它们如何交互? 这种全局视角让组织内的每个人都能找到并理解数据资产——无需技术背景;于是业务分析师或新同事无需数据团队协助就能释放信息价值。
随着组织在人员与数据资产上的扩张,最终会大到任何个人,甚至单个团队都无法协调的程度。这时,拥抱数据建模的组织将与未拥抱者拉开差距。建模要么成为推动组织规模化数据版图的“助推器”,要么变成束缚前进的技术债。
当然,尽管益处显著,建模并非一招鲜吃遍天的保证成功之术。建模方法众多、流派各异,适配不同的工作负载。全书将系统讲解建模基本原理,帮助你理解这些差异,并以第一性原理选择最合适的方案。首先,我们将拆解两大数据库用例,并观察建模在它们各自中的角色。
运行型与分析型的建模场景(Operational and analytical modeling scenarios)
我们今日所知的关系型数据库诞生于 20 世纪 70 年代——让组织可以将数据存放在集中式库中,而非各自的磁带上。同一年代后期,联机事务处理(OLTP)出现,使得更快的数据访问成为可能,并解锁了诸如订票系统与银行柜面系统等数据库的新用法。这是数据库从数据档案向运行系统范式的转变。
由于资源受限,数据分析无法在与运行处理同一套数据库上完成。对运行数据进行分析的需求在 20 世纪 80 年代催生了管理信息系统(MIS) ,后来被称为决策支持系统(DSS) 。数据会从运行数据库抽取到 DSS,在那里按业务需要进行分析。OLTP 架构并不适合后者,于是出现了联机分析处理(OLAP) ,以便用户用复杂查询从多个视角分析多维数据。这也是 Snowflake 等现代数据平台至今采用的范式。
在 OLAP 系统中,数据的存放与管理方式与运行/交易型数据库本质不同。OLAP 中的数据通常存放在数据仓库(DW/DWH) ——一个集中式存储库,用于汇聚来自多源的结构化数据,以支持分析与决策。交易系统保留最新的“真实版本”,通常关注单条记录;而数据仓库会留存多版历史快照,并聚合大量数据以满足多样的分析需求。
数据诞生于交易数据库:日常业务操作(如订票、销售、取款)被记录下来。相对地,仓库不创造数据,而是装载来自一个或多个源系统的抽取信息。交易库与仓库在功能上的差异,带来了不同的建模挑战:
- 交易系统必须贴合其要处理的数据本性来建模。这意味着要清楚事务所需的格式、关系与属性。
- 交易型数据库模型的主要关注点是表之间的结构与关系。
相对地,数据仓库装载已有的源数据。仓库关注的不是定义单笔交易,而是横跨多维度分析海量交易以回答业务问题。为此,仓库必须对源数据进行转换以满足多种分析,往往需要在不同粒度与细节层级创建副本。
数据仓库中的建模建立在源系统的关系模型之上,通过统一公共要素并以转换逻辑改造数据。
等等——如果转换逻辑是数仓建模的核心概念,为何它在建模讨论中常常缺席?因为若要公正地讨论“转换式建模”,就必须放弃“通用建模原则”的普适性,转而深入平台细节(如语法、存储与内存使用)。与此相反,本书将拥抱 Snowflake 的细节,不仅讨论物理建模,还会深入物理表背后的转换逻辑。这种方法能更全面地理解底层建模概念,并为读者提供所需的 SQL“菜谱”,不仅能构建模型,还能以最高效的方式装载并自动化它们。正如后续章节所示,这正是 Snowflake 真正发光之处,带来性能与成本上的收益。
Snowflake 仅限于 OLAP 吗?
Snowflake 的主要用例是数据仓库——具备 OLAP 的所有性质,以在大规模数据集上实现多维分析。不过,在 2022 年 Snowflake 峰会上,官方发布了一种新的表类型 Hybrid Unistore,在同一语义对象下同时具备OLTP 存储表与OLAP 分析表。这意味着 Snowflake 用户如今可以设计事务型 OLTP 数据库模式,同时利用 Snowflake 著称的分析性能。Hybrid Unistore 将在后续章节中进一步讨论。
尽管 OLAP 与 OLTP 系统针对不同数据库操作各自优化,二者本质上仍是数据库,都使用 SQL 操作同一组对象(表、约束、视图等)。然而,两种用例在如何建模数据方面的方式截然不同。下一节将展示各自场景下建模通常的样貌。
走近关系与转换式建模(A look at relational and transformational modeling)
上一节描述了运行型与数据仓库场景中建模的差异。在深入建模流程细节之前,先感受一下关系建模与转换式建模的“外观与手感”,以及我们的目标。继续之前,先总结交易库与数仓的主要差异(见下表):
| 交易型数据库(Transactional Database) | 数据仓库(Data Warehouse) |
|---|---|
| 支持日常运营 | 提供运营洞察 |
| 操作单条记录 | 汇总多条记录 |
| 此时此刻的准确性 | 随时间推移的历史快照 |
| 单一真实来源(SSOT) 、非冗余 | 为不同分析而冗余 |
| 模型由业务操作定义 | 模型由业务问题生成 |
| 静态且结构化的数据模型 | 继承结构并动态转换的数据模型 |
| 单一应用数据 | 多源数据汇聚 |
图 1.4 – 交易库与仓库的常见差异
基于这些差异,下面分别展示两类系统中的建模长什么样、要达成什么目标。
运行系统中的建模长什么样(What modeling looks like in operational systems)
先暂时忽略把我们带到这一步的建模流程(后文会讲),来看一个交易系统中最常见的建模示例。图 1.5 的物理图既是声明所需表的蓝图,也是理解其业务语境的向导。
依循建模约定(即便你尚不熟悉,后续章节会详讲),我们可以从这张简单的图中推断很多信息。例如,Person 由一个八位数标识符(主键)唯一标识,且必须具备 SSN、驾驶证号、姓名与出生日期。
两张表之间的一对多关系表明:Person 不一定必须有 Account,但每个 Account 必须隶属于且仅隶属于一个 Person:
图 1.5 – 使用“乌鸦脚”标记法的物理模型
这些细节连同字段清单、数据类型与约束,不仅限定了可写入表中的数据类型,也让我们一窥业务如何运作。那么,在分析型数据库中又有何不同?
分析系统中的建模长什么样(What modeling looks like in analytical systems)
在数据仓库场景中,PERSON 与 ACCOUNT 表不会从零定义——而是从源系统中抽取并装载进来,结构与数据一并进入流程。随后围绕组织的业务问题开始分析性转换。这就是大家熟悉的 ETL(尽管 ELT 现已更常用,但原术语沿用至今)。
假设管理团队想分析:按年龄段(十岁一档) ,各年龄段开设了哪些账户类型,并希望把结果存入独立表以便单独分析。
下面的图展示了通过转换性分析得到的一个对象的关系模型,但不提供业务上下文:
图 1.6 – 一个转换性需求的关系模型
尽管物理建模可以描述这张表(如图 1.6 所示)——包含账户类型、年龄段与账户数量(整数) ——这样的模型却无法传达最关键的细节,包括:
- 用于进行该分析的逻辑
- 源表与输出表之间的关系
- 示例中 ACCOUNT_TYPE_AGE_ANALYSIS 的业务需求刻意不在目标表中保留源键字段,从而无法建立任何关系型链接。
不过,关系模型依然扮演关键角色:它告诉我们源之间如何关联,以及如何正确地 Join 以产出所需分析。
然后,我们可按下列方式联接 PERSON 与 ACCOUNT 来构建逻辑:
CREATE TABLE account_types_age_analysis AS
SELECT
a.account_type,
ROUND(DATEDIFF(years, p.birth_date, CURRENT_DATE()), -1) AS age_decade,
COUNT(a.account_id) AS total_accounts
FROM account AS a
INNER JOIN person AS p
ON a.person_id = p.person_id
GROUP BY 1, 2;
尽管 ACCOUNT_TYPE_AGE_ANALYSIS 与其来源之间没有关系型连接,但它显然依赖这些源及其列。对于这类转换管道,我们不再用表达实体与关系的 ERD,而使用血缘(lineage)图来可视化。血缘图给出列级映射,从源到目标,包含所有中间步骤,如下所示:
图 1.7 – 转换式建模的可视化呈现
配合用于构建它的 SQL 逻辑,血缘图为分析/仓库场景下的源—目标转换关系提供了完整视图。
在见识了关系型与分析型两种建模方式后,不难看出:二者在企业级 Snowflake 环境中应对复杂且动态的现实,都扮演着关键角色。
尽管我们仅仅走马观花地介绍了建模所涉内容,以及可为此目的加以利用的 Snowflake 独特特性,但希望本章已让你感受到建模在构建、维护与文档化数据库系统中的重要作用。在接下来的章节深入口头、技术与可视三类建模语义的细节之前,让我们先回顾一下本章要点。
摘要(Summary)
逃不开建模。我们在日常生活中用它来规划与穿行周遭世界的复杂性——数据库也不例外。对一些读者而言,本章呈现的建模风格也许是他们重新构想数据库版图的新方式;对另一些读者,这可能是对其标记法与用例的再熟悉。无论是思考一家公司的业务模型,还是把定稿设计分享给团队成员,我们都在不同程度上参与着建模。
拥抱数据库建模并学习使用一套全组织通用的语言,可以为整个组织解锁大量节省时间与协作的收益。相较于战术性应对,从长期出发、进行战略性建模,能够让数据库设计与其所支撑的业务相一致,从而确保其可行性。在了解了建模能带来的优势及其落地场景之后,我们可以开始剖析构成要素,以明确它们应在何处使用,以及它们如何自然衔接形成一条设计演进路径。
在下一章中,我们将探讨数据库设计中使用的四种建模类型,讨论它们各自的擅长领域,以及它们如何相互叠加,把一个想法逐步演化为技术系统设计,同时产出可用于导航与维护最终产品的活文档式项目资产。