题记与说明
课题:数据建模入门:范式、反范式、时间序列与事件数据取舍
报告性质:纵轴(历时)与横轴(2026-11-05 截面对比)两份章节报告的综合稿。本文件为最终稿,已按独立审读意见(8 条)逐条修订。
日期:2026-11-05
信源声明:两份章节报告的关键事实均在撰写当日经 WebSearch 与网页抓取工具核验并随文附来源 URL(纵轴章:WebSearch 12 次 + Wikipedia: Apache Cassandra 全文核读;横轴章:WebSearch 16 次 + WebFetch 实抓 6 页 + WebReader 实抓 2 页)。本综合稿合并两章来源并保留全部链接;凡属本稿新增的综合判断而非章节原文,均在文中标注"综合判断"。
综合处理说明(对两章差异与重复的处理记录):
1. 两章使用了两套案例叙事——纵轴的"青苔账本"七时代叙事、横轴的 A/B/C 三个基准场景。本稿将其统一为同一套案例体系:A/B/C 即青苔账本三个功能面在当下时间截面上的切片,映射表见 §2.4。
2. Timescale 公司已更名为 Tiger Data。本稿统一写法:公司名作"Tiger Data(Timescale)",其产品名作"TimescaleDB"。
3. 纵轴阶段三(NoSQL,2005–2012)与阶段五(事件数据,2005–2019)时间区间重叠并非矛盾,而是两条并行演化的支线,正文 §1.3 已明确标注。
4. Kimball《The Data Warehouse Toolkit》1996 年初版(纵轴事件)与 2013 年第 3 版(横轴竞品)是同一方法论的不同版本,不构成冲突。
5. 本稿面向入门读者:正文首现的技术术语(CDC、TTL、写放大、ELT、GIN、向量化执行、hypertable、连续聚合、物化视图等)在附录 C 术语表中给出一句话白话解释;§2.2 图例说明两套评分刻度(✔/△/✘ 与 ★)的定义及换算关系。
TL;DR
数据建模五十六年只由一个变量驱动:查询模式的可预知程度 × 存储/算力成本曲线。范式(1971)与反范式(星型模型,1996)不是对错,是同一问题在不同读写比下的时间差;NoSQL 撕开固定模式后,时序与事件把建模对象从实体扩展到时间线与日志;2020 年代重新融合、单体单库回归。横向对比 15 项(五类)学习资源:没有单一竞品能同时做到四主题覆盖、免费且贴合个人项目尺度;时序与事件两子域,课程类全部缺席、书籍类除 DDIA 2e 外也无人系统覆盖,厂商文档权威但只讲自家。建议:先用归一化的 PostgreSQL 起步,用三问做取舍——查询可预知吗、数据是实体/时间/事件吗、量级多大(判断顺序与量级参考值见附录 A);最贵的错误是用企业数仓的粒度解决一个人的问题(青苔账本 2026 年的完整建表 DDL 与取舍清单见附录 B)。
一、纵轴:发展脉络(1970–2026)
1.1 一条主线
数据建模五十六年的演化,表面上是"范式 vs 反范式"的钟摆之争,实际上由一个真正的变量驱动:读写比例与查询模式的可预知程度,叠加存储/算力的价格曲线。
- 查询模式可预知、磁盘昂贵 → 归一化省空间(1970s);
- 查询模式可预知、读多写少、CPU 贵 → 反范式物化换速度(1990s 数仓);
- 查询模式完全不可预知、写入爆炸 → 干脆放弃固定模式(2000s NoSQL);
- 数据的本质是时间(时序)或过程(事件)→ 建模对象从"实体"转向"时间线"与"日志"(2010s);
- 存储/算力再次暴跌、查询依旧不可预知 → 列式 + 宽表 + "一个引擎吃下所有"(2020s)。
驱动每一次转向的从来不是数据库厂商的品味,而是"下一个数量级的数据是谁写入的、按什么形状查询"这个朴素问题。
1.2 贯穿案例:「青苔账本」
按课题"个人项目案例驱动"的补充要求,全文以一个个人项目作为主线案例——「青苔账本」:一个自用记账 + 博客流量面板的个人小项目,功能包括:①日常记账(收入/支出/分类/账户);②个人博客的文章与评论;③"我这周花了多少、博客哪篇文章最火"的统计面板;后期又接入电表/体重秤(时序数据)与自动化记账(事件流)。
必须如实声明:这是一个为教学叙事构建的复合示例(composite case),由各时代个人开发者最典型的技术栈与决策场景拼合而成,并非某个真实存在并持续运行的项目;每个阶段的"案例节点"演示的是当年一个入门者会面对的真实取舍。所有工程事实与版本节点均有来源支撑,案例本身不冒充真实经历。它从 1970 年代到 2026 年被七个时代的主流范式各"建模"一遍。
(横轴章的三个基准场景——记账 App、传感器日志、埋点事件流——正是青苔账本三个功能面在 2026 年的切片,映射见 §2.4。)
1.3 七个阶段
阶段一:范式奠基(1970–1985)——"一切为了消除冗余"
关键事件与版本节点
- 1970 年:IBM 研究院的 E. F. Codd 发表《A Relational Model of Data for Large Shared Data Banks》(Communications of the ACM, Vol.13, pp.377–387),提出用"关系(表)"存数据、用关系代数查询,让用户不必了解物理存储(ACM DL、免费 PDF、IBM 官方史话、Two Bit History 解读)。鲜为人知的是,它最初是一份 IBM 内部报告的改写——IBM 一度不愿发表,怕动摇自己 IMS 层级数据库的生意。
- 1971–1972 年:Codd 在 Courant 计算机科学研讨会报告《Further Normalization of the Data Base Relational Model》,正式定义 1NF/2NF/3NF——"范式"这个入门第一课的出处(Wikipedia: Third normal form)。1974 年 Boyce 与 Codd 定义更严格的 BCNF;1977 年 Ronald Fagin 提出 4NF(Wikipedia: Database normalization)。归一化的原始动机朴素到一句话:同一个事实只存一遍。
- 1976 年:Peter Chen 发表《The Entity-Relationship Model—Toward a Unified View of Data》(ACM TODS 1(1):9–36),ER 图从此成为全世界数据库入门课本第一章的画法(ACM DL、作者 LSU 页 PDF)。
- 1970s 中期:IBM System R 项目诞生 SEQUEL(后来的 SQL);伯克利 Stonebraker 团队启动 Ingres,随后 1986 年启动 Postgres(PostgreSQL 官方史话)。
- 1979 年:Relational Software Inc.(后改名 Oracle)发布 Oracle V2——第一个商用 SQL 关系数据库(Oracle 文档)。
- 1986 年:ANSI 采纳第一个 SQL 标准 ANSI X3.135-1986(SQL-86),1992 年 SQL-92 成为各家真正对齐的基线(ANSI Blog、Wikipedia: SQL)。
案例节点 1:青苔账本如果活在 1980 年,入门者会这样建模——把"账户""分类""交易"拆成三张表用外键相连,金额冗余字段会被老师用红笔圈出来:省下的每一 KB 都是钱。这时期学的是"如何把事实只存一遍"。
主要参与者:Codd(IBM)、Chen、Stonebraker(伯克利)、Chamberlin 与 Boyce(SEQUEL)。驱动因素:磁盘昂贵、文件系统数据冗余引发的更新异常灾难、以及"数据独立性"的理论追求。
阶段二:反范式合法化(1986–2004)——"为查询而冗余"
关键事件与版本节点
- 1991 年:Bill Inmon 出版《Building the Data Warehouse》,定义"面向主题、集成、随时间变化"的企业级数据仓库,主张仓库本身保持归一化(PDF)。
- 1993 年:Codd 二度出场——白皮书《Providing OLAP to User-Analysts: An IT Mandate》发明了 OLAP 这个词(olap.com 存档)。
- 1996 年:Ralph Kimball 出版《The Data Warehouse Toolkit》初版,把星型模型(star schema)——事实表 + 反范式化的维度表——变成行业标准方法论。这是"反范式"第一次从权宜之计升格为正式的建模学科(Kimball Group 官方方法论页)。"Inmon vs Kimball"之争(自顶向下归一化 vs 自底向上维度建模)主导了此后二十年的数仓课程。
- 1995–1996 年:MySQL 由 Michael "Monty" Widenius、David Axmark、Allan Larsson 创建并对外发布,2008 年 Sun 以 10 亿美元收购,2009 年 Widenius 又 fork 出 MariaDB(Oracle MySQL 回顾、Wikipedia: Michael Widenius);Postgres95 于 1995-09-05 发布、1996-07-08 更名 PostgreSQL(PostgreSQL 官方史话)。LAMP 栈把数据库带进个人开发者的客厅。
案例节点 2:青苔账本的统计面板要做"本周各类目支出趋势"。归一化的三张表 JOIN 起来慢得难受,入门者第一次学到那句反直觉的口诀:"报表库里允许、甚至应该冗余"——预聚合一张宽表,空间换时间。范式与反范式的分工雏形就此出现:OLTP 归一化保一致,OLAP 反范式保查询。
主要参与者:Inmon、Kimball、Codd(二度)、MySQL/PostgreSQL 社区。驱动因素:BI 分析需求爆发、硬件变便宜使"冗余换查询速度"从奢侈变成划算。
阶段三:NoSQL 冲击(2005–2012)——"模式被撕开的十年"
关键事件与版本节点
- 2000 / 2002 年:Eric Brewer 在 PODC 主题演讲提出 CAP 猜想,2002 年 MIT 的 Gilbert 与 Lynch 形式化证明——分布式系统必须在一致性/可用性/分区容忍间取舍,为"放弃强一致"提供理论通行证(Gilbert & Lynch 论文、Wikipedia: CAP theorem、Brewer 2012 反思)。
- 2006 年:Google《Bigtable: A Distributed Storage System for Structured Data》(OSDI'06,Fay Chang、Jeff Dean 等)公开宽列存储蓝图(PDF)。
- 2007 年:Amazon《Dynamo: Amazon's Highly Available Key-value Store》(SOSP'07)公开最终一致性 + 可调取舍的设计(PDF),被公认为点燃 NoSQL 运动的导火索。
- 2008–2010 年:Facebook 的 Avinash Lakshman(Dynamo 共同作者)与 Prashant Malik 为收件箱搜索开发 Cassandra,2008 年 7 月在 Google Code 开源,2009 年 3 月进 Apache 孵化器,2010-02-17 毕业为 Apache 顶级项目(Wikipedia: Apache Cassandra,纵轴章本次已全文核读)——"Dynamo 的分布 + Bigtable 的存储模型"的合体。
- 2009 年:MongoDB 1.0 于 2009-02-11 由 10gen 公开发布,文档模型把"schema-less"带给大众开发者;Redis 由 antirez 为自己的实时分析服务 LLOOGG 于 2009 年 3 月发布(Wikipedia: MongoDB、Wikipedia: Redis);同年 6 月 11 日 Johan Oskarsson 在旧金山组织 meetup,Eric Evans(Rackspace)把 "NoSQL" 这个标签贴给了整个运动。
- 同期理论余波:Brewer 2012 年《CAP Twelve Years Later》自我修正,指出 CAP 常被滥用为"三选二"。
案例节点 3:2010 年的青苔账本赶了时髦——迁移 MongoDB,"想加字段就加,再也不写迁移脚本"。三个月后为统计面板聚合账目时才撞上第一课的反面:当查询模式不可预知时,模式自由是 gift;当查询模式很明确时(报表就是明确查询),它变成账单。最终博客与账本回到 PostgreSQL,只留一个缓存用 Redis。入门者由此学到"取舍"这个词的真正含义。
主要参与者:Google、Amazon、Facebook、10gen、antirez、Apache 社区。驱动因素:Web 2.0 数据量指数级增长、单机 RDBMS 扩展成本、可用性优先的互联网业务形态。
阶段四:时间序列成为一等公民(2010–2017)——"当数据的本质是时间"
关键事件与版本节点
- 更早的伏笔:金融界早就为 tick data 建了专门的列式时序库——Arthur Whitney 1993 年创立 Kx Systems,kdb(约 1998)演化出 kdb+ 与 q 语言(2003),至今仍是高频交易标配(Kx 官方、kdb 史话)。
- 2010 年:StumbleUpon 的 Benoit Sigoure 为监控十亿级数据点写出 OpenTSDB(架在 HBase 上)(OpenTSDB 官网)。
- 2012 年:SoundCloud 的 Matt T. Proud 与 Julius Volz 发起 Prometheus(Go、拉模型、多维标签),2013 年投入生产、2015 年 1 月公开发布(SoundCloud 官方博客);2016 年成为 CNCF 第二个托管项目、2018 年 8 月第二个毕业(仅次于 Kubernetes)(CNCF 公告)。
- 2013–2016 年:InfluxDB 项目启动,2016 年 9 月发布 1.0 GA,内置自研 TSM(Time-Structured Merge)存储引擎——为追加写入、按时间过期、降采样这些"时序形状"的负载专门设计(InfluxData 1.0 回顾)。
- 2014 年:Torkel Ödegaard 从 Kibana fork 出 Grafana,2014-01-19 首次公开发布,与 Raj Dutt 等创立 Grafana Labs("4 Years Of Grafana"、Grafana UX 史话)。
- 2017 年 3 月:TimescaleDB beta 发布,口号"无聊的 brilliant"——把时序能力做成 PostgreSQL 扩展,用自动分块(chunk)+ 行列混合存储,主张"不要为时序再养一个数据库"(Timescale 官宣;Timescale 公司现已更名 Tiger Data)。
案例节点 4:青苔账本接上了电表和体重秤,数据第一次有了"append-only、按时间查询、定期过期"的形状。沿用案例节点 3 回归的 PostgreSQL 存了半年,B 树索引的写放大与"过期数据只能手写 DELETE 逐批清理"的维护负担开始报警;入门者学到时序建模三件套:时间为主键前缀、按标签分 series、downsampling + retention 策略——这是与"实体建模"完全不同的一套肌肉。
主要参与者:Kx、StumbleUpon、SoundCloud、InfluxData、Tiger Data(Timescale)、Grafana Labs。驱动因素:IoT、DevOps 监控与金融行情把"时间戳数据"推到主流,通用数据库的写放大与 TTL 缺陷暴露无遗。
阶段五:事件数据与流(2005–2019,与阶段三、四并行演化)——"当数据的本质是过程"
(注:本阶段与阶段三时间区间重叠,因为"NoSQL 撕开 schema"与"事件建模成形"是同一场 Web 2.0 数据洪流的两个侧面,属于并行支线而非先后继承。)
关键事件与版本节点
- 2005 年:Martin Fowler 撰文定义 Event Sourcing——不存"当前状态",存"改变状态的事件",状态是事件重放的结果(EventSourcing)。
- 2011 年 7 月:Fowler 为 CQRS(命令查询职责分离,Greg Young 命名并推广)写 bliki 正式收录(CQRS、Greg Young 博客)——读写两侧从此被允许使用两种不同的数据模型。
- 2010–2012 年:LinkedIn 的 Jay Kreps、Neha Narkhede、Jun Rao 开发 Kafka,2011 年初开源、2011 年 7 月进 Apache 孵化器、2012-10-23 毕业为顶级项目;2011 年论文《Kafka: a Distributed Messaging System for Log Processing》(Wikipedia: Apache Kafka、论文 PDF)。
- 2013-12-16:Kreps 发表《The Log: What every software engineer should know about real-time data's unifying abstraction》,把"日志"立为统一抽象——事件数据第一次有了自己的"关系模型时刻"(原文)。
- 2014 年:Kafka 三位作者离职创立 Confluent,Schema Registry 让 Avro/JSON/Protobuf 消息获得带兼容性检查的版本化 schema——事件流的"范式治理"成型(Confluent 文档)。
- 2016 年:Red Hat 开源 Debezium(CDC),2016-08-02 发布 MySQL binlog 变更捕获——数据库自身的事务日志变成事件流的源头,"双写不一致"问题有了标准解法(Debezium 官宣博客)。
- 约 2019 年:Adam Dymitruk 提出 Event Modeling,把事件溯源的蓝图方法可视化(eventmodeling.org、Confluent 课程)。
案例节点 5:青苔账本想加"转账后自动记账 + 报表实时刷新"。第一版用定时轮询 + 双写,很快遭遇"两边对不上"。重构成事件模型后:记账命令追加事件流,报表是事件的物化视图,CDC 同步两库。入门者学到事件建模的核心三问:事实(Fact)、命令(Command)、读模型(Read Model)各自是什么——这是与实体建模并立的第二套世界观。
主要参与者:Fowler、Greg Young、Kreps 团队、Confluent、Red Hat、Dymitruk。驱动因素:微服务解耦、实时数仓需求、以及"日志即真相"哲学的普及。
阶段六:现代数据栈与湖仓(2015–2022)——"建模对象变成表格式与管道"
关键事件与版本节点
- 2015 年:Snowflake 云数仓 GA,首创存储与计算分离、按需付费;2020-09-16 IPO 定价 $120、募资 34 亿美元、首日开盘涨超 111%,创下当时软件公司 IPO 纪录(Snowflake 公告、CNBC)。
- 2016 年:咨询公司 Fishtown Analytics 把内部工具 dbt 产品化——SQL 写的 SELECT + Jinja 即数据转换,自称"the T in ELT";2021 年 6 月更名 dbt Labs 并获 1.5 亿美元 C 轮(dbt Labs 公告)。"分析工程"(analytics engineering)成为新职业,建模从 DBA 的 ER 图变成 git 仓库里的 SQL 文件。
- 2017–2019 年,三大湖仓表格式相继诞生:Uber 的 Hudi(2017 开源,为数据湖补 upsert/增量处理)、Netflix 的 Iceberg(2018,取代 Hive 表格式,2020 年成为 Apache 顶级项目)、Databricks 的 Delta Lake(2019,基于 Parquet 补 ACID)——建模的前沿从"表结构"下沉为"表格式"(ACID、schema evolution、time travel)(Dremio 对比)。
案例节点 6:青苔账本的原始流水一键 Fivetran/CSV 进对象存储,dbt 里写 stage → mart 两层模型,git 版本管理。入门者第一次发现"数据建模"的重心从怎么设计表漂移到怎么设计管道与契约。
主要参与者:Snowflake、Fishtown/dbt Labs、Uber、Netflix、Databricks。驱动因素:对象存储价格崩溃、计算存储分离、ELT 取代 ETL、分析师工程化。
阶段七:融合与回归(2019–2026)——"一个引擎吃下所有,然后重新组合"
关键事件与版本节点
- 伏笔(2014-12-18):PostgreSQL 9.4 发布 JSONB——二进制 JSON + GIN 索引,让关系库正面对抗文档库,"Postgres 万能化"路线开启(官方发布公告)。
- 2016-06-15:Yandex 在 Highload++ 开源 ClickHouse(Apache 2.0;原型 2009 年起为 Yandex.Metrica 服务),列式 + 向量化执行 + 宽表反范式成为 OLAP 事实标准;2021 年分拆成立 ClickHouse, Inc.(官方开源十周年回顾、Wikipedia: ClickHouse)。ClickHouse 社区把去归一化宽表作为官方推荐姿势——反范式在此彻底"转正"(社区讨论、DoubleCloud 解析)。
- 2019 年:CWI 阿姆斯特丹的 Raasveldt 与 Mühleisen 发表 DuckDB(SIGMOD'19)——进程内的"SQLite for analytics",把列式分析能力塞回每个人的笔记本(论文 PDF)。
- 2021 年:Andrew Kane 发布 pgvector(2021-04),Postgres 从此也能存向量;AI 时代它以 2 万+ star 证明"一个库到底"路线的生命力(GitHub)。
- 2023 年:两个标志性"反架构税"事件——5 月 Prime Video 团队把音视频质量监控从 Step Functions+Lambda 微服务合并为单机单体,成本降约 90%,引爆全行业反思(原文 PDF 存档、HN 讨论);DHH 发文《How to recover from microservices》,37signals 用"单体 + 单库"重写 Campfire(DHH 原文)。
- 2023–2025 年:InfluxDB 3.0 把引擎重写为 Rust + Apache Arrow/DataFusion/Parquet,支持 SQL,2025 年 4 月 Core/Enterprise 开源 GA——连最专一的时序库也开始向 SQL/列式开放生态靠拢(3.0 公告、开源计划)。
案例节点 7(当下):2026 年的青苔账本大概长这样——一个 PostgreSQL(账本 + JSONB 存原始收据 + TimescaleDB 存传感器时序 + pgvector 存"记账助手"语义检索),一个 DuckDB(本地随手分析 Parquet),一条轻量事件流(CDC 到下游物化视图)。当年"为每种形状养一个数据库"的教条,让位给"先一体、长痛再拆"的工程务实。
主要参与者:PostgreSQL 全球社区、Yandex/ClickHouse Inc.、CWI、InfluxData、37signals。驱动因素:云成本审计、开发者体验优先、单体性能回归(Prime Video 效应)、AI 负载与向量数据的加入。
1.4 纵轴收束:给入门者的五条历史结论
- 范式与反范式不是对错,是时间差:归一化押注"查询模式将来才知道",反范式押注"查询模式现在已经知道"。三范式(1971)与星型模型(1996)相隔 25 年,本质是同一问题在不同读写比下的两种答案。
- 每个"反范式时刻"都伴随硬件/成本曲线的拐点:磁盘贵 → 归一化;CPU/IO 贵但磁盘便宜 → 物化;对象存储白菜价 → 湖仓宽表。
- 建模对象在扩大,从没有替换:实体(1976)→ 维度(1996)→ 文档/宽列(2009)→ 时间线(2013)→ 事件日志(2013)→ 表格式与管道(2019)——今天的入门者需要的是一张"取舍地图",而不是"唯一正解"。
- 钟摆的摆锤是复杂度税:NoSQL 解放了 schema,也把一致性责任甩给应用;微服务解放了部署,也甩来了分布式事务。2023 年 Prime Video 与 37signals 的"回归"不是倒退,是对超出问题规模的复杂度说不。
- 个人项目的最佳策略与五十六年历史同构:先用一个归一化的 SQL 库开始(1985 的答案仍然正确),等负载的真实形状显现后,再按本史各阶段的工具箱对症物化——这就是"数据建模入门"五个字在 2026 年的全部含义。
二、横轴:横向对比(2026-11-05 截面)
2.1 研究方法与课题画像
方法:把本课题当成一个"产品"做竞品分析。竞品按学习路径而非按产品划分,归为五类:①经典书籍;②付费专栏与在线课程;③官方文档;④免费交互式练习平台;⑤权威短文与 AI 助教。对比维度:主题覆盖度(范式/反范式/时序/事件四子域逐一打分)、成本、入门友好度、实践性、时效性与维护状态、生态与社区、中文可用性、与个人项目的贴合度。事实核验方式:本会话 WebSearch 共 16 次;WebFetch 抓取 SQLBolt、Select Star SQL、MongoDB 数据建模文档、PostgreSQL 教程与 DDL 章节、Fowler Event Sourcing 共 6 页全部成功;WebReader 抓取极客时间《MySQL 实战 45 讲》官方页与 O'Reilly DDIA 第 2 版书目页成功。
课题画像:
| 属性 | 本课题的设定 |
|---|---|
| 受众 | 个人开发者 / 独立项目作者,不是 DBA 或数仓工程师 |
| 覆盖 | 范式 + 反范式 + 时序数据 + 事件数据,四主题合一的入门取舍指南 |
| 教学方式 | 个人项目案例驱动:用自己要写的 App / 传感器日志 / 埋点来引出建模决策 |
| 成本假设 | 趋近于零(免费、自托管、单机可复现) |
| 语言假设 | 中文为主,代码与术语英文 |
这个画像决定了竞品地图:任何单独一种传统资源都不能同时满足"四主题覆盖 + 案例驱动 + 免费 + 个人项目尺度",这正是本课题的定位空间,也是逐项对比要验证的假设。
2.2 总对比表
评分说明:✔=完整覆盖该主题;△=部分覆盖(如只讲思想不讲取舍,或只覆盖自家产品);✘=基本不覆盖。"贴合"指读者能否把内容直接套进自己的个人项目。其余各列采用高/中/低三档定性评级:高=可直接照做、无额外门槛;中=需要补充材料、翻译或迁移才能用上;低=需要大量改造或基本用不上。时效性按 2026-11-05 截面判断:高=一年内有新版或持续在线更新;中=多年未再版但方法论仍被公认有效;低=内容已明显过时。
本表的主题覆盖刻度(✔/△/✘)与 §2.4 的星级(★~★★★★★)是两套刻度:前者衡量"该子域的知识是否在这份资源里",后者衡量"放进那个场景能不能直接抄"。大致换算:✔ ≈ ★★★★–★★★★★,△ ≈ ★★–★★★,✘ ≈ ★;但覆盖≠好用,语境不匹配照样低星——例如 IBM 短文对范式是 ✔(速查级覆盖),在场景 A 的完整建模决策里只值 ★★★★;DDIA 2e 的时序是 △(散落在存储引擎章节),到场景 B 就无法直接照做。
| 竞品(类别) | 范式 | 反范式 | 时序 | 事件 | 成本 | 入门友好 | 实践性 | 时效性 | 中文 | 贴合 |
|---|---|---|---|---|---|---|---|---|---|---|
| DDIA 2nd ed(书) | △ | ✔ | △ | ✔ | ~$70 / O'Reilly 订阅 | 低(中级起) | 中 | 高(2026-02 新版) | 英文(有旧版中译) | 中 |
| Database Design for Mere Mortals 4e(书) | ✔ | △ | ✘ | ✘ | 印刷/电子 ~$53+ | 高 | 中 | 中(25 周年版) | 英文 | 中 |
| Kimball Toolkit 3e(书) | ✘ | ✔(分析侧) | △ | △ | ~$19–70 | 中 | 高 | 中(2013) | 英文(有中译) | 低(个人项目尺度偏大) |
| 《大数据之路》(1/2)(书) | ✘ | ✔ | △ | △ | 人民币纸书价 | 中 | 高 | 中(第 2 部 2025-03) | ✔ | 低(公司级数仓尺度) |
| 极客时间《MySQL 实战 45 讲》(专栏) | △ | △ | ✘ | ✘ | ¥68(划线 ¥199) | 中 | 高 | 中(已完结) | ✔ | 中 |
| Coursera Duke SQL 专项(课程) | △ | △ | ✘ | ✘ | 旁听免费 / 证书付费 | 高 | 高 | 高 | 英文(有字幕) | 中 |
| DataCamp Premium(订阅课程) | △ | △ | △ | ✘ | ~$28/月按年付(约 $330/年) | 高 | 高 | 高 | 英文 | 中 |
| PostgreSQL 官方文档(文档) | △ | △ | △ | ✘ | 免费 | 中 | 中 | 高(PG18 在线版) | 英文(社区中译) | 高 |
| MongoDB Data Modeling 文档(文档) | △ | ✔ | △ | △ | 免费 | 高 | 高 | 高 | 英文(社区中译) | 高 |
| InfluxDB 3 / Tiger Data(Timescale)/ ClickHouse 文档(文档) | ✘ | △ | ✔ | △ | 免费 | 中 | 高 | 高 | 英文 | 高(限自家产品) |
| SQLBolt(交互练习) | ✘ | ✘ | ✘ | ✘ | 免费 | 极高 | 高 | 高 | 英文 | 低(不教建模) |
| Select Star SQL(交互练习) | ✘ | ✘ | ✘ | ✘ | 免费 | 极高 | 高 | 中 | 英文 | 低(不教建模) |
| freeCodeCamp 关系数据库认证(交互练习) | △ | ✘ | ✘ | ✘ | 免费(含认证) | 高 | 高 | 高(V9 为 2025-12 新版) | 英文/部分社区中文 | 中 |
| IBM / Fowler 等权威短文(短文) | ✔(速查) | ✔(思想) | △ | ✔(模式) | 免费 | 高 | 低 | 中 | 英文 | 中 |
| AI 助教(LLM 对话式学习)(新形态) | △ | △ | △ | △ | 免费~订阅 | 极高 | 视提问而定 | 即时 | ✔ | 高(可按项目定制) |
| 本课题 | ✔ | ✔ | ✔ | ✔ | 免费 | 高 | 高(案例驱动) | 截面交付 | ✔ | 高 |
2.3 五类竞品逐项评述
① 经典书籍:深度最高,但四主题从不"打包"。
- 《Designing Data-Intensive Applications》第 2 版(Martin Kleppmann & Chris Riccomini,O'Reilly,2026 年 2 月,672 页;据 O'Reilly 书目页,实抓)是唯一与本课题四主题大面积重叠的单本资源:第 3 章 "Data Models and Query Languages" 直接包含 *Normalization, Denormalization, and Joins* 与 *Event Sourcing and CQRS* 两节,第 12 章 "Stream Processing" 讲事件流。但它定位 "Intermediate to advanced"(书目页原文),672 页对只想给个人项目建几张表的读者明显过重;时序数据建模也只是散落在存储引擎讨论中,不是独立章节。结论:能力上限最高、上手成本也最高的竞品,适合作为"下一本书"而非入门书。
- 《Database Design for Mere Mortals》第 4 版(25 周年版)(Michael J. Hernandez,Pearson;据 Pearson 与 O'Reilly 图书页,来自搜索摘要):从规划、表、字段、键、关系、业务规则到视图的通俗逻辑设计教程,是范式主题公认最平易的入门书。局限同样明显:完全停留在关系库逻辑设计层,反范式只在少数段落出现,时序与事件主题空白。结论:范式子域的最强单点竞品。
- 《The Data Warehouse Toolkit》第 3 版(Kimball & Ross,Wiley,2013;据 Amazon 列表,来自搜索摘要):维度建模(星型模型)的权威——而星型模型本质上就是分析场景的反范式。1996 年初版奠定方法论(见 §1.3 阶段二),2013 年后未再版,且案例全部是企业数仓(超市、订单、医院),对个人项目尺度偏大。结论:反范式子域的思想源头,但需要读者自行"缩编"。
- 《大数据之路:阿里巴巴大数据实践》与《大数据之路 2》(据《大数据之路2》发布消息、掘金书评,来自搜索摘要):中文世界里反范式落地(数仓分层、维度设计、事实表设计)最好的工业视角,第 2 部于 2025 年 3 月上市、时效尚可。但它是公司级平台经验的总结,个人项目读者借鉴时需要大量"降维"。结论:中文反范式思想的最佳参考书,案例尺度不匹配。
② 付费专栏与在线课程:体验好、覆盖窄。
- 极客时间《MySQL 实战 45 讲》(林晓斌/丁奇,前腾讯云数据库负责人;据官方页面,实抓):已完结、共 49 讲、22.5 万人已学、到手价 ¥68(划线价 ¥199),主线是事务、索引、锁等 MySQL 内核原理,36 个痛点问题 + 100+ 手绘图。它是数据库"引擎视角"的顶级中文课,但建模不是主线:范式、时序、事件三个子域基本不覆盖。结论:本课题在中文市场声量最大的"隔壁竞品"——视角互补而非替代:先懂引擎原理,再做建模取舍,两者拼起来才完整。
- Coursera / Duke "Excel to MySQL" 专项(据 专项页、课程页,来自搜索摘要):大学式数据库设计教学(ER 图、多表设计、JOIN),体系完整、有作业,证书付费、旁听政策以课程页为准。覆盖止步于关系库设计,时序与事件主题缺失。结论:课堂体验最好,但节奏以周为单位,个人项目作者常在中途流失。
- DataCamp Premium(据 datacamp.com/pricing,来自搜索摘要):约 $28/月按年计付(≈$330/年),学生计划约 $164/年;交互式刷题体验佳、SQL 轨道齐全。对本课题四个主题只有 SQL 语言层与部分数据工程轨道的间接覆盖,且订阅制成本在五类竞品中最高。结论:成本最高、建模理论覆盖最浅的竞品。
③ 官方文档:免费、权威、最贴近"抄作业",但视角锁死在自家产品。
- PostgreSQL 官方文档:第 2 章 SQL 教程 与 第 5 章 Data Definition(实抓)覆盖建表、约束(主键/外键/排他约束)、分区等 DDL 全景,免费且随版本持续更新(当前 PG18,2026-10 已发布 PG19 RC1)。它回答"怎么建",不回答"该不该范式化"。
- MongoDB Manual "Data Modeling"(manual/data-modeling,实抓):官方原则 "data that's accessed together should be stored together",系统给出 embedding(嵌入,反范式)与 referencing(引用,范式化)的取舍框架,并配有 Schema Design Patterns 与 Anti-Patterns(反模式) 子章节——这是反范式子域免费资源里最权威、最可操作的文本,且思想对关系库同样适用。
- 时序三家的官方文档:InfluxDB 3 的 Schema design 最佳实践(tags/fields/timestamp 数据模型、"query-first schema design");Tiger Data(Timescale)的 TimescaleDB hypertable 文档——
create_hypertable()把普通 PG 表转为按时间自动分块(chunk)的超表,配压缩、连续聚合与保留策略(据文档页与 GitHub 仓库,来自搜索摘要);ClickHouse 的 MergeTree 引擎文档(ORDER BY即主键排序键)与 时序数据实践博客。这三家文档合起来正好是"时序数据建模"子域的全部内容,且互相不可替代——分别代表"宽表引擎 + SQL"(Timescale)、"专用时序模型"(InfluxDB)、"分析列存"(ClickHouse)三种建模世界观。 - 官方文档的共性短板:只讲自家答案,不讲横向取舍。InfluxDB 不会告诉你什么时候该留在 PostgreSQL,MongoDB 不会教你 1NF。取舍恰恰是本课题标题里的核心词。
④ 免费交互式练习平台:语言层体验极佳,建模层为零。
- SQLBolt(sqlbolt.com,实抓):完全免费、无需注册,18 课覆盖 SELECT/JOIN/聚合/INSERT/UPDATE/DDL,外加子查询与集合操作附加课。是"会用 SQL"的最快路径,但不涉及任何建模决策。
- Select Star SQL(selectstarsql.com,实抓):免费、5 章 × 约 30 分钟、以美国死刑司法真实数据集贯穿,CC BY-SA 4.0 开放许可。定位同样是查询能力而非建模。
- freeCodeCamp Relational Databases 认证(据 认证页 与 新版公告,来自搜索摘要):完全免费且连认证都免费,V9 版于 2025 年 12 月上线,5 个项目 + 考试,动手环境为 PostgreSQL。结论:这一类是所有竞品中"入门友好度"最高的,也是本课题最应主动衔接的先修层——本课题不与它们竞争,而是接在它们后面。
⑤ 权威短文与 AI 助教:免费速查与新型变量。
- IBM《What Is Database Normalization?》(ibm.com/think/topics/database-normalization,来自搜索摘要):1NF/2NF/3NF 的免费速查短文,范式子域"五分钟版"。
- Martin Fowler 的 Event Sourcing 与 CQRS bliki(Event Sourcing,实抓;CQRS):把事件溯源定义为 "Capture all changes to an application state as a sequence of events",明确指出它不是自然的选择、适用于审计日志(会计系统)、调试重放、事件驱动架构等场景——这正是"事件数据取舍"子域的思想锚点,而且 Fowler 文章对"何时不该用"的强调与本课题的"取舍"立场完全同构。
- AI 助教(定性判断):用 LLM 对话式学习是 2026 年的新变量——它可以按"我的记账 App 有这些字段"即时生成建表方案并解释范式/反范式权衡,定制性极高、边际成本趋零。但两个结构性缺陷使其无法独立成课:其一,答案无固定信源、容易在细节上产生幻觉(本报告的信源声明环节就是反例教学);其二,缺少渐进式课程结构,学习者难以自查"学到哪一步了"。合理用法是把它当"无限耐心的一对一答疑",而不是教学大纲。(此段为定性判断,无单一 URL 可附。)
2.4 三个基准场景:青苔账本的三个功能面(与纵轴案例的映射)
纵轴的青苔账本活在时间轴上;横轴把它按功能切成三个 2026 年的真实场景做"基准测试",检验每类竞品的实际可用性。映射关系:场景 A = 账本本体(案例节点 1、2 的当下版本);场景 B = 电表/体重秤(案例节点 4 的当下版本);场景 C = 博客与自动记账的事件/埋点(案例节点 5 的当下版本)。
场景 A:个人记账 App(SQLite 或 PostgreSQL)
会碰到的建模决策:交易表要不要把"账户名"冗余进来(反范式)还是只存 account_id(范式)?转账必须双边记账,怎么靠范式化保证一致性?月末报表很慢,要不要建月度汇总宽表?
| 竞品 | 适配表现 |
|---|---|
| Mere Mortals 4e | ★★★★★ 范式决策全程对口,正是该书写的内容 |
| IBM 短文 | ★★★★ 五分钟补齐 1NF–3NF |
| DDIA 2e ch3 | ★★★★ Normalization/Denormalization 一节直接回答冗余取舍 |
| MongoDB 文档 | ★★★☆ "accessed together"原则可迁移,但语境是文档库 |
| Kimball / 大数据之路 | ★★ 方法论对,尺度过大 |
| 45 讲 | ★★☆ 帮你理解索引与事务,不回答表怎么分 |
| SQLBolt / Select Star | ★ 会查询,不解决建模 |
结论:场景 A 是关系范式与反范式的标准战场,书籍类竞品表现最好;本课题的价值在于把这几本书的答案压缩成一次可执行的取舍清单(三问卡速查版见附录 A,记账 App 建表 DDL 与取舍清单见附录 B),并配上记账 App 的完整案例。
场景 B:电表 / 体重秤读数日志(树莓派传感器,每分钟 1 条,约 50 万行/年)
会碰到的建模决策:宽表(每个传感器一列)还是长表(每行一条读数)?要不要按时间分区?旧数据怎么压缩/丢弃?查询几乎全是"按传感器 + 时间范围聚合"。
| 竞品 | 适配表现 |
|---|---|
| Tiger Data(Timescale)文档 | ★★★★★ hypertable/连续聚合/保留策略就是为这个场景设计的 |
| InfluxDB 3 文档 | ★★★★★ tags/fields 模型 + query-first schema 直接给答案 |
| ClickHouse 文档 | ★★★★☆ MergeTree ORDER BY (time, sensor_id) 是标准解法,但单机个人项目略重 |
| PostgreSQL 文档 | ★★★★ 原生表分区(DDL §5.11)是不引第三方的折中路线 |
| 其余全部竞品 | ★ 三本书、45 讲、SQLBolt 均不覆盖 |
结论:时序子域是书籍与课程竞品几乎无人覆盖的领域——书籍中只有 DDIA 2e 在存储引擎章节散落谈及(总表计 △),没有一本经典书或主流课程系统教个人开发者"50 万行传感器日志该怎么建模",唯一成体系的知识来源就是三家时序库官方文档,而它们给出三种彼此分歧的建模世界观。表中两家 ★★★★★ 的决胜规则就在量级(三问之③,见 §3.2):50 万行/年的树莓派数据,Tiger Data(Timescale)把答案留在 PostgreSQL 生态内,是"不引入第二套运维"的默认解;InfluxDB 的 tags/fields 模型适合以监控为中心、写多读聚合的独立负载;ClickHouse 留给日增亿级以上的档位。本课题在此子域的横向对比价值最高:把三家的取舍放进同一张表,正是个人项目作者最需要而市场上没有的东西。
场景 C:个人博客 / 小工具的埋点事件流(page_view、sign_up、button_click)
会碰到的建模决策:事件表要不要 append-only?事件属性用固定列还是 JSONB?要不要引入完整的 Event Sourcing?事件名怎么命名才不会半年后失控?
| 竞品 | 适配表现 |
|---|---|
| Fowler Event Sourcing 短文 | ★★★★★ 定义 + 适用/不适用清单,一篇文章就是取舍清单 |
| DDIA 2e ch3/ch12 | ★★★★ Event Sourcing & CQRS 与 Stream Processing 两节 |
| MongoDB 文档(反模式章) | ★★★☆ 事件属性膨胀的反模式警示可迁移 |
| 其余书籍 | ★★ Kimball 事实表思想相关但语境是企业数仓 |
| 全部课程/练习平台 | ★ 无覆盖 |
结论:事件子域与场景 B 同构——经典书只有 DDIA 谈到,课程类竞品(45 讲、Coursera、DataCamp、SQLBolt)全部缺席。本课题"要不要上 Event Sourcing"的答案(通常:不上,用 append-only 事件表就够)恰好与 Fowler 文章立场一致,可以引用其 URL 作为权威背书。
三场景综合:
| 子域 | 对应场景 | 最强竞品 | 本课题的差异化 |
|---|---|---|---|
| 范式 | A | Mere Mortals 4e / IBM 短文 | 把书里的 25 年方法压缩成个人项目尺度的清单 |
| 反范式 | A+C | MongoDB 文档 / DDIA ch3 / Kimball | 三种语境(文档库/分析数仓/OLTP)的冗余决策统一到一张取舍表 |
| 时序 | B | 三家时序库官方文档 | 在彼此分歧的三个官方答案之间做横向裁判 |
| 事件 | C | Fowler 短文 / DDIA ch12 | 给"要不要上 ES"一个个人项目尺度的明确答案 |
2.5 竞争格局五条结论
- 没有全能竞品,但每类竞品在单点上都有优势:DDIA 2e(能力上限)、Mere Mortals(范式通俗度)、MongoDB 文档(反范式可操作性)、三家时序文档(时序权威)、SQLBolt/freeCodeCamp(入门体验)、Fowler 短文(事件模式)、45 讲(中文内核视角)。
- 本课题的生态位是"地图层":四个子域各自的头号竞品都已存在且基本免费,缺的是把它们放在同一张取舍表里、并用个人项目案例串联的中文入门路径。因此正确策略是衔接而非对抗——先修层挂 SQLBolt/freeCodeCamp,深度层外链 DDIA 与 Kimball,时序与事件层逐家引用官方文档。本稿以附录 A(三问卡速查版)与附录 B(青苔账本 2026 建表 DDL 与取舍清单)兑现该路径的可执行部分。
- 两大结构性空档构成课题最大价值:时序与事件两个子域在书籍与课程竞品中几乎无人覆盖,而个人项目(传感器、埋点、日志)恰恰最容易碰到这两个子域。
- 时效风险:竞品中 DDIA 2e(2026-02)与 freeCodeCamp V9(2025-12)刚更新,本报告结论在半年内应保持稳定;Kimball 3e 若出新版、Tiger Data 若再更名,需回刷 §2.3。
- 成本维度上的提醒:对个人项目作者,最贵的不是钱而是"学错粒度"——用企业数仓的方法论(Kimball/大数据之路)建一张 50 万行的个人表,或用 DataCamp 330 美元换来的 SQL 熟练度去做本该 10 分钟完成的范式取舍。本课题把所有竞品的粒度对齐到"一个人的项目",这是横向对比的最终落点。
三、交叉洞察:两轴结合说明了什么
以下四条洞察为本稿新增的综合判断:把纵轴(五十六年怎么走到今天)与横轴(今天谁在教、谁缺席)叠在一起,能得到任何单轴都得不到的结论。
3.1 洞察一:今天的竞品格局,是历史的沉积层
横轴的五类竞品不是随机分布的,它们恰好对应纵轴各时代知识的"固化形态":
- 书籍类沉淀于范式与数仓时代:Mere Mortals 传承的是 Codd/Chen 的 1970s–1980s 逻辑设计传统,Kimball 3e 是 1996 年方法论的 2013 年固化,大数据之路是 2000s–2010s 企业数仓实践的总结。书是慢介质,所以它们覆盖的恰好是已经"定型"了 20 年以上的知识。
- 课程类沉淀于高校与培训体系:Coursera/Duke 教 ER 图与 JOIN——仍是 1976 年 Chen 画法的教学化;45 讲教 MySQL 内核——对应 1990s–2000s OLTP 引擎时代。课程比书更快,但仍以"成熟知识"为前提。
- 官方文档类是 NoSQL/时序/云时代的直接产物:MongoDB 建模章(2009+)、InfluxDB/Timescale/ClickHouse 文档(2010s+)只讲自家答案,因为它们正在打仗,还没到"写成书"的沉淀期。
- 交互练习平台只覆盖 SQL 语言层——因为语言(SQL-92 起就稳定)最适合标准化刷题,而建模决策无法自动判卷。
这条沉积律直接解释了横轴最大的发现——时序与事件两子域,课程类全部缺席,书籍类除 DDIA 2e 外也无人覆盖:不是作者们疏忽,而是这两个子域 2010 年代才成形(§1.3 阶段四、五),知识还在"厂商文档"这一层,尚未完成向书籍和课程的"下沉"——书籍类唯一的例外 DDIA 2e(2026-02)恰是离这两个子域成书最近的一次尝试。历史进度表恰好解释了竞品缺口的位置(横轴先发现缺口、纵轴事后给出解释,而非预言)。(综合判断)
3.2 洞察二:历史的主线变量,就是个人的决策变量
纵轴的主线变量是"查询模式的可预知程度 × 成本曲线"——它解释了五次范式转移,反过来它也就是个人开发者今天做建模决策时唯一需要问的变量。把五十六年压缩成一张三问决策卡(综合判断):
| 三问 | 若答案偏向左 | 若答案偏向右 |
|---|---|---|
| ① 查询模式现在就可预知吗? | 预知(报表/面板固定)→ 放心反范式:物化、宽表、预聚合 | 不可预知 → 保持归一化 + 灵活索引,等形状显现再动 |
| ② 数据的本质是实体、时间还是过程? | 实体 → ER + 范式化 | 时间 → 时序三件套(时间主键前缀/标签分 series/降采样);过程 → append-only 事件表 + 物化视图 |
| ③ 量级多大? | 个人尺度(总量百万行级以内、写入持续低于百行/秒)→ 一个 PostgreSQL 到底(JSONB/Timescale/pgvector 扩展按需加) | 写入爆炸(持续万行/秒以上、单表日增亿级)或多服务规模 → 才轮到 NoSQL/流/湖仓那一格 |
执行顺序(三问的使用规则):三问不是并列的选择题,而是一条有先后的流水线——
- 先问 ②,定形状:数据的本质(实体/时间/过程)决定用哪套建模范式——实体走 ER + 范式化,时间走时序三件套,过程走 append-only 事件表。这一步与名气、时尚无关。
- 再问 ③,定档位:量级决定工具档位,参考值:个人尺度(总量百万行级以内、写入持续低于百行/秒)→ 一个 PostgreSQL 到底;中间档(总量千万至亿行、写入千行/秒级)→ 单机加专用引擎(如 TimescaleDB hypertable;ClickHouse 对个人项目略重);写入爆炸(持续万行/秒以上、单表日增亿级、需要水平分片)→ 才轮到 NoSQL/流/湖仓那一格。
- ① 只作触发器:查询模式可预知只是"允许反范式"的许可条件,不是动手的理由——与建议 3"范式默认开、反范式等触发"一致,等报表真变慢且查询形状固定,才物化宽表/预聚合。
按此顺序,"查询可预知(想反范式)"与"量级小(一个 PG 到底)"同时命中时不再无所适从:②定形状、③定档位、①只在慢了以后触发冗余,三步走完答案唯一。速查版见附录 A。(综合判断)
这张卡的三个格子恰好覆盖纵轴七个阶段的所有答案,也和横轴的最佳适配资源一一对应:问①对应 Mere Mortals/MongoDB 文档/DDIA ch3,问②对应三家时序文档/Fowler 短文,问③对应 PostgreSQL/ClickHouse/InfluxDB 文档。历史给个人项目的最大馈赠是:你不需要记住 56 年,只需要记住这三个问题。
3.3 洞察三:两轴共同的警告——"复杂度税"与"学错粒度"
纵轴结论 4(钟摆的摆锤是复杂度税)与横轴结论 5(最贵的是学错粒度)其实是同一条定律的宏观版与微观版(综合判断):
- 宏观版:Prime Video 把微服务合并成单体省 90% 成本、37signals 回归单库(§1.3 阶段七)——企业为超出问题规模的架构纳税;
- 微观版:用 Kimball 的企业数仓方法论建一张 50 万行的个人表、为个人博客引入完整 Event Sourcing——个人为超出问题规模的知识粒度纳税。
两轴合起来给出一条精确的边界线:架构复杂度应该与数据形状的多样性成正比,而不是与"看起来专业"的程度成正比。青苔账本 2026 年的形态(一个 PostgreSQL + 一个 DuckDB + 一条轻量事件流)之所以是"对的",不是因为它是新潮流,而是因为它的问题规模只值这么多复杂度;同样,一旦你的传感器真到每天亿级点位,三家时序文档里 ClickHouse 那种列存世界观就会变成正解——横轴 §2.4 场景 B 中三家文档"彼此分歧"的表象,在纵轴的时间变量下其实是统一的:它们各自对应不同量级与负载形状下的最优解,矛盾只在你选错尺子时才出现。
3.4 洞察四:"地图层"生态位是历史结构的必然,衔接是唯一正确策略
横轴结论 2 说本课题的生态位是"地图层、衔接而非对抗";纵轴为这个判断补上了结构性理由:四个子域的头号资源分属四个不同时代的产物(1970s 的范式理论、1990s 的维度建模、2010s 的厂商文档、2020s 的 DDIA),它们在时间上从未同框,自然也不会有人把它们放进同一张图。书籍不会替你补厂商文档,文档不会教你理论,课程不知道你个人项目的规模。地图层的空档不是商业巧合,而是知识生产速度差造成的永久性结构缝——这也是"入门类横向综述"类内容长期有效的根本原因。(综合判断)
3.5 对用户的判断与建议
基于两轴证据,给出如下可执行的判断与建议(综合判断,工具与文档均引用 §1/§2 中已核验来源):
总体判断:2026 年个人项目的数据建模,"起步姿势"五十六年没变(一个归一化的 SQL 库),"上限"被一个引擎吃下所有负载的融合潮流大幅抬高(PostgreSQL 系扩展 + DuckDB + 轻量事件流);真正的入门难点不在选库,而在识别自己数据的时间/事件属性并拒绝超尺度的复杂度。
建议清单:
- 起步:一个归一化的 PostgreSQL(或 SQLite)。1985 年的答案在 2026 年依然正确,且 PG 已通过 JSONB(2014)、TimescaleDB、pgvector(2021)吃下文档、时序、向量三种形状——先一体,长痛再拆。
- 三问决策卡:每次加表/加库前过一遍 §3.2 的三问(可预知吗?实体/时间/过程?量级多大?),按"先②定形状、再③定档位、①只作触发器"的顺序执行,量级参考值见附录 A。问完通常会发现什么都不用做。
- 范式默认开,反范式等触发:报表或面板慢了、且查询形状固定了,再物化宽表/预聚合(青苔账本案例节点 2 的教训反着用:不要提前预聚合)。
- 时序看形状:数据一旦是 append-only + 按时间查询 + 要过期,就换时序肌肉——个人尺度优先 PG 原生分区或 TimescaleDB hypertable(场景 B ★★★★★),别一上来就 ClickHouse;InfluxDB 的 tags/fields 模型适合监控类负载。三家文档代表三种世界观,按量级选,不按名气选(参考阈值见附录 A:总量年增百万行级以内留在 PG 或加 hypertable;持续万行/秒以上、单表日增亿级,才轮到 ClickHouse 这类列存引擎)。
- 事件克制:埋点、操作审计日志、自动记账这类"只看流水、不靠重放重建状态"的需求,用 append-only 事件表 + JSONB 属性列就够了;完整 Event Sourcing 留给"必须重放历史重建状态"的场景——需要重放出任意时点余额与报表的会计账本、协作编辑——与 Fowler 的适用清单一致(§2.3 ⑤)。
- 学习路径:SQL 先修挂 SQLBolt / freeCodeCamp(免费、上手最快)→ 用本课题的地图层建立四子域取舍观 → 深度外链按需选:范式补 Mere Mortals,反范式补 MongoDB 文档与 DDIA ch3,时序补三家官方文档,事件补 Fowler 短文,进阶通读 DDIA 2e。AI 助教当答疑陪练,不当大纲。
- 防粒度税自查:如果你正在为个人项目读《大数据之路》或给博客引入 Kafka + Event Sourcing + 微服务数据层,先回到三问卡——大概率是学错粒度了。
- 时效维护:本报告结论稳定期约半年;DDIA 2e(2026-02)与 freeCodeCamp V9(2025-12)为最新竞品基线,Kimball 出新版或 Tiger Data 再更名时回刷横轴 §2.3。
四、参考来源
4.1 纵轴(历史脉络,按阶段)
4.2 横轴(2026-11-05 截面竞品,检索与抓取来源汇总)
(口径与 §2.3 一致:标注"实抓"者为当日 WebFetch/WebReader 全文抓取并核验;其余条目来自当日 WebSearch 搜索摘要。)
书籍类
- DDIA 2nd edition(O'Reilly 书目页,实抓):https://www.oreilly.com/library/view/designing-data-intensive-applications/9781098119058/
- Database Design for Mere Mortals 4e(Pearson):https://www.pearson.com/en-us/pearsonplus/p/9780137459667 ;(O'Reilly 版):https://www.oreilly.com/library/view/database-design-for/9780136788133
- The Data Warehouse Toolkit 3e(Amazon 列表):https://www.amazon.com.au/Data-Warehouse-ToolKit-Third-Dimensional/dp/1118530802
- 《大数据之路 2》上市消息:https://blog.csdn.net/BeiisBei/article/details/146031778 ;《大数据之路》书评(掘金):https://juejin.cn/post/6844903646790942733
课程与专栏类
- 极客时间《MySQL 实战 45 讲》官方页(实抓):https://time.geekbang.org/column/intro/100020801
- Coursera Duke 专项:https://www.coursera.org/specializations/excel-mysql ;课程:https://www.coursera.org/learn/analytics-mysql
- DataCamp 定价:https://www.datacamp.com/pricing ;学生计划:https://www.datacamp.com/pricing/student
官方文档类(均免费)
- PostgreSQL 教程 ch2(实抓):https://www.postgresql.org/docs/current/tutorial-sql.html ;DDL ch5(实抓):https://www.postgresql.org/docs/current/ddl.html
- MongoDB Data Modeling(实抓):https://www.mongodb.com/docs/manual/data-modeling/ ;Best Practices:https://www.mongodb.com/docs/manual/data-modeling/best-practices
- InfluxDB 3 Schema Design:https://docs.influxdata.com/influxdb3/enterprise/write-data/best-practices/schema-design
- Tiger Data(Timescale)hypertable 文档(产品 TimescaleDB):https://www.tigerdata.com/docs/learn/hypertables/understand-hypertables ;GitHub:https://github.com/timescale/timescaledb
- ClickHouse MergeTree:https://clickhouse.com/docs/reference/engines/table-engines/mergetree-family/mergetree ;时序实践博客:https://clickhouse.com/blog/working-with-time-series-data-and-functions-ClickHouse
交互练习与短文类
- freeCodeCamp 认证(V9):https://www.freecodecamp.org/learn/relational-databases-v9 ;新版公告:https://www.freecodecamp.org/news/freecodecamps-new-relational-databases-certification-is-now-live
- SQLBolt(实抓):https://sqlbolt.com
- Select Star SQL(实抓):https://selectstarsql.com
- IBM 数据库规范化短文:https://www.ibm.com/think/topics/database-normalization
- Fowler Event Sourcing(实抓):https://martinfowler.com/eaaDev/EventSourcing.html ;CQRS:https://martinfowler.com/bliki/CQRS.html
五、附录
附录 A:三问卡速查版(打印/置顶用)
判断顺序:先 ② 定形状 → 再 ③ 定档位 → ① 只作触发器。(使用规则详见 §3.2;与 §3.5 建议 3"范式默认开、反范式等触发"一致。)
第 1 步|问②:数据的本质是什么?(定形状)
- 实体 → ER 图 + 范式化(默认开)
- 时间 → 时序三件套:时间为主键前缀、按标签分 series、降采样 + 保留策略
- 过程 → append-only 事件表 + 物化视图
第 2 步|问③:量级多大?(定档位)
| 档位 | 参考量级 | 对应答案 |
|---|---|---|
| 个人尺度 | 总量百万行级以内,写入持续低于百行/秒 | 一个 PostgreSQL 到底(JSONB / TimescaleDB / pgvector 按需加,SQLite 亦可) |
| 中间档 | 总量千万至亿行,或写入千行/秒级 | 单机加专用引擎:TimescaleDB hypertable(ClickHouse 对个人项目略重) |
| 写入爆炸 | 持续万行/秒以上、单表日增亿级、需要水平分片 | 才轮到 NoSQL / 流 / 湖仓那一格(Dynamo/Cassandra/Kafka 思路),或分布式 ClickHouse/列存集群 |
典型例子对号入座:青苔账本全年记账数万条(个人尺度);场景 B 的传感器每分钟 1 条 ≈ 50 万行/年(个人尺度);传感器真到每天亿级点位(写入爆炸 → ClickHouse 列存世界观变成正解,见 §3.3)。
第 3 步|问①:查询模式现在就可预知吗?(只作触发器)
- 可预知 → 只是"允许反范式"的许可条件:等报表真变慢且查询形状固定,再物化宽表/预聚合
- 不可预知 → 保持归一化 + 灵活索引,等形状显现再动
常见误用:①③同时命中(查询可预知 + 量级小)→ 仍按顺序走:②定形状、③定档位,①只决定"何时开始冗余";问完大概率是什么都不用做(建议 2)。
附录 B:青苔账本 2026 建表 DDL 与取舍清单
形态即案例节点 7:一个 PostgreSQL(账本 + JSONB 收据 + TimescaleDB 时序 + pgvector 检索)+ 一个 DuckDB(本地分析 Parquet)+ 一条轻量事件流(CDC 到下游物化视图)。以下 DDL 为可运行的最小示意(PostgreSQL 18 + TimescaleDB + pgvector,术语见附录 C)。
① 账本与博客:范式默认开(场景 A)
CREATE TABLE accounts (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
type TEXT NOT NULL CHECK (type IN ('cash','bank','card','virtual'))
);
CREATE TABLE categories (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
kind TEXT NOT NULL CHECK (kind IN ('income','expense'))
);
-- 交易头 + 双边分录:转账 = 两条分录同一事务写入,靠外键与 CHECK 保证借贷相抵
-- 取舍:不冗余账户名/分类名(范式),改名只改一处
CREATE TABLE transactions (
id SERIAL PRIMARY KEY,
occurred_at TIMESTAMPTZ NOT NULL DEFAULT now(),
note TEXT
);
CREATE TABLE transaction_entries (
id SERIAL PRIMARY KEY,
transaction_id INT NOT NULL REFERENCES transactions(id),
account_id INT NOT NULL REFERENCES accounts(id),
category_id INT REFERENCES categories(id),
direction TEXT NOT NULL CHECK (direction IN ('in','out')),
amount NUMERIC(12,2) NOT NULL CHECK (amount <> 0)
);
-- 博客(案例节点 3 回归 PG 的那一半):两张标准范式表
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
slug TEXT NOT NULL UNIQUE,
title TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE TABLE comments (
id SERIAL PRIMARY KEY,
post_id INT NOT NULL REFERENCES posts(id),
author TEXT NOT NULL,
body TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);② 报表:反范式等触发(触发器①)
-- 只有当"按月×分类汇总"被反复查询且真的变慢了,才建物化视图(案例节点 2 的教训反着用)
CREATE MATERIALIZED VIEW monthly_category_spend AS
SELECT date_trunc('month', t.occurred_at) AS month,
e.category_id,
sum(e.amount) FILTER (WHERE e.direction = 'out') AS outflow,
sum(e.amount) FILTER (WHERE e.direction = 'in') AS inflow
FROM transaction_entries e
JOIN transactions t ON t.id = e.transaction_id
GROUP BY 1, 2;
-- 刷新:REFRESH MATERIALIZED VIEW monthly_category_spend;(定时或报表前手动)③ 传感器时序:时序三件套(场景 B)
CREATE EXTENSION IF NOT EXISTS timescaledb;
CREATE TABLE sensor_readings (
ts TIMESTAMPTZ NOT NULL,
sensor_id TEXT NOT NULL, -- 电表 / 体重秤
value DOUBLE PRECISION NOT NULL
);
SELECT create_hypertable('sensor_readings', 'ts'); -- 按时间自动分块
-- 降采样:连续聚合,按小时增量维护
CREATE MATERIALIZED VIEW readings_hourly
WITH (timescaledb.continuous) AS
SELECT time_bucket('1 hour', ts) AS hour,
sensor_id, avg(value) AS avg_value,
min(value) AS min_value, max(value) AS max_value
FROM sensor_readings
GROUP BY 1, 2;
-- 保留策略:明细只留两年,到期自动清理,不手写 DELETE
SELECT add_retention_policy('sensor_readings', INTERVAL '2 years');④ 事件流:事件克制(场景 C)
-- append-only 事件表:只插不改不删;属性进 JSONB,等知道要查什么再加 GIN 索引
CREATE TABLE app_events (
id BIGSERIAL PRIMARY KEY,
occurred_at TIMESTAMPTZ NOT NULL DEFAULT now(),
event_name TEXT NOT NULL, -- page_view / sign_up / entry_auto_created
payload JSONB NOT NULL DEFAULT '{}'
);
-- 完整 Event Sourcing 不上:账本状态以分录表为准,无需重放事件重建;
-- 下游报表由 CDC(如 Debezium)把变更同步成物化视图,避免双写不一致(案例节点 5)⑤ 原始收据与语义检索:一个库吃下文档与向量
-- 结构未定的原始收据先整包进 JSONB,解析稳定后再提字段(PG 9.4+,案例节点 7)
CREATE TABLE raw_receipts (
id SERIAL PRIMARY KEY,
txn_id INT REFERENCES transactions(id),
raw JSONB NOT NULL
);
CREATE INDEX ON raw_receipts USING gin (raw); -- GIN:支持"含某键/某值"类查询
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE assistant_docs ( -- "记账助手"语义检索
id SERIAL PRIMARY KEY,
content TEXT NOT NULL,
embedding vector(1536)
);取舍清单(一页版)
| 决策点 | 选择 | 一句话理由 |
|---|---|---|
| 交易表要不要冗余账户名 | 不冗余,存 account_id | 范式默认开:改名只改一处 |
| 转账一致性靠什么 | 同一事务写两条分录 + 外键/CHECK | 让库保证,不靠应用自觉 |
| 月末报表慢怎么办 | 先索引;查询形状固定后再建物化视图 | 反范式等触发,不提前预聚合 |
| 传感器数据放哪 | 同一个 PG 的 hypertable | 50 万行/年犯不着第二套运维(决胜规则见 §2.4 场景 B) |
| 旧读数怎么清 | 保留策略自动过期 | append-only 数据别手写 DELETE |
| 事件要不要上 Event Sourcing | 不上,append-only 事件表就够 | 账本状态以分录为准,无需重放重建 |
| 事件属性怎么存 | JSONB 列 + 按需加 GIN 索引 | 半年后才知道要查什么 |
| 什么时候才拆库 | 日增亿级 / 持续万行/秒以上 | 按量级选,不按名气选(附录 A 档位表) |
附录 C:术语表(按文中首现顺序的白话一句话)
| 术语 | 白话解释 |
|---|---|
| append-only | 只追加、不修改、不删除的写入方式——日志、事件流、时序读数的天然形态。 |
| series(时间线) | 时序数据库里"同一来源的连续读数":某一只电表的全部读数就是一条 series,靠标签(如 sensor_id)区分。 |
| 降采样(downsampling) | 把高频原始读数按时间窗口压成低频汇总(如每分钟一条 → 每小时一条均值),给老数据省空间。 |
| 保留策略(retention policy) | 数据到期自动清理的规则,例如"明细只留两年",替代手写 DELETE。 |
| 写放大(write amplification) | 实际写入磁盘的数据量远大于应用写入量——每插一行都要同步更新所有索引,高频写入时被索引拖垮。 |
| TTL(Time To Live) | 数据的"保质期",到期自动删除;监控与指标类数据最常见的过期方式。 |
| CDC(Change Data Capture,变更数据捕获) | 盯住数据库自己的事务日志,把每一行变更转成事件发给下游;下游不用"双写"也能与主库保持同步。 |
| 物化视图(materialized view) | 把一个查询的结果实际存成表,查询时直接读现成答案;代价是底层数据变了之后要手动或定时刷新。 |
| ELT(Extract-Load-Transform) | 先把原始数据原样搬进仓库,再用 SQL 做转换;与传统"先转换再装载"的 ETL 顺序相反。 |
| GIN 索引 | PostgreSQL 的倒排索引,专治"一个字段里装了很多东西"的查询——比如 JSONB 里有没有某个键、数组里含不含某个值。 |
| 向量化执行 | 查询引擎一次处理一整批(一列向量)数据而非逐行处理,是列存分析数据库快的关键之一。 |
| hypertable | TimescaleDB 的核心抽象:一张逻辑上的普通 PG 表,背后按时间自动切成小块(chunk);一条 create_hypertable() 即可变出来。 |
| 连续聚合(continuous aggregate) | TimescaleDB 的自动预聚合:按小时/天等时间窗口持续维护汇总结果,新数据一到自动增量更新。 |
*本综合稿由纵轴章(2026-11-05-数据建模入门-vertical.md)与横轴章(2026-11-05-数据建模入门-horizontal.md)综合而成,未验证细节已在两章原文用保守措辞处理并随文标注。本稿为最终稿:已按 2026-11-05 独立审读意见(8 条)逐条修订,新增附录 A(三问卡速查版)、附录 B(青苔账本 2026 建表 DDL 与取舍清单)与附录 C(术语表)。*