设为首页 收藏本站
查看: 2369|回复: 0

[经验分享] 写给MongoDB开发者的50条建议Tip1

[复制链接]

尚未签到

发表于 2018-10-28 07:55:27 | 显示全部楼层 |阅读模式
  本系列文章翻译自《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值。
DSC0000.png

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

  图1.2 引用式结构,fruit的值只存在于food集合,meals集合存储fruit的id
  这需要权衡,你不能同时拥有最好的性能和确保及时的数据一致性。你必须决定哪一个对于你的应用来说更重要。
  

  
举个例子来说。
  

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

  
引用式结构
  


  • a product:
  • {
  •   "_id":productId,
  •   "name":name,
  •   "price":price
  • }
  • a order:
  • {
  •   "_id":orderId,
  •   "user":userInfo,
  •   "items":[
  •     productId1,
  •     productId2
  •   ]
  • }
  

  

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

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

  
嵌入式结构
  


  • a product:
  • {
  •   "_id":productId,
  •   "name":name,
  •   "price":price
  • }
  • a order:
  • {
  •   "_id":orderId,
  •   "user":userInfo,
  •   "items":[
  •     {
  •       "_id":productId1,
  •       "name":name,
  •       "price":price
  •     },
  •     {
  •       "_id":productId2,
  •       "name":name,
  •       "price":price
  •     }
  •   ]
  • }
  

  

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

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

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



  • 为很少发生变化的数据,每次都是再次读取,你是否愿意付出这样的代价?
  你是愿意承担1000次读取带来的惩罚?大多数应用,读的压力要大于写的压力。这需要你仔细测试自己的比例。
  你正在考虑的引用数据的变化频率如何?改变越少,越是赞成使用嵌入式的结构。引用很少改变的数据,例如名称,出生日期,存货标记和地址,是很不值的。


  • 一致性有多重要?
  如果一致性很重要,你就应该使用引用式结构。例如,多个文档需要原子的查看数据的变化。如果我们正在设计一个交易系统,有价证券只能在特定的时间才可以进行交易,到达不可以进行交易的时间,我们需要立即锁定这些有价证券。这种事情在应用级别来操作可能更好,因为应用需要知道在什么时间锁定或者解锁。
  在上面的这个订单应用中,一致性可能是有害的。假设我们想要给一个产品打折,20% off。我们不想更新已经存在的订单中的产品信息。这时候,我们需要的可能是一个快照,是下单时候的产品信息。


  • 是否需要更快的读取速度?
  如果需要尽可能快的读取速度,我们应该使用嵌入式结构。实时系统应该更多的使用嵌入式结构。
  上面的这个订单文档是一个很好的嵌入式结构的例子,改变产品信息的时候,我们不想改变订单的信息。在这里,引用式结构不能带给我们任何的好处。
  在这个例子中,嵌入式结构是最佳的选择。
  最后给大家一个地址,Your Coffee Shop Doesn't Use Two-Phase Commit,,里面的例子讲述了在真实的环境中,如何处理一致性问题,以及相关的系统改如何设计。



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-627297-1-1.html 上篇帖子: 实战MongoDB-Replication之Replica Set 下篇帖子: 写给MongoDB开发者的50条建议【系列索引】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表