21

我正在构建一个简单的会计系统,其中用户有很多账单。现在我正在尝试决定 bills 是否应该是它自己的集合,或者嵌套在用户中。我倾向于前者,但我从来没有做过任何 noSQL 的东西,所以我只是通过反复试验和我认为对我来说有意义的事情。

我知道 Mongo 有 4mb 的文档大小限制,这让我认为我应该单独收集账单,因为这些账单会每天累积,最终可能会占用大量空间。

我只是在寻找对此事的意见。基本上,我将查询不同日期期间的用户账单(您可以想象会计系统会这样做)。

这并不重要,但我在 Rails3 项目中使用 Mongoid。我想我会做类似的事情:

class User
  references_many :bills
end

class Bill
  referenced_in :user
end

非常感谢任何意见或设计建议。

4

3 回答 3

24

1)关于 4MB 文档限制,这就是“MongoDB:权威指南”所说的:

大于 4MB 的文档(转换为 BSON 时)无法保存到数据库中。这是一个有点武断的限制(将来可能会提高);它主要是为了防止糟糕的架构设计并确保一致的性能。要查看文档doc的 BSON 大小(以字节为单位),请从 shell运行 Object.bsonsize( doc )。

为了让你知道 4MB 是多少,《战争与和平》的整个文本只有 3.14MB。

最后,这取决于您期望用户的账单增长有多大。我希望上面的摘录能让您了解文档大小所施加的限制。

2)如果你知道你永远不会对账单运行全局查询,那么去规范化的模式(账单与用户文档一起)是要走的路(如果你想检索最近的十张账单,这种查询的例子是进入系统)。如果您使用非规范化模式,则必须使用 map-reduce 来检索此类查询的结果。

如果您希望灵活地查询账单的方式,规范化模式(用户和账单在单独的文档中)是更好的选择。但是,由于 MongoDB 不支持连接,因此每次要检索与用户对应的账单时都必须运行多个查询。

鉴于您提到的用例,我将使用非规范化模式。

3) MongoDB 中的所有更新都是原子的和序列化的。这应该能回答史蒂夫的担忧。

您可能会发现这些幻灯片很有帮助。http://www.slideshare.net/kbanker/mongodb-meetup

您还可以查看 MongoDB 的生产部署页面。您可能会发现 SF.net 幻灯片很有帮助。

于 2010-09-28T15:54:55.077 回答
1

这个问题已经很久没有解决了,但我正在处理类似的事情,并认为我会为其他研究这个问题的人添加我的发现。

我的理解是 4MB 的文档在 1.8+ 版本中已经扩展为 16MB。这是来自 MongoDB 成员之一的 Banker 的视频演示。我没有验证这个值,但我相信他的话(因为他希望知道他在说什么)。

至于当同一个用户使用嵌入式账单发生多次更新时会发生什么的问题......再次来自同一个视频演示,提供的答案是 MongoDB 更新信息如此之快以至于它通常不是问题。MongoDB 实例在更新发生时被锁定,因此多次更新不应该成为问题。

我对嵌入文档的担忧是不能独立于其父文档来处理它们。在我看来,这使得嵌入式文档变得毫无价值。它们仅对满足特定用例的利基案例有用。

我个人发现 MongoDB(和 NoSQL DB)对于特定情况很有用,但传统的 SQL/RDMS 对于大多数问题仍然更好。如果您是 Craigslist 之类的人,并且架构更改需要您 2 个月才能在存档数据上运行,那么是的,MongoDB 和 NoSQL 是有意义的。但对于绝大多数应用程序,我认为处理这么多数据不会是一个主要问题。

于 2011-07-12T16:45:58.373 回答
1

您可能要考虑的一个问题是,除了用户的会员资格之外,您是否需要单独参考账单?如果是这样,如果他们有独立的存在,那就更简单了。

除此之外,您已经确定的大小限制问题是拆分它们的一个很好的理由。

也可能存在事务问题,如果您正在编写包含许多账单的大用户,如果您从不同的连接合理地同时写入同一用户的更改会发生什么?我对 mongo 知之甚少,不知道它将如何解决这个问题——我的猜测是,如果写入包含不同的添加账单,你会同时得到它们,但如果它们包含现有账单的不同变化,你会得到覆盖——希望其他人会对此发表评论,但至少我会对其进行测试。如果您将账单写入单独的集合,这不是问题。

于 2010-09-28T14:56:38.987 回答