知识卡片

文档数据库(MongoDB):用no-schema换取灵活性,但丢失事务与join

普通读书笔记卡

内容

[[NoSQL的本质定位是针对关系数据库四大缺陷的补充方案]]里文档数据库针对的是”schema强约束”这个缺陷,核心特点是no-schema——可以自由存储和读取任意结构的数据,大多数文档数据库(以MongoDB为代表)用JSON(或BSON)作为存储格式,因为JSON是自描述的,读取一个JSON里不存在的字段只会得到空值,不会像SQL那样直接报错。no-schema带来三个明显优势:新增字段无须像关系数据库那样先执行DDL修改表结构,代码直接读写即可;历史数据即使没有新字段也不会出错,只需在代码里做兼容处理;能很自然地存储复杂嵌套数据——比如一个用户信息里既有姓名性别这类简单字段,又有”爱好”这种列表、”地址”这种嵌套结构、”学历”这种带时间区间的对象数组,用关系数据库要拆成基本信息、爱好、地址、学历四张表分别设计,用文档数据库一个JSON就能完整描述清楚。这个特性特别适合商品属性差异极大的电商和游戏这类场景——冰箱和笔记本电脑的属性字段完全不同,甚至同类商品(如LCD和LED显示器)的参数指标也不一样,用关系数据库存储会很麻烦,用文档数据库存储和扩展新属性都简单得多。这些优势的代价是不支持事务:比如用MongoDB存储商品库存,创建订单时要先扣库存再建订单,这本该是一个事务操作,但MongoDB无法保证这个操作的事务性,异常情况下完全可能出现库存被扣了、订单却没建成的不一致状态,因此对事务要求严格的业务场景不适合用文档数据库。另一个代价是无法实现关系数据库式的join——比如要查询”购买了苹果笔记本用户中的女性用户”,关系数据库一次join就能完成,文档数据库只能分两次查:先查出购买了苹果笔记本的用户,再从中筛选女性用户,和分库分表后失去join能力面临的是同一类问题。

参考来源

- 位置:《从零开始学架构》第16讲《高性能NoSQL》"文档数据库"(源文件:_epub-src/OEBPS/text00001.html) - 结论依据:原文说明"文档数据库最大的特点就是 no-schema,可以存储和读取任意的数据",列出新增字段简单/历史数据不出错/可存储复杂数据三点优势并给出用户信息JSON示例,同时说明"文档数据库 no-schema 的特性带来的这些优势也是有代价的,最主要的代价就是不支持事务……文档数据库另外一个缺点就是无法实现关系数据库的 join 操作",直接支撑本卡片结论。 - 原始内容:文档数据库最大的特点就是 no-schema,可以存储和读取任意的数据……使用 MongoDB 来存储商品库存……如果用 MongoDB 来实现,就无法做到事务性……文档数据库另外一个缺点就是无法实现关系数据库的 join 操作。