2010-09-28 69 views
21

我正在建立一个简单的会计系统,用户有很多账单。现在我正在试图确定账单应该是自己的收藏,还是嵌套在用户中。我倾向于前者,但我从来没有做过任何noSQL的东西,所以我只是通过试验和错误,我认为对我有意义。Mongo DB设计,嵌入vs关系

据我所知,Mongo的文件大小限制为4mb,这让我觉得我应该有一个单独的帐单收集,因为这些将每天累积,最终可能会占用大量的空间。

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

不在于它真的很重要,但我在Rails3中项目中使用Mongoid。我想我会这样做:

class User 
    references_many :bills 
end 

class Bill 
    referenced_in :user 
end 

任何意见或设计建议,非常感谢。你可能要考虑

回答

24

1)关于4MB文件的限制,这是什么“的MongoDB权威指南”说:不是4MB大

文件(当转换为BSON)不能被保存到数据库中。这是一个有些武断的限制(将来可能会提出);主要是为了防止糟糕的模式设计并确保一致的性能。为了从壳中看到的文档DOC的BSON大小(以字节为单位),运行Object.bsonsize(DOC)。

为了让你知道4MB是多少,战争与和平的全文只是3.14MB。

最终它取决于您期望用户增长的账单有多大。我希望上面的摘录能够让您了解文档大小所带来的限制。

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

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

鉴于你提到的用例,我会去解规范化的模式。

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

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

您也可以看看MongoDB的Production Deployments页面。您可能会发现SF.net幻灯片很有帮助。

+0

啊它只是在写...这是否会影响嵌入式文档的原子选择?例如,如果我只是在我的用户文档中对我的账单进行$推送,那么,如果我的用户和所有账单达到4mb,或者只有账单本身在写入时为4mb才算是否重要。我有一种感觉,它是后者,因此我很安全(因为单一账单不可能包含4mb数据,或者我会在1次写足够的账单以达到这个数量)这听起来是对的吗?假设,我想我会采取你的建议,并去标准化。 – brad 2010-09-28 23:30:50

+0

嗯...我想我其实是错的,我敢肯定如果他们的账单超过了这个数额,4mb限制会影响用户,但是账单中的数据量相当小,所以我要给它一张带嵌入式账单的照片,并在未来做一些测试,看看我可以处理什么样的账单容量 – brad 2010-09-29 12:11:59

1

一个问题是,会不会有永远是一个时间,你需要从他们的成员单独分开引用账单用户?如果是这样,如果他们有独立的存在就会更简单。

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

有可能是一个交易的问题为好,如果你正在写了许多包括票据庞大的用户,如果你改变的合理同时写入不同的连接相同的用户会发生什么?我对mongo知之甚少,不知道它会如何解决这个问题 - 我的猜测是,如果写入内容包含不同的附加账单,您可以同时获得这两个账单,但如果它们包含现有账单的不同更改,则会被覆盖 - 希望别人会对此发表评论,但至少我会测试它。如果您将帐单写入单独的收藏夹,这不是一个问题。

1

由于这个问题已经解决了很长时间,但我正在处理类似的事情,并认为我会将我的发现添加到研究此问题的任何其他人。

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

至于当同一个用户使用嵌入式账单发生多个更新时,会发生什么......如果再次使用同一个视频演示文件,问题就在于MongoDB更新信息的速度太快,通常不是问题。在更新发生时,MongoDB实例被锁定,所以多个更新不应该成为问题。

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

我个人发现MongoDB(和NoSQL DB)在特定情况下很有用,但传统的SQL/RDMS对于大多数问题仍然更好。如果你是Craigslist之类的人,并且模式变更需要2个月时间来运行你的归档数据,那么是的,MongoDB和NoSQL是合理的。但对于绝大多数应用程序,我不认为处理这些数据量是一个主要问题。