在数据库系统实践的半个世纪里,“建模”一词的含义已经发生了显著变化。本章旨在揭开建模的神秘面纱,探讨其应用、方法论及其带来的益处。通过这一旅程,建模的概念将逐步展开,成为一套帮助组织设计和管理数据的方法和术语,更重要的是,帮助组织更好地理解自身。
广义而言,建模是一种选择性简化,用于帮助理解或设计更复杂的事物。任何系统都可以被分解为更小、更易管理的部分。单独处理任何一个部分可能是简单的,但如果没有整体策略,这样的做法可能会在未来妨碍系统的可扩展性和可维护性。
尽管建模通常被认为是与具体数据库无关的,但像 Snowflake 这样的现代云数据平台由于其创新的架构和基于消费的定价模式,为用户提供了许多独特功能。一个清晰且面向未来的设计,能够利用支持平台的原生功能,是构建能够满足和预见业务需求的高效成本解决方案的关键。
数据驱动型组织的分析需求通常复杂且不断变化,因此建模必须紧跟步伐,陪伴数据团队从概念到执行的全过程。要实现这一点,建模必须超越数据库表的结构和关系,还要涵盖用于移动和塑造底层数据的转换逻辑。只有深入挖掘 Snowflake 的功能和架构,才能高效地从头到尾构建模型。
本章涵盖的主要主题包括:
- 认识模型在日常生活中的实用性
- 了解建模规范的实际应用
- 熟悉建模工具箱中的工具
- 探索建模对企业团队的益处
- 将建模纳入战略规划
- 理解建模在事务性和分析性系统中的应用
技术要求
本书专注于 Snowflake 数据云中的数据建模。尽管建模包含许多与系统无关的术语和规范,本书将在构建物理模型和结构化查询语言 (SQL) 转换时,利用 Snowflake 架构、数据类型和功能的独特优势。
为了跟随后续章节中的练习,您需要一个 Snowflake 账户,并能够访问用于创建模式、对象和加载数据的沙箱区域。如果您尚未拥有 Snowflake 账户,可以注册一个 30 天免费试用账户。
本书经常使用建模流程中的可视化建模图。这些图表可以手绘,也可以使用 PowerPoint 或 Lucidchart 构建,但建议使用支持常见数据库建模功能的工具。由于本书的练习将读者从概念性、与数据库无关的图表引导至可部署和运行的 Snowflake 代码,因此推荐使用支持多种建模类型且可以正向生成 Snowflake 语法的工具。
本书中的图表是使用 SqlDBM 在线数据库建模工具(SqlDBM)生成的,该工具支持上述功能并提供两周的免费试用。
目标驱动的建模
模型是用来简化复杂系统的。以现代城市为例,我们可以看到它由复杂交织的系统组成,比如高速公路、电网和公共交通系统。尽管这些系统共处于同一物理区域,但它们需要完全不同的模型来帮助我们理解它们。例如,地铁系统穿梭在城市多变的地形下,但我们对它的建模——地铁线路图——却采用了直线,并将车站几乎均匀地排列开来。地铁线路图并不是城市本身,而是对城市的选择性简化,使乘客能够更轻松地规划他们的旅程。地铁线路图作为一种模型已经如此普及,以至于我们很难想象其他的表示方式——然而,它的形成经历了一段演变过程。
我们今天熟知的地铁线路图由哈里·贝克(Harry Beck)于1931年设计,当时他正在重新设计伦敦地铁的地图。旧版设计让乘客感到困惑,因为它关注了错误的目标——地理的精确性。以下是贝克之前的设计样式:
幸运的是,贝克并非一名制图师,而是一名工程师。
通过牺牲地形细节,贝克的设计使乘客可以快速计算出旅程所需的停靠站数量,同时保留了整体的方向感。这段故事恰如其分地提醒了我们——地图不是领土本身。
与地图类似,建模的多种方式可以帮助组织内的团队理解其运作环境的多个层面。同样如地图般,模型还能够帮助组织为未来的旅程做好准备。但是,如何利用模型来导航一个数据库,甚至规划它的未来呢?
利用建模工具箱
在深入探讨之前,我们需要正式划分建模中经常结合使用的三种概念,以便在后续章节中更清晰地引用建模工具箱中的具体工具。通过理解这些组成部分在数据库设计和管理领域中的位置,后续深入的技术概念将更易于理解和消化。
以下是这三种组件:
- 自然语言语义——文字
- 技术语义——SQL
- 视觉语义——图表
让我们逐一详细探讨这些内容:
自然语言语义:文字
自然语言语义指的是人们在交流模型细节时使用的术语。这些术语是事先约定的词语,遵循预定义的惯例,将复杂的概念浓缩为简单的表述。例如,当交流双方都理解“代理键”的概念时,无需额外解释它是一个用于唯一标识表记录但没有任何内在业务含义的标识符(如整数序列或哈希值)。
为了确保技术交流的有效性,熟练掌握建模的语义非常重要。它不仅通过简洁的方式传递复杂概念节省时间,更能避免因误解而浪费时间。例如,在伦敦和洛杉矶点“chips”,服务员会端上不同的食物。同样,一个适当建模的数据库绝不会因为相同的代理键返回不同的记录。
技术语义:SQL
SQL(结构化查询语言)是一种领域特定的语言,用于管理关系型数据库管理系统(RDBMS)中的数据。与通用编程语言(如YAML或Python)不同,领域特定语言的应用范围更窄,但提供了更丰富的细微差别和精确度。尽管SQL不能用于格式化网页或发送电子邮件,它却能定义数据库结构并操作其内容。
SQL将建模概念(用文字或图像表达)与数据库中物理定义的内容联系起来。Snowflake数据库使用符合美国国家标准协会(ANSI)的SQL语法,这意味着其基本命令(如SELECT、UPDATE、DELETE、INSERT和WHERE)与使用这一标准的其他数据库供应商兼容。此外,Snowflake还提供了许多超越ANSI标准SQL的额外功能、子句和约定,为用户灵活管理数据库提供了更多选择。
然而,由于其领域特定的性质,SQL也存在显著局限性:它只能表达数据库明确理解的内容。尽管SQL可以定义表结构并精确操作数据,但它过于详细,难以清晰地表达底层业务需求。
视觉语义:图表
通过其简洁性,图像能够传递其他语言形式难以承载的信息密度。在建模中,图表结合了SQL的领域特定精确性和自然语言的细腻表达。这使得图表能够在捕捉数据模型的业务意义和技术细节方面大有作为。
首先,图表的详细程度可以根据观察者的需求调整——既能避免信息过载,也不会因信息不足而影响理解。最重要的是,图表中使用的语义约定是通用的,不仅限于数据分析师和工程师。尽管建模图表是技术绘图,使用公认的视觉约定来表示严格的技术概念,但其最简单的形式几乎可以被直观地理解而无需事先知识。即便是更高级别的逻辑或物理模型,学会阅读模型也比学习SQL简单得多。
当这些语义融合在一起并被整个组织理解时,它们便形成了一种通用语言。这一概念最早由埃里克·埃文斯(Eric Evans)在其《领域驱动设计》(Domain-Driven Design)一书中提出。建模成为组织内普遍使用的语言的一部分,用来描述业务并存储支持业务的数据资产。但这仅仅是建模带来的众多好处之一。
数据库建模的好处
没有战略的战术只是一场失败前的喧嚣。(孙子)
对于许多人来说,数据库建模让人联想到陈旧的图表、晦涩的符号,或是项目结束时的一些额外工作。仅仅十年前,受 2000 年代初分布式计算兴起的推动——这促进了“大数据”概念的普及——“建模已死”的观点广为人知。更确切地说,人们认为廉价且几乎无限的计算能力已经让规划和设计成为过去。有人宣称,灵活的半结构化数据格式以及即时解析能力(即“按读取建模”或“schema-on-read”)使建模变得多余。
然而,随着运行和维护成本逐渐显现,按读取建模方法的两大缺陷暴露出来。其一,无论数据的结构如何,它都必须功能性地与其支持的业务绑定。换句话说,半结构化格式既不是灵丹妙药,也不能成为跳过业务验证过程的借口。其二——也是最重要的——一个模型不仅仅是数据上传到数据库后的形状,而是业务运作的蓝图,没有它,构建可持续架构是不可能的。
可持续的解决方案需要一项长期战略,以确保其设计与底层业务模型匹配。如果没有这种战略,无论是按读取建模(将在第 15 章《建模半结构化数据》中讨论)、星型模型(将在第 17 章《通过现代技术扩展数据模型》中讨论),还是其他任何模式,都只是狭隘的战术,无法带来真正的成果。但如果做得正确,建模能够让数据库架构的开发更加敏捷,并帮助项目从概念阶段逐步演进到实施阶段。在开发的每个阶段,模型都可以作为指导工具,支持推动设计进入下一个阶段的必要讨论,并提供额外的业务背景。一旦实施,模型就变成了一份“活文档”,帮助用户理解、导航并逐步优化其帮助构建的系统。
虽然每个组织在技术层面都在进行建模(例如创建表和转换数据),但并非所有组织都会从头到尾地进行战略性建模,从而错过了长期的收益。这些收益包括以下几点:
- 对更广泛的业务模型达成共识并提升可见性
- 与业务团队进行更高效的对话
- 提高需求质量
- 在技术讨论中减少噪声,提高信号强度
- 跨平台、跨领域且广泛适用的约定
- 对业务及其数据库影响的全局视觉概览
- 初步设计变成可实施的蓝图
- 加快新团队成员的入职流程
- 提升数据的可访问性并释放组织内的自助服务潜力
- 在大规模场景下保持数据库环境的可管理性
- 掌控复杂的数据管道
为了展示没有正式建模的工作困难,我们可以以 Snowflake 提供的共享 TPC-H 数据集为例(可在名为 SNOWFLAKE_SAMPLE_DATA 的共享数据库中找到)。初看之下,这个简单的模式可能像这样:
尽管这些表格已经从严格意义上被建模,甚至包含了数据,但我们很难获取有关这些数据的具体含义、它们与其他表格中数据的关联方式,或它们在更广泛的业务运营背景中的位置。
直觉上,SALES_ORDER 和 CUSTOMER 表之间似乎存在某种关系,但这一假设需要验证。即使在这个只有八个表的简单示例中,要彻底梳理数据并理解其上下文也需要相当多的时间。
讽刺的是,我们正在寻找的许多细节实际上早已嵌入到物理表的设计中,因为它们在某个时刻已经被建模过了。只是我们无法直接看到它们。没有地图,地形便无从得知。
以下是通过一种建模约定——实体关系图(Entity-Relationship Diagram, ERD)——可视化的同一组表:
一目了然,全局视图变得清晰起来。像这样的图表可以帮助我们理解数据背后的业务概念,并确保它们保持一致。拥有一个可视化模型还可以让我们从单个表的细节中抽离出来,从整体上理解业务的语义:这些独立的组成部分是什么,它们如何交互?这种全局视角为组织内的每个人提供了一种方式,使他们能够找到并理解数据资产,而无需具备技术背景——因此,业务分析师或新员工无需数据团队的帮助,也能挖掘出信息的价值。
随着组织的发展,无论是人员规模还是数据资产的扩张,最终都会变得过于庞大,以至于个人甚至一个团队都无法协调管理。在这种情况下,那些拥抱数据建模的组织将从未采用建模的组织中脱颖而出。建模可能成为帮助组织扩展其数据环境的关键工具,也可能是阻碍其发展的技术债务。
然而,尽管建模有诸多好处,它并不是一个保证成功的万能解决方案。建模有许多方法和各种适合不同工作负载的建模方法论。在本书中,我们将探讨建模的基本原理,这些原理将帮助您理解这些差异,并通过第一性原理的方法应用最适合的解决方案。首先,我们将从拆解两个主要的数据库用例开始,观察建模在每种用例中的作用。
运营和分析建模场景
我们今天所熟知的关系型数据库起源于 1970 年代,使得组织能够将数据存储在集中式存储库中,而不是分散在各个磁带上。到了同一年代后期,联机事务处理(Online Transaction Processing,OLTP) 应运而生,极大地提高了数据访问速度,并解锁了数据库的新用途,例如预订和银行柜员系统。这对数据库来说是一场范式转变——从数据存档进化为运营系统。
由于资源有限,数据分析无法在运行操作流程的同一个数据库上进行。对运营数据进行分析的需求在 1980 年代催生了管理信息系统(MIS) ,后来被称为决策支持系统(DSS) 。运营数据库中的数据被提取到 DSS 系统中,在那里可以根据业务需求进行分析。由于 OLTP 架构并不适合分析需求,联机分析处理(Online Analytical Processing,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 操作相同的一组对象(例如表、约束和视图)。然而,每种用例对数据建模的需求截然不同。以下部分展示了在每种场景下建模通常会是什么样子。
关系建模与转换建模的概览
上一部分描述了建模在运营系统和数据仓库场景中的差异。在详细探讨建模过程之前,了解关系建模和转换建模的外观与特点,以及我们所要实现的目标,会有所帮助。在深入之前,以下是事务型数据库和数据仓库之间主要差异的总结:
| 事务型数据库 | 数据仓库 |
|---|---|
| 支持日常操作 | 提供运营洞察 |
| 处理单个记录 | 汇总多个记录 |
| 反映当前时刻的准确性 | 提供随时间推移的历史快照 |
| 单一事实来源(SSOT),无冗余 | 为支持不同分析目的而冗余 |
| 数据模型由业务操作定义 | 数据模型由业务问题生成 |
| 静态且结构化的数据模型 | 继承结构并动态转换的数据模型 |
| 单一应用的数据 | 来自多个源的数据汇聚 |
图 1.4 – 事务型数据库与数据仓库的常见差异
鉴于这些差异,以下部分展示了每种系统中的建模外观及其目标。
运营系统中的建模外观
暂时忽略将我们引入此处的建模工作流程(稍后章节会详细介绍),我们可以观察事务型系统中最常见的一种建模示例。图 1.5 中的物理图既可以作为声明所需表的蓝图,也可以作为理解其业务背景的指南。
遵循建模约定(如果您对此仍不熟悉,请不用担心——后续章节会详细讲解),我们可以从这个简单的图表中推断出很多信息。例如,一个人通过一个八位数的标识符(主键)唯一标识,且必须具有社会安全号码(SSN)、驾驶证、姓名和出生日期。
两个表之间的一对多关系表明:虽然一个人不一定需要拥有一个创建的账户,但一个账户必须属于一个特定的人:
这些细节结合属性列表、数据类型和约束,不仅规定了可以写入这些表的数据类型,还提供了关于业务运作方式的一些线索。那么,这与分析型数据库有何不同呢?
分析系统中的建模外观
在数据仓库场景中,PERSON 和 ACCOUNT 表不会从零开始定义——它们会从其所在的源系统中提取并加载进来,同时引入其结构和数据。随后,围绕组织的业务问题展开分析型转换。这一过程被称为提取-转换-加载(Extract Transform Load,ETL) 。(尽管 ELT(先加载后转换)已经成为首选处理顺序,但最初的术语仍然沿用下来。)
假设管理团队希望分析不同年龄段(以十年为单位)的人群开设哪种类型的账户,并希望将结果存储在一个独立的表中以供进一步分析。
下图展示了通过转换分析获得的一个对象的关系模型,但未提供任何业务背景:
尽管物理建模可以描述这样一个表(如图 1.6 所示)——包含账户类型、年龄和账户数量等整数字段——但这样的模型无法传达最相关的细节,这些细节如下所示:
- 执行分析所用的逻辑
- 源表与输出结果之间的关系
在此示例中,ACCOUNT_TYPE_AGE_ANALYSIS 的业务需求特意将源键字段排除在目标表之外,从而无法建立任何关系链接。然而,关系模型仍然发挥着重要作用:它告诉我们源表之间的关系,以及如何正确地连接它们以生成所需的分析结果。
分析逻辑可以通过将 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)不同,转换型数据管道通常通过数据血缘图来可视化。这种图表提供了从源到目标的字段级映射,包括所有中间步骤,如下所示:
与用于构建数据表的 SQL 逻辑结合使用,数据血缘图提供了在分析/数据仓库场景中源数据与目标数据之间的转换关系的完整视图。
在了解了关系建模和分析建模的方法后,可以清楚地看到,这两者在企业级 Snowflake 环境中所面临的复杂动态环境中都扮演了重要角色。
尽管我们仅仅触及了建模的表面,以及 Snowflake 平台可以用来支持建模的独特功能,但本章的内容希望能够让您初步认识到建模在构建、维护和记录数据库系统中至关重要的作用。在深入研究建模中的自然语言、技术和视觉建模语义之前,我们先回顾一下所学内容。
总结
建模是不可避免的。在日常生活中,我们通过建模来规划和应对周围世界的复杂性——数据库也不例外。对于部分读者来说,本章介绍的建模方式可能是一种全新的数据库思维方式,而对于其他读者,这可能是重新熟悉其符号和用例的机会。无论是思考公司的业务模型,还是与团队成员分享最终设计,我们都在不同程度上参与建模。
拥抱数据库建模并学会使用一种通用语言,可以为整个组织带来许多节省时间和增强协作的好处。从长远考虑并进行战略性建模,而不是采取战术性的应对,可以让数据库设计与其支撑的业务保持一致,确保其可行性。在了解了建模的优势以及其可实施的领域后,我们可以开始分析建模的组成部分,以准确理解它们应该被使用的场景以及它们如何形成自然的设计演进。
在下一章中,我们将探讨数据库设计中使用的四种建模类型,并讨论它们的优点,以及如何在这些类型的基础上逐步构建,从一个想法演变为技术系统设计,同时生成项目的动态工件,以帮助导航和维护最终产品。
进一步阅读
本章中提到的 Eric Evans 的书探讨了如何通过深入系统意图而不仅仅停留在表面,来创建有效的模型。对于希望深入研究通过模型进行有效沟通的领域(不限于特定技术领域、方法或约定)的读者,这本书是强烈推荐的阅读材料:
Evans, Eric. Domain-Driven Design: Tackling Complexity in the Heart of Software. Addison-Wesley Professional, 2004.
参考资料
- 经典地铁图,维基媒体共享资源,commons.wikimedia.org/wiki/File:T… 年 10 月 2 日。