知识卡片
读时模式与写时模式的权衡及适用场景
内容
文档数据库常被称为”无模式”,这个说法有误导性——读取数据的代码通常仍然假定某种
结构,只是这个隐式模式不由数据库强制执行罢了。更准确的说法是”读时模式”(数据的
结构是隐含的,只有读取时才被代码解释)对应传统关系数据库的”写时模式”(模式明确,
数据库确保所有写入的数据都符合该模式)——这组对立很像编程语言里动态类型检查和
静态类型检查的对立,同样存在争议,没有绝对的对错。两者的区别在应用想改变数据格式
时体现得最明显:假如要把”姓名”字段拆成”姓”和”名”两个字段,文档数据库下只需要开始
写入带新字段的新文档,读取旧文档时用代码判断字段是否存在并临时兼容;关系数据库下
则要执行ALTER TABLE加列、再用UPDATE语句批量迁移已有数据——不过这里有个常被
夸大的误解:多数关系数据库执行ALTER TABLE本身只需几毫秒(MySQL是明显的例外,
它执行该操作时会复制整张表,大表可能停机几分钟到几小时),真正慢的是对大表做
UPDATE重写每一行,而这个问题即使在关系数据库里也有和文档数据库同样的解法:把
新列默认设为NULL,读取时再按需填充。读时模式在两种情况下更有优势:一是集合里存在
许多不同类型的对象,把每种类型单独建表不现实;二是数据结构由外部系统决定、且这个
外部系统随时可能变化、不受你控制。反过来,如果所有记录都具有相同结构,写时模式的
模式约束就是一种有效的机制而非负担。
参考来源
- 位置:《数据密集型应用系统设计》第二章《数据模型与查询语言》"文档模型中的模式
灵活性"(源文件:_epub-src/ch2_split_001.html)
- 结论依据:原文区分读时模式与写时模式,说明两者在应用想改变数据格式时的处理差异
(文档数据库直接写新字段并用代码兼容旧文档、关系数据库需要ALTER TABLE和UPDATE
迁移),并指出多数关系数据库ALTER TABLE本身很快、MySQL是例外,以及读时模式在
异构数据或数据结构由外部系统决定时更有优势,直接支撑本卡片结论。
- 原始内容:一个更精确的术语是读时模式……相应的是写时模式……读时模式类似于编程
语言中的动态(运行时)类型检查,而写时模式类似于静态(编译时)类型检查……大多数
关系数据库系统可在几毫秒内执行ALTER TABLE语句。MySQL是一个值得注意的例外……当
由于某种原因(例如,数据是异构的)集合中的项目并不都具有相同的结构时,读时模式
更具优势。