对于MongoDB,面临的最大问题就是如何为应用程序设计出良好的数据模型,大家都是摸着石头过河,意见很难达成一致。最近读了O‘REILLY的一本小册子《50 Tips & Tricks for MongoDB Developers》受益匪浅,所以决定将其中的内容翻译出来。并结合自己实际感受给予评注。
#第一条 为了速度去重复数据,为了完整性去引用数据(Duplicate data for speed,reference data for integrity)
多个文档中的数据能够被“嵌入”(embed)或是“引用”(reference)。很难说“嵌入”的方式就一定比“引用”好,反之亦然。每种方式都有自己用处,而你应该为你的应用程序去选择合适的方式。
“嵌入”会引起数据的“不一致”:假设你想把(图1.1)中的苹果变成梨,如果你更改了其中一个文档中的值,但恰巧在就要更改第二个文档的值之前系统崩溃了,那么你的数据库中对于fruit会出现两个不同的值。
图1.1
“不一致”并不是件好事,但是“不好”的程度取决于你存储的是什么。在许多应用中,短暂的“不一致”是被允许的:例如某人修改他的用户名,他并不会介意在几个小时内他的旧文章中仍然显示其旧用户名。如果连短期内的不一致都不被允许,这时你需要考虑“引用”了。
然而,如果你“引用”,那么你的应用程序就必须做额外的查询去找出这个水果是什么(图1.2),如果你的应用不能这样的性能打击或是具备稍后将数据一致化的能力,那么你一改使用“嵌入”。
这是一种权衡:你不可能同时具有“最快性能”(fastest performance)和“即刻一致性”(guaranteed immediate
consistency)。你必须去决定哪个对你的应用来说更重要。
例子:购物车订单
假设我们在为一个购物车应用设计数据模型。我们的应用将订单存储在MongoDB中,那么一个订单中应该包含什么样的信息呢?
“引用”模式:
A product:
{
"_id" : productId,
"name" : name,
"prise" : price,
"desc" : description
}
An order:
{
"_id" : orderId,
"user" : userInfo,
"items" : [
productId1,
productId2,
productId3
]
}
我们将所定产品的_id存储在[订单]文档的“items”集合中。然后,当我们需要显示订单内容的时候,我们去查询[订单]文档来获取正确的订单,然后通过“items”中的产品_ids去[产品]文档中查询与之相关的每个产品。“引用”模式中,我们没有办法通过单次查询来获取到全部的订单内容。
如果产品信息被更新,所有引用该产品的文档都会跟着“改变”,因为这些文档中存储的仅仅只是产品的引用。
“嵌入”模式
A product(和“引用”模式中的相同):
{
"_id" : productId,
"name" : name,
"prise" : price,
"desc" : description
}
An order:
{
"_id" : orderId,
"user" : userInfo,
"items" : [
{
"_id" : productId1,
"name" : name1,
"price" : price1,
"desc" : description1
},
{
"_id" : productId2,
"name" : name2,
"price" : price2,
"desc" : description2
},
{
"_id" : productId3,
"name" : name3,
"price" : price3,
"desc" : description3
}
]
}
我们将产品信息当做嵌入到[订单]文档中,然后,当我们要显示订单的时候,只需要做一次查询。
如果一个产品的信息被更新,并且需要将订单中的产品同时更新,我们需要分别去更新每个订过该产品的[订单]文档。“嵌入”使得我们能够更快的读取,但是产品信息不能够在多个文档中被原子性的改变。
因此,给出一些选项,帮助你决定使用“引用”还是“嵌入”?
决定因素
有三个主要因素需要考虑:
1.你是否为了很少才会发生一次的数据变化而在每次读取上花费代价。
你也许会去读取一个产品一万次为了它的每一次变化。你是否会愿意每次为了”使一次写入更快或是保证一致性而去做10000次读取”缴纳罚金。大多数的应用程序read-heavy比write-heavy要重要一些:做出你的权衡吧。
2.一致性对你的应用来讲有多重要?
如果你的应用中一致性很重要,你应该采用"引用"模式,例如,我们需要多个文档原子性的看到一次数据变化。 如果我们做的是一个只能在某些时间段内交易某种"有价证券"的交易系统,当"有价证券"不可交易时,我们应该立即对它 们加"锁"。我们可以将一个加锁的单个文档引用到一组与之相关的[有价证券]文档中。这样做要比在应用程序层面上去加 锁要好一点。但是无论如何,应用程序需要知道何时去加锁以及何时去解锁。
3.是否需要快速读取?
如果读取需要尽可能的快,那么应该采用"嵌入"。在实时(Real-time)系统中应该尽可能的使用"嵌入"。
- 大小: 19.4 KB
- 大小: 19.4 KB
- 大小: 16.4 KB
分享到:
相关推荐
《MongoDB developers》 原书高清版本,希望你喜欢
综上所述,提升MongoDB开发者的效率是一个系统性的工程,需要从多个方面进行综合考虑和设计。通过遵循周李洋(E叔)分享的这些经验和最佳实践,开发者可以更有效地利用MongoDB来支撑业务的快速发展,同时保持系统的...
C# 驱动是 MongoDB 提供的一种客户端库,允许 .NET 开发者与 MongoDB 数据库进行交互。标题提到的是 MongoDB 的 C# 驱动的最新版本——mongodb.driver.dll,具体为 2.12.0-beta1 版本。 MongoDB.Driver.dll 是 C# ...
MongoDB开发者指南是一份全面的参考手册,涵盖了MongoDB的各个方面,适合所有级别的开发者阅读。 ### **32. 锁定在Mongo中的应用(Locking in Mongo)** 这部分内容进一步探讨了锁定在MongoDB中的具体实现和使用...
在《50个技巧与窍门:MongoDB开发者指南》这本书中,作者Kristina Chodorow为MongoDB开发者提供了丰富的经验和建议。MongoDB是一种非常流行的NoSQL数据库系统,以其灵活性和高性能著称。本书分为五个章节,每个章节...
在Linux环境下安装MongoDB 4.2.21版本,是许多系统管理员和开发者的常见任务。本篇将详细介绍在Linux上安装MongoDB 4.2.21的步骤,以及相关的知识点。 首先,我们需要了解MongoDB的体系结构。MongoDB由以下几个核心...
MongoDB是一款高性能、无模式的分布式文档数据库,广泛应用于现代应用程序开发中,特别是对于处理大量非结构化数据的场景。Windows 64位版本的MongoDB安装包是为64位操作系统设计的,能充分利用系统资源,提供更好的...
9. 社区支持:MongoDB有一个活跃的开发者社区,提供丰富的文档、教程和论坛支持,帮助用户解决遇到的问题。 总的来说,MongoDB的32位版本虽然在性能上稍逊于64位,但仍是一个功能齐全的数据库解决方案。对于32位...
Spring Data MongoDB 是一个项目,它将 Spring 框架的核心概念应用于使用 MongoDB 文档样式数据存储的解决方案开发中。该项目提供了一个“模板”作为存储和查询文档的高级抽象层,其设计思想与 Spring Framework 中...
6. Python支持:MongoDB提供了PyMongo库,这是一个Python语言的官方驱动程序,让Python开发者可以方便地与MongoDB交互,进行数据的存取和处理。 在32位系统上安装MongoDB 3.0.8版本时,需要注意以下几点: 1. 内存...
Compass是MongoDB的官方图形界面工具,它提供了一个用户友好的界面,用于可视化数据库和集合,帮助开发者和管理员进行数据探索、查询构建、性能分析以及基本的数据库管理。通过Compass,用户可以轻松地浏览和操作...
MongoDB是一种流行的开源、分布式文档型数据库,以其灵活性、高性能和易用性而备受开发者青睐。作为NoSQL数据库的一种,它存储数据的方式不同于传统的表结构,而是采用键值对、文档、集合的形式。MongoDB的官方中文...
MongoDB是一种分布式文档数据库,它在处理大量数据时提供了高性能、高可用性和可扩展性。PHP是广泛用于Web开发的脚本语言,它有一个专门的MongoDB扩展,允许开发者直接在PHP中操作MongoDB数据库。这个压缩包包含了...
MongoDB Stitch是一种后端即服务(Backend as a Service),它为MongoDB应用提供了一个无服务器的平台,使得开发者可以更专注于应用程序的开发而不是后端的搭建和维护。 本文还提供了关于如何高效利用MongoDB官方...
MongoDB 是一款非常流行的开源文档型数据库系统,因其灵活性高、易于扩展等特性而受到众多开发者青睐。本文旨在为初次接触 MongoDB 并希望在 Windows 环境下进行安装配置的用户,提供一份详尽的操作指南。 #### 二...
MongoDB是一款分布式文档数据库系统,以其灵活性、高性能和易扩展性而受到开发者的广泛欢迎。在Java编程环境中,与MongoDB交互主要通过其提供的Java驱动程序。本篇将深入探讨"mongodb_java_2.6_API",即MongoDB 2.6...