Chinaunix首页 | 论坛 | 博客
  • 博客访问: 869189
  • 博文数量: 366
  • 博客积分: 10267
  • 博客等级: 上将
  • 技术积分: 4290
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-24 14:04
文章分类

全部博文(366)

文章存档

2012年(366)

分类: 系统运维

2012-03-03 13:58:26

本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译一下。一方面加强自己学习的效果,另一方面让大家也一起来体验一下需要我们这些mongodb使用者需要注意的地方。

首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到合适的词来表达,所以在文章中可能会出现英文原词,或者说有些地方的翻译会有些生硬,也就是说会出现直译的地方。翻译该书的主要目的是为大家学习探讨用的,如果有翻译不精准的地方,或者说有更加精准的翻译,还请大家指出,我会及时的更正的,在此先谢过各位了。

Tip#1.Duplicate data for speed,reference data for integrity

数据冗余是为了性能,引用数据是为了完整性。

被多个文档使用的数据,既可以直接嵌入文档,也可以在文档中引用数据。嵌入不一定就比引用好,反之,引用也不一定就比嵌入好。每一种都有自己的取舍,不论什么,你都应该选择适合你的应用程序的方式。

嵌入式的结构,可能会导致数据的不一致。假设你需要把图1.1中的fruit的值从苹果修改为鸭梨,你刚修改完food集合中的fruit值,这时候你的应用崩溃了,其他地方的fruit的值还是旧的值,这时候你的应用中就同时存在两种不同的fruit值。

图1.1 嵌入式结构,fruit的值既存在于food集合,也存在于meals集合

不一致性也不是什么大问题,但“不是大问题”也是有级别的,这个级别依赖于你的用户需求。对于很多的应用,短时间内的不一致是可以接受的。假设一个用户修改了他的姓名,在几个小时内,他的旧帖子继续显示他的旧姓名,是可以接受的。如果是即使短时间的不一致性也不能接受的话,你就需要考虑使用引用式的结构了。

图1.2 引用式结构,fruit的值只存在于food集合,meals集合存储fruit的id

这需要权衡,你不能同时拥有最好的性能和确保及时的数据一致性。你必须决定哪一个对于你的应用来说更重要。

举个例子来说。

假设我们正在设计一个购物车的应用,设计在mongodb中存在订单信息,订单需要包含哪些信息呢?

引用式结构

  1. a product:
  2. {
  3. "_id":productId,
  4. "name":name,
  5. "price":price
  6. }
  7. a order:
  8. {
  9. "_id":orderId,
  10. "user":userInfo,
  11. "items":[
  12. productId1,
  13. productId2
  14. ]
  15. }



在订单的item项中存在每一个productid,当需要显示订单内容的时候,首先查询order集合,然后根据productid查询product集合来获取相应的产品名称,没有办法做到只用一次查询就可以获取完整的订单信息。

如果产品信息被更新,所有引用该产品的地方,都会显示新的产品信息。引用式的结构会拖慢读数据的速度,但是在多个订单会有很好的一致性,多个文档能实现原子的变化(只需要修改引用的文档的信息)。

嵌入式结构

  1. a product:
  2. {
  3. "_id":productId,
  4. "name":name,
  5. "price":price
  6. }
  7. a order:
  8. {
  9. "_id":orderId,
  10. "user":userInfo,
  11. "items":[
  12. {
  13. "_id":productId1,
  14. "name":name,
  15. "price":price
  16. },
  17. {
  18. "_id":productId2,
  19. "name":name,
  20. "price":price
  21. }
  22. ]
  23. }



将产品信息嵌入到订单信息中,当需要显示订单的时候,只需要执行一次查询即可。如果产品的信息发生变化,而且我们想要将变化传递给订单的话,我们需要更新多个独立的订单。

嵌入式结构加快了读取的速度,但是一致性会降低,产品信息不能被原子的在多个文档中被修改。

决定使用嵌入式结构还是使用引用式结构,可以参考下面的因素:

  • 为很少发生变化的数据,每次都是再次读取,你是否愿意付出这样的代价?

你是愿意承担1000次读取带来的惩罚?大多数应用,读的压力要大于写的压力。这需要你仔细测试自己的比例。

你正在考虑的引用数据的变化频率如何?改变越少,越是赞成使用嵌入式的结构。引用很少改变的数据,例如名称,出生日期,存货标记和地址,是很不值的。

  • 一致性有多重要?

如果一致性很重要,你就应该使用引用式结构。例如,多个文档需要原子的查看数据的变化。如果我们正在设计一个交易系统,有价证券只能在特定的时间才可以进行交易,到达不可以进行交易的时间,我们需要立即锁定这些有价证券。这种事情在应用级别来操作可能更好,因为应用需要知道在什么时间锁定或者解锁。

在上面的这个订单应用中,一致性可能是有害的。假设我们想要给一个产品打折,20% off。我们不想更新已经存在的订单中的产品信息。这时候,我们需要的可能是一个快照,是下单时候的产品信息。

  • 是否需要更快的读取速度?

如果需要尽可能快的读取速度,我们应该使用嵌入式结构。实时系统应该更多的使用嵌入式结构。

上面的这个订单文档是一个很好的嵌入式结构的例子,改变产品信息的时候,我们不想改变订单的信息。在这里,引用式结构不能带给我们任何的好处。

在这个例子中,嵌入式结构是最佳的选择。

阅读(387) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~