对比MongoDB与传统RDBMS

日期: 2013-03-28 作者:Krishna Prasad翻译:张亮亮 来源:TechTarget中国

RDBMS之所以能够长久不衰,是由于对关系和集合等数学理论的强烈依托,包括:模式验证,数据的标准化,原子性,锁机制,并发性,高可用性以及所谓的单一版本事实(single version of truth)。

  以上理论对于数据存储和检索是有非常有利的,它们会影响到企业级扩展性、系统性能和灵活性。我们来考虑一个典型的采购订单的例子,在RDBMS中有两张一对多关系表,OrderHeader和LineItem。

  考虑到需要存储大量的采购订单,我们首先进行了分区,分区的方法之一是将OrderHeader表放入一个DB实例,而将LineItem信息放入另一DB实例。如果想要插入或更新订单信息,则需要自动对两个表加以更新并且需要一个事务管理器来保证其原子性。如果在处理和数据存储的规模上有进一步要求,那就只有增加硬盘空间和RAM了。

  垂直扩展是在RDBMS中实现扩展的方法:

对比MongoDB与传统RDBMS

  让我们来考虑另外一种情况。由于我们业务上的变更,我们要在LineItem表中加入一个称为LineDesc的新列。假设这个应用程序正在生产环境中运行,要应用变更,就需要服务器停机才能生效。

  实现企业级可扩展性,性能和灵活性

  现代化的企业级系统基本要求有:

  • 在扩展数据库方面,灵活性能够让数据库的多个实例并行处理信息
  • 在数据库变更方面,灵活性可以让变更生效过程不需要太长的停机时间
  • 当应用程序/中间层无法处理对象-关系时,可以运用类似JSON的技术来处理

  我们再来回顾之前的PurchaseOrder例子并梳理RDBMS的某些方面诸如标准化(避免多行连接),原子性等并试看能否实现以上的一些目标。

  下面是一个我们如何存储PurchaseOrder的例子:

orderheader:{
orderdescription: “Krishna’s Orders”
date:”Sat Jul 24 2010 19:47:11 GMT-0700(PDT)”,
lineitems:[
{linename:”pendrive”, quantity:”5″}, {linename:”harddisk”, quantity:”10″}
]
}

  如果你注意观察,就会发现以上采购订单是存储在JSON文档的结构中。你可能会注意到,我们并不需要多个表,关系或是标准化,因此就不需要做连接。并且由于文档中存在模式限定符,表的定义就不存在了。

  你可以将它们作为对象或是文档的集合加以存储。假设如果我们需要存储数百万的采购订单,那么我们就可以对它们进行分组并存储在多个实例中。

  如果你想要基于特定条件来检索采购订单,比如要检索有一栏项目是“pendrive”的所有采购订单,我们就可以要求所有单独实例基于相同的条件来并行检索,而且其中一个实例可以整合列表然后返回信息给客户端。这就是水平扩展的概念。

  由于没有单独的表模式而且模式定义是包含在JSON对象当中的,我们仅在应用程序层进行操作就可以对文档结构进行更改、存储以及恢复等操作了,同时不需要重启数据库。

  最后是JSON对象结构,我们可以将其直接交付给页面层或是移动设备,并会被很好的予以呈现。

  NoSQL是一种被设计用来实现以上各方面特性的新型数据库。

  MongoDB:基于文档的NoSQL数据库

  MongoDB是基于文档的数据库,并应用以上技术来存储和检索数据。还有少数如RedisCassandra的NoSQL数据库是基于键值的,它们同样也采用这些技术但是要简单的多。

  如果非要给RDBMS做一类比,那么MongoDB中的集合类似于表,而文档就类似于记录。MongoDB在内部将信息以二进制序列化的JSON对象进行存储,称之为BSON

  典型的文档如下所示:

post={
author:“Hergé”,
date:new Date(),
text:“Destination Moon”,
tags:[“comic”,“adventure”] }
> db.post.save(post)
————
>db.posts.find()  {
_id:ObjectId(” 4c4ba5c0672c685e5e8aabf3″),
author:”Hergé”,
date:”Sat Jul 24 2010 19:47:11 GMT-0700(PDT)”,
text:”Destination Moon”,
tags:[“comic”,”adventure”]
}

  在MongoDB中,原子性是在一个文档中加以保证的。如果你非要在文档外实现原子性,那就必须在应用程序层进行管理。例子如下

  多对多:

products:{
_id:ObjectId(“10”),
name:”DestinationMoon”,
category_ids:[ObjectId(“20”),ObjectId(“30”)]}
categories:{
_id:ObjectId(“20”),
name:”adventure”}
//All products for a given category
>db.products.find({category_ids:ObjectId(“20”)})
//All categories for a given product
product=db.products.find(_id:some_id)
>db.categories.find({
_id:{$in:product.category_ids}
})
[feedly mini] 

  在一个应用MongoDB的典型堆栈中,使用基于JavaScript的框架是很有意义的。一个好的页面框架,我们是使用Express,Node.js,或是MongoDB 堆栈的。下面链接是一个讲解如何使用这些堆栈的很好例子:http://howtonode.org/express-MongoDB

  MongoDB NoSQL同时支持分片技术,它能够支持并行处理和水平扩展。对MongoDB的典型应用场景包括:事件日志,实时分析,内容管理,电子商务。而对基于交易的银行系统和非实时的数据仓储场景的应用并不十分合适。

  参考:

  MongoDB NoSQL 数据模型技术:http://highlyscalable.wordpress.com/2012/03/01/nosql-data-modeling-techniques/

  Ricky Ho关于NoSQL的文章:http://horicky.blogspot.com/search?q=nosql

  MongoDB NoSQL在模式设计上的应用:http://www.scribd.com/doc/47326395/MongoBoulder-Schema-Design

  数据库可扩展样式:http://www.slideshare.net/xzilla/database-scalability-patterns-4825223

  用MongoDB进行实时分析:http://www.slideshare.net/jrosoff/realtime-analytics-with-MongoDB-MongoDB-meetup-nyc

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

翻译

张亮亮
张亮亮

TechTarget特邀编辑。毕业于北京邮电大学网络技术研究院。熟悉软件开发测试的各个环节和流程,对操作系统,数据库,计算机网络等有较为深入的理解。现就职于中国电子科技集团公司下属研究所,从事软件研发工作。热衷于英文的学习交流,平时喜欢户外运动,音乐,电影。

相关推荐