- 论坛徽章:
- 49
|
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(包括和外键息息相关的外键约束)等特性,习惯性的沿用关系模型有的时候会出现问题。需要利用起文档数据库提供的丰富的数据模型来应对。
颜开提出一个例子,指出这个例子存在两个问题:
存在描述多对多的关系表
没有区分"一对多关系"和“多对一关系”
颜开提出一个正确使用的场合:
关系型模型是非常成功的数据模型,合理的沿用是非常好的。但是由于文档数据库的特点,需要适当的调整,这样得出的数据模型,尽管性能不是最优,但是有最好的灵活性。并且也有利于和关系数据库转换。
反模式二:处处引用客户端Join
这样的坏处是:
手动Join,麻烦且易出错。
多次查询。如果引用过多,查询的时候需要多次查询才能查到足够的数据。
事务处理繁琐。
解决方法是:
在以下三种场合,适当使用内联数据结构。
使用内联可以解决读性能问题,明显减少Query的次数的时候。
可以简化数据模型,化简表之间的关系,而同时不会影响灵活性的时候。
事务可以得到简化为单行事务的时候
正确的场合是:
范式化的使用场景,文档数据库会被多个应用使用。由于数据库设计无法估计多个应用现在及将来的查询情况,需要极大的灵活性。在这个时候,使用引用比内联靠谱。
反模式三:滥用内联后患无穷
有四种主要症状:
- 妨碍到查询的内联
- 无限膨胀的内联
- 无法维护的内联
- 盯死应用的内联
反模式四:在线计算
主要症状:有一些运行时间很长的Query,由于有聚合计算,索引也不能解决。随着数据量的增长,逐渐成为性能瓶颈。
坏处有二:
解决方案:要权衡聚合操作是否必要,是否需要实时完成。如果务必要,可采取离线模式。如必须实时,则可以新建一个字段,用“incr”这样的操作,在运行的时候,实时聚合结果。如果逻辑比较复杂,或者觉得大量“incr”操作给数据库系统带来了压力,可以使用Storm之类的实时数据处理框架。总之,要慎用长查询。
反模式五:把内联Map对象的Key当作ID用
其症状是:
文档数据库支持内联Map类型。将其中Map的Key当作数据库的主键来用。
颜开指出:“这个反模式很容易犯,因为在编程语言中Map数据结构就是这么用的。但是对于数据库模型来说,这是不折不扣的反模式。”
主要坏处有二:
解决方案:使用数组+Map来解决。。Map类型中的Key是属性名,Value是属性值。这样的用法是文档数据库数据模型的本意,因此其提供的各种功能才能利用上。否则就无法使用。
反模式六:不合理的ID
症状:使用String甚至更复杂数据结构作为的ID,或者全部使用数据库提供的自生成ID
两个坏处是:
解决方案:
尽量使用有一定意义的字段做ID,并且不在其他字段中重复出现。不使用复杂的数据类型做ID,只使用int,long或者系统提供的主键类型做ID。
在文章最后,颜开用一个表格涵盖了所有反模式,读者可点击
原文链接
查看。
颜开最后说道:
现在关于NoSQL数据模型设计模式的讨论才刚刚起步,将来也许会逐渐自成体系。对于列数据库和Key-Value的反模式,笔者等到有了足够积累的时候,再和大家分享。
时间:2013-01-28 07:50来源:InfoQ 作者:郑柯责任编辑:zhangkai
本文来自ChinaUnix新闻频道,如果查看原文请点:http://news.chinaunix.net/opensource/2013/0128/2614664.shtml |
|