跳转到内容

Codd 1970 — 关系模型奠基

是什么

Codd 1970 是 IBM 数学家 Edgar F. Codd 在 1970 年 6 月发表在 CACM 上的一篇 11 页论文。它提出一个看起来朴素到不可能的主张:数据应该用”数学集合 + 表”来表示,找数据应该用”描述要什么”来写,不是用”按图爬路径”来写

日常类比:

  • 1970 年以前的数据库长得像 组织架构图(层次模型)或 地铁线路图(网状模型)。员工想找老板的部门要先沿”指针”一层一层爬上去;找一个产品的所有客户要顺着关系链跳。
  • Codd 提出:数据其实就像 一摞 Excel 表。员工表、部门表、订单表,每张表是一个”关系”。要查”高薪员工”不用爬路径,就一句话:“给我员工表里 salary > 50000 的所有行”。

这套思想就是 postgresql / mysql / Oracle / SQL Server 等所有关系数据库的源头。

为什么重要

不理解 Codd 1970,下面这些事都没法解释:

  • 为什么 SQL 的语法是 SELECT ... FROM ... WHERE ... —— 这正是 Codd 主张的”描述要什么、不是怎么找”的语法化
  • 为什么 mysql / postgresql 加列、加索引、改存储引擎,应用层完全不用改代码 —— Codd 提出的”数据独立性”概念
  • 为什么 1981 年 Codd 拿了图灵奖 —— 这篇论文是核心成就之一
  • 为什么现代分布式数据库(cockroachdb / spanner)即便存储改成了”全球分片+共识协议”,对外接口还是关系模型 + SQL —— 关系代数这套数学框架太稳

核心要点

Codd 论文的三个核心概念:

  1. 关系(Relation):一张表就是一个数学集合。每行是一个 tuple(元组),每列是一个 attribute(属性)。集合性质决定了行无序、行不重复——这跟”链表 / 树”完全不同。

  2. 关系代数(Relational Algebra):六个基本运算——选择 σ(筛行)、投影 π(筛列)、并 ∪、差 −、积 ×、连接 ⋈。任何复杂查询都可以拆成这六个的组合。这就是 SQL 的数学底座。

  3. 规范化(Normalization):通过拆表消除冗余和”更新异常”。比如把”员工 + 部门”的大表拆成两张小表,用 dept_id 关联。Codd 在后续论文(1971、1974)才把 1NF / 2NF / 3NF 完整定义出来,但 1970 这篇已经给了思想雏形。

第四个隐性贡献:数据独立性——应用程序看到”逻辑表”,存储层换硬盘换格式,应用一行不用改。这是当时最革命的卖点。

实践案例

案例 1:一张关系长什么样

Employee (id, name, salary, dept_id)
---------+--------+---------+---------
1 Alice 80000 10
2 Bob 45000 10
3 Carol 120000 20

每行是一个员工 tuple,整张表是一个 Employee 关系。注意:

  • 列名 + 类型固定(id 是整数、name 是字符串)
  • 行无内在顺序(数据库可以按任意顺序存)
  • 不允许两行完全一样(集合性质)

案例 2:用关系代数查”高薪员工”

数学写法:

σ (salary > 50000) (Employee)

读作”对 Employee 表做选择,条件是 salary > 50000”。

SQL 等价写法(1974 年才被发明):

SELECT * FROM Employee WHERE salary > 50000;

—— SQL 几乎是关系代数的语法糖。SELECT 对应投影 π,FROM 对应关系名,WHERE 对应选择 σ,JOIN 对应连接 ⋈。

案例 3:连接两张表

要查”每个员工 + 他的部门名”:

SELECT e.name, d.dept_name
FROM Employee e JOIN Department d
ON e.dept_id = d.id;

关系代数:

π (name, dept_name) (Employee ⋈ Department)

整个数据库引擎要做的事,就是把这种”声明式描述”翻译成”具体怎么扫硬盘 / 怎么用索引 / 怎么并行”的物理计划。这步翻译叫 查询优化器,是关系数据库 50 年来最难的工程。

踩过的坑

  1. NULL 不是值:Codd 的关系模型最初没考虑 NULL;后来加了”三值逻辑”(true / false / unknown),让 SQL 的 WHERE col = NULL 永远返回空——很多新人栽过。

  2. 关系不允许重复行,但 SQL 允许:现实里 SQL 的 SELECT 默认返回 multiset(可重集),不是真正的集合。这是工程妥协,跟 Codd 原始定义有偏差。SELECT DISTINCT 才回到真正的集合语义。

  3. 过度规范化反而慢:3NF / BCNF 把表拆得很细,查的时候要 JOIN 很多张表。OLAP 场景往往故意”反规范化”(把列宽展开),换查询速度。Codd 的纯洁主义需要工程权衡。

  4. 关系代数表达不了递归:算”组织架构里 Alice 下面所有人”——基本关系代数搞不定,要等 1999 年 SQL 加 WITH RECURSIVE 才解决。

适用 vs 不适用

适用

  • 结构化数据 + 强一致性场景(财务、订单、库存)
  • 复杂多表关联查询(电商、ERP、CRM)
  • 需要事务(ACID)保证

不适用

  • 半结构化 / 文档数据(用 MongoDB 这种 json 文档库更顺)
  • 图数据 + 多跳查询(社交网络、知识图谱用 Neo4j 这种图库)
  • 时序数据(IoT、监控指标用 InfluxDB / TimescaleDB)

注意”不适用”也在变:postgresql 加了 JSONB,把文档查询塞进关系模型;cockroachdb / spanner 把分布式塞进关系模型。Codd 的框架显示出极强的吸纳能力。

历史小故事(可跳过)

  • 1968 年:Codd 在 IBM 圣何塞研究中心,看不惯当时主流的 IMS(层次数据库)和 CODASYL(网状)—— 程序员要写一堆指针操作,存储一改全部应用都得重写。
  • 1969 年:Codd 写了一份 IBM 内部技术报告 RJ-599,第一次提出关系模型。IBM 高层不想动 IMS 这棵摇钱树,把报告压住了。
  • 1970 年 6 月:Codd 直接投到 CACM(ACM 通讯),论文公开发表。这是 IBM 内部斗争的转折点。
  • 1973 年:IBM 圣何塞启动 System R 项目,Berkeley 同时启动 Ingres 项目,两条线独立验证关系模型可工程化。
  • 1974 年:System R 团队的 Donald Chamberlin 和 Raymond Boyce 发明 SEQUEL(后改名 SQL),把关系代数语法化。
  • 1979 年:Larry Ellison 读了 IBM 论文,抢在 IBM 商业化之前发布 Oracle V2(V1 内部跳过),关系数据库进入商业市场。
  • 1981 年:Codd 获图灵奖,颁奖词专门提了 1970 这篇论文。
  • 1986 年:ANSI SQL 标准发布,SQL 成为关系数据库的通用接口。
  • 2010s 至今cockroachdb / spanner 等 NewSQL 把关系模型 + SQL 接到分布式共识上,证明 Codd 的框架在云时代仍然站得住。

学到什么

  1. 声明式 vs 命令式 —— Codd 让数据查询从”怎么找”变成”找什么”,背后是数学(集合论 + 一阶逻辑)的胜利。这个思路后来扩散到 React(声明式 UI)、Kubernetes(声明式编排)、Terraform(声明式基础设施)。

  2. 抽象的力量 = 解耦 = 长寿 —— 关系模型把”逻辑”和”物理存储”分开。50 年来硬盘从机械改成 SSD、单机改成分布式,应用层 SQL 改的极少。

  3. 数学不是装饰 —— Codd 是数学家,他用集合论严格定义了数据库该怎么操作。事后看,正是这层数学把”野生设计”挡在外面,让关系数据库经得起时间。

  4. 理论 → 工程 → 商业的 10 年节奏:1970 论文 → 1973 原型 → 1979 商业化。这个节奏在 postgresql、Linux、深度学习里反复出现。

延伸阅读

关联

  • postgresql —— 关系模型最忠实的工业实现
  • mysql —— 关系模型在互联网时代的主力
  • cockroachdb —— 关系模型 + 分布式共识的现代演化
  • spanner —— 关系模型在 Google 全球规模上的延展

反向链接

  • bernstein-1981-cc —— Bernstein 1981 并发控制综述 — 把分布式数据库的 20+ 算法整成两条主线
  • cascades-1995 —— Cascades 1995 — 用规则 + Memo 拼装一个可扩展查询优化器
  • cockroachdb —— CockroachDB — 分布式 SQL 数据库
  • codd-1979-extending —— Codd 1979 — 给关系模型补上”语义”
  • cstore-2005 —— C-Store — 把数据按列存,分析查询直接快十倍
  • dewitt-gray-1992 —— DeWitt-Gray 1992 — 并行数据库取代专用机的宣言
  • eswaran-1976 —— Eswaran 1976 — 串行化与谓词锁的源头
  • gray-1981-transaction —— Gray 1981 — 把”事务”提升为通用抽象
  • ingres-1976 —— INGRES 1976 — Berkeley 平行实现的关系数据库
  • machanavajjhala-l-diversity-2007 —— l-多样性 — k-匿名之后的隐私保护
  • mysql —— MySQL — 全球最流行关系数据库
  • pandas —— pandas — Python 表格数据事实标准
  • postgresql —— PostgreSQL — 工业级关系数据库
  • sequel-1974 —— SEQUEL 1974 — 让数据库”听懂”近似英语的查询
  • spanner —— Spanner — 全球分布式 SQL 数据库
  • stonebraker-2010-sqlnosql —— Stonebraker 2010 SQL vs NoSQL — 慢的是老实现,不是 SQL
  • sweeney-k-anonymity-2002 —— k-匿名 — 发布数据时让攻击者无法锁定你是谁
  • system-r-1976 —— System R 1976 — 第一个跑起来的关系数据库