知识卡片

读时模式与写时模式的权衡及适用场景

普通读书笔记卡

内容

文档数据库常被称为”无模式”,这个说法有误导性——读取数据的代码通常仍然假定某种 结构,只是这个隐式模式不由数据库强制执行罢了。更准确的说法是”读时模式”(数据的 结构是隐含的,只有读取时才被代码解释)对应传统关系数据库的”写时模式”(模式明确, 数据库确保所有写入的数据都符合该模式)——这组对立很像编程语言里动态类型检查和 静态类型检查的对立,同样存在争议,没有绝对的对错。两者的区别在应用想改变数据格式 时体现得最明显:假如要把”姓名”字段拆成”姓”和”名”两个字段,文档数据库下只需要开始 写入带新字段的新文档,读取旧文档时用代码判断字段是否存在并临时兼容;关系数据库下 则要执行ALTER TABLE加列、再用UPDATE语句批量迁移已有数据——不过这里有个常被 夸大的误解:多数关系数据库执行ALTER TABLE本身只需几毫秒(MySQL是明显的例外, 它执行该操作时会复制整张表,大表可能停机几分钟到几小时),真正慢的是对大表做 UPDATE重写每一行,而这个问题即使在关系数据库里也有和文档数据库同样的解法:把 新列默认设为NULL,读取时再按需填充。读时模式在两种情况下更有优势:一是集合里存在 许多不同类型的对象,把每种类型单独建表不现实;二是数据结构由外部系统决定、且这个 外部系统随时可能变化、不受你控制。反过来,如果所有记录都具有相同结构,写时模式的 模式约束就是一种有效的机制而非负担。

参考来源

- 位置:《数据密集型应用系统设计》第二章《数据模型与查询语言》"文档模型中的模式 灵活性"(源文件:_epub-src/ch2_split_001.html) - 结论依据:原文区分读时模式与写时模式,说明两者在应用想改变数据格式时的处理差异 (文档数据库直接写新字段并用代码兼容旧文档、关系数据库需要ALTER TABLE和UPDATE 迁移),并指出多数关系数据库ALTER TABLE本身很快、MySQL是例外,以及读时模式在 异构数据或数据结构由外部系统决定时更有优势,直接支撑本卡片结论。 - 原始内容:一个更精确的术语是读时模式……相应的是写时模式……读时模式类似于编程 语言中的动态(运行时)类型检查,而写时模式类似于静态(编译时)类型检查……大多数 关系数据库系统可在几毫秒内执行ALTER TABLE语句。MySQL是一个值得注意的例外……当 由于某种原因(例如,数据是异构的)集合中的项目并不都具有相同的结构时,读时模式 更具优势。