抖音技术能力大揭密!钜惠大礼、深度体验,尽在火山引擎增长沙龙,就等你来! 立即报名>> 了解详情
写点什么

EMC 颜开纵论 NoSQL 文档数据库反模式

2013 年 1 月 27 日

SQL 的反模式已经有不少人熟悉,但 NoSQL 是否也有反模式?

在自己的一篇博客文章中,EMC 中国研究院的颜开对 NoSQL 中的文档数据库进行了分析,并提炼出六种反模式。

在文章开头,颜开指出:

好的反模式可以在我们设计 Schema 告诉哪里是陷阱和悬崖。NoSQL 宣传的时候往往宣称是 SchemaLess 的,这会让人误解其不需要设计 Schema。但如果不意识到设计 Schema 的必要,陷阱就在一直在黑暗中等着我们。

接下来,颜开分析了三种主流的 NoSQL 数据库:

  • 文档数据库,以 MongoDB 为代表
  • 列存数据库,以 HBase 为代表
  • 键值数据库,以 Redis 为代表

加上 MySQL,他将这四种开源数据库产品做了比喻和对比:

MySQL——菜刀

尽管其没有什么大的改进,但是新兴的互联网使用的最多的数据库。就像传统的菜刀,结构简单,几百年没有改进。但是不妨碍产生各式各样的刀法,只要有一把,就能胜任厨房里的大部分事务。MySQL 也是一样,核心已经稳定。但是切库,分表,备份,监控,等等手段一应俱全。

MongoDB——瑞士军刀

提供更灵活的 Schema,Capped Collection,异步提交,地理位置索引等五花十色的功能。就像瑞士军刀,不但可以当刀用,还可以开瓶盖,剪指甲。但是他也不比 MySQL 强,因为还缺乏时间的磨砺。一是系统本身的稳定性,二是开发,运维需要更多经验才能流行。

HBase——大象兵

依仗着 Hadoop 的生态环境,可以有很好的扩展性。但是就像象兵一样,使用者需要养一头大象 (Hadoop), 才能驱使它。

Redis——金箍棒

键值存储的代表,功能最简单。提供随机数据存储。就像一根棒子一样,没有多余的构造。但是也正是因此,它的伸缩性特别好。就像悟空手里的金箍棒,大可捅破天,小能成缩成针。

颜开指出 SQL 关系模型的两个弱点:

  • 必须支持 Join:因为数据不能够有重复。所以使用范式的关系模型会不可避免的大量 Join。如果参与 Join 的是一张比内存小的表还好。但是如果大表 Join 或者表分布在多台机器上的话,Join 就是性能的噩梦。
  • 计算与存储耦合:关系模型作为统一的数据模型既可以用于数据分析,也可以用于在线业务。但这两者一个强调高吞吐,一个强调低延时,已经演化出完全不同的架构。用同一套模型来抽象显然是不合适的。

颜开认为:

针对这两个梦魇。文档数据库如 MongoDB 的主要目的是:提供更丰富的数据结构来抛弃 Join 来适应在线业务

……文档数据库并不比关系数据库强大,由于对 Join 的弱支持,功能会弱许多。设计关系模型的时候,通常只需要考虑好数据直接的关系,定义数据模型。而设计文档数据库模型的时候,还需要考虑应用如何使用。因此设计好一个的文档数据库 Schema 比设计关系模型更加的困难。除此之外,由于文档数据库事务的支持也是比较弱,一般 NoSQL 只会提供一个行锁。这也给设计 Schema 更加增加了难度。

接下来,颜开从模型设计部分提炼出六种反模式。

反模式一:惯性思维 / 沿用关系模型

由于文档数据库不支持 Join(包括和外键息息相关的外键约束) 等特性,习惯性的沿用关系模型有的时候会出现问题。需要利用起文档数据库提供的丰富的数据模型来应对。

颜开提出一个例子,指出这个例子存在两个问题:

  1. 存在描述多对多的关系表
  2. 没有区分"一对多关系"和“多对一关系”

颜开提出一个正确使用的场合:

关系型模型是非常成功的数据模型,合理的沿用是非常好的。但是由于文档数据库的特点,需要适当的调整,这样得出的数据模型,尽管性能不是最优,但是有最好的灵活性。并且也有利于和关系数据库转换。

反模式二:处处引用客户端 Join

这样的坏处是:

  1. 手动 Join,麻烦且易出错。
  2. 多次查询。如果引用过多,查询的时候需要多次查询才能查到足够的数据。
  3. 事务处理繁琐。

解决方法是:

在以下三种场合,适当使用内联数据结构。

  1. 使用内联可以解决读性能问题,明显减少 Query 的次数的时候。
  2. 可以简化数据模型,化简表之间的关系,而同时不会影响灵活性的时候。
  3. 事务可以得到简化为单行事务的时候

正确的场合是:

范式化的使用场景,文档数据库会被多个应用使用。由于数据库设计无法估计多个应用现在及将来的查询情况,需要极大的灵活性。在这个时候,使用引用比内联靠谱。

反模式三:滥用内联后患无穷

有四种主要症状:

  • 妨碍到查询的内联
  • 无限膨胀的内联
  • 无法维护的内联
  • 盯死应用的内联

反模式四:在线计算

主要症状:有一些运行时间很长的 Query, 由于有聚合计算,索引也不能解决。随着数据量的增长,逐渐成为性能瓶颈。

坏处有二:

  • 影响用户体验。
  • 影响数据库性能。

解决方案:要权衡聚合操作是否必要,是否需要实时完成。如果务必要,可采取离线模式。如必须实时,则可以新建一个字段,用“incr”这样的操作,在运行的时候,实时聚合结果。如果逻辑比较复杂,或者觉得大量“incr”操作给数据库系统带来了压力,可以使用 Storm 之类的实时数据处理框架。总之,要慎用长查询。

反模式五:把内联 Map 对象的 Key 当作 ID 用

其症状是:

文档数据库支持内联 Map 类型。将其中 Map 的 Key 当作数据库的主键来用。

颜开指出:“这个反模式很容易犯,因为在编程语言中 Map 数据结构就是这么用的。但是对于数据库模型来说,这是不折不扣的反模式。”

主要坏处有二:

  • 无法通过数据库做各种 (><=) 查询。
  • 无法通过索引查询。

解决方案:使用数组 +Map 来解决。。Map 类型中的 Key 是属性名,Value 是属性值。这样的用法是文档数据库数据模型的本意,因此其提供的各种功能才能利用上。否则就无法使用。

反模式六:不合理的 ID

症状:使用 String 甚至更复杂数据结构作为的 ID,或者全部使用数据库提供的自生成 ID

两个坏处是:

  • ID 混乱。
  • 索引庞大,性能低下。

解决方案:

尽量使用有一定意义的字段做 ID,并且不在其他字段中重复出现。不使用复杂的数据类型做 ID,只使用 int,long 或者系统提供的主键类型做 ID。

在文章最后,颜开用一个表格涵盖了所有反模式,读者可点击原文链接查看。

颜开最后说道:

现在关于 NoSQL 数据模型设计模式的讨论才刚刚起步,将来也许会逐渐自成体系。对于列数据库和 Key-Value 的反模式,笔者等到有了足够积累的时候,再和大家分享。

2013 年 1 月 27 日 08:562195
用户头像

发布了 479 篇内容, 共 130.1 次阅读, 收获喜欢 33 次。

关注

评论

发布
暂无评论
发现更多内容

架构师训练营第三周作业

文智

极客大学架构师训练营

架构师训练营第三周作业

邓昀垚

极客大学架构师训练营

第二周-学习总结-框架设计原则

莫森

极客大学架构师训练营

【架构笔记之设计模式】架构师训练营第1期第3周

业哥

极客大学架构师训练营

原创 | 使用JPA实现DDD持久化-O/R阻抗失配(2/2)

编程道与术

Java hibernate DDD JDBC jpa

原创视频 | 架构漫谈—如何创造复杂而有序的软件系统【含课件下载】

编程道与术

Java 编程 架构 软件开发 软件架构

区块链带来的技术创新和变革

CECBC区块链专委会

区块链技术 经济

原创 | 正确区分属性和字段

编程道与术

Java hibernate 编程 软件开发 jpa

原创 | 使用JPA实现DDD持久化-JPA,Hibernate与Spring Data JPA

编程道与术

Java hibernate Spring C Data jpa

LeetCode题解:641. 设计循环双端队列,使用双向链表,JavaScript,详细注释

Lee Chen

LeetCode 前端进阶训练营

联邦计算:不暴露真实数据如何完成合作建模?

小小的一朵云

大数据

c++杂谈4

菜鸟小sailor 🐕

你在开发过程中使用Git Rebase还是Git Merge?

华为云开发者社区

git 华为 管理 代码

架构师训练营第1期第3周作业

业哥

极客大学架构师训练营

腾讯云大数据发布最新产品矩阵,助力企业整合打通海量数据

小小的一朵云

大数据

智能体的奇幻漂流之“成都折叠”篇

脑极体

手把手教你:将 ClickHouse 集群迁至云上

小小的一朵云

大数据 Clickhouse

第二周-命题作业

莫森

极客大学架构师训练营

用go语言实现快排

Sean

go 算法 快速排序

高中生写LOL外挂1年狂赚五百万,落网前刚买下120万保时捷

Java架构师迁哥

原创 | 使用JPA实现DDD持久化-JPA vs MyBatis

编程道与术

Java hibernate 编程 mybatis jpa

腾讯云副总裁刘煜宏:大数据平台算力弹性资源池达500万核,国内最强

小小的一朵云

大数据

鲲鹏播种于时代,花开五色中原

脑极体

【FastDFS】SpringBoot整合FastDFS实战,我只看这一篇!!

冰河

springboot fastdfs

持续引领大数据行业发展,腾讯云发布全链路数据开发平台WeData

小小的一朵云

大数据

致谢!华为全联接2020精彩回顾

华为云开发者社区

华为 华为云 智能 hdc

jdk 源码系列之StringBuilder、StringBuffer

sinsy

Java jdk 源码解析

数字货币视域下的金融安全实现路径

CECBC区块链专委会

区块链 数字货币

Greenplum 性能优化之路 --(一)分区表

小小的一朵云

大数据

Greenplum 性能优化之路 --(二)存储格式

小小的一朵云

大数据

揭开500亿“区块链”骗局

CECBC区块链专委会

法律 传销

Study Go: From Zero to Hero

Study Go: From Zero to Hero

EMC颜开纵论NoSQL文档数据库反模式-InfoQ