0

我是 MongoDB 的新手,我正试图在使用的数据建模范式上取得领先。

我认为最好提供一点背景知识。假设我是一家向客户销售东西的公司;但是我的商品价格并不固定:每次购买都会发生迭代的易货交易序列。(即我公司报价、他们还价、我公司还价等)。我的数据库的目的是存储交易的演变。我公司有能力以不同的选择还价。唯一客户数<1000。因此,我有以下设置:

{
   customer_id : Number
   unique_deal_id: Number
   parent_unique_deal_id: Number
   child_unique_deal_id's: [Number]
   deal : {
     // info on price of each good negotiated
   }
}

如果 %100 我的查询涉及 a) 检索特定交易或 b) 检索交易的“分支”,那么在 MongoDB 中,我尝试将客户标准化并将其分离到他们自己的集合中,或者是将所有内容保存在单个集合(和索引客户)?

4

2 回答 2

1

我不认为文档结构真的是这里的问题。让我们从不同的角度来看这个。把它想象成一个会计分类账。

line #, Date,  Description,   Count,  Price each
1, 02/25/2013,  Super widgets, 1000, $1   // <-- Strike though font
2, 02/25/2013, Super Widgets, 5000, $0.50 // <-- Strike though font
3, 02/26/2013, Super widgets 3500, $0.75

最后一行#3,是当前的计数。通过查看日期,您可以看到保留的内容和未保留的内容。“交易”的演变很像您的帐户对帐单,只需将行记录项目更改添加到交易中,并“删除”未保留的那些(不要删除它们,只需将它们标记为非活动状态)。

我认为你有 3 个收藏:

  • 经销商 - 公司
  • 交易(经销商与您之间)
  • 交易存档(旧东西)

    { _id: mongoid, company_id: integer, ... 其他字段... transaction_log: [ { active: boolean, id: integer, date: datetime, description: text, count: integer, price: float?/integer? }, { active: boolean, id: integer, date: datetime, description: text, count: integer, price: float?/integer? }, { active: boolean, id: integer, date: datetime, description: text, count: integer, price: float?/integer? }, { active: boolean, id: integer, date: datetime, description: text, count: integer, price: float?/integer? }, ... ] }

于 2013-07-22T01:15:43.187 回答
1

我认为这是一个可能最好在现场进行的设计讨论,但希望我可以引导您朝着正确的方向前进。

听起来这个场景涉及 3 个主要实体:客户、交易和交易出价历史。将数据嵌入或存储在单独的集合中的决定是特定于开发人员应用程序的设计决策。如果您还没有学习一些基础知识,我强烈建议您参加免费的在线培训课程。有一个关于基本模式设计的课程将帮助指导您的思考过程。看起来您在考虑主要数据访问模式时已经直观地知道如何做出决定。

根据我对您的数据的理解,我可能会将您的客户数据存储在它自己的集合中。原因是您的应用程序可能会独立于交易访问客户详细信息,并且似乎不需要以原子方式访问客户和交易(Mongodb 旨在提供文档级别的原子操作)。这就是为什么在所有数据中复制客户数据可能不是更好的选择的一些原因。一旦客户登录,您就可以提取客户数据,并获得上下文(即客户 ID)。然后,您可以使用此上下文来读取和更新交易信息。您的交易集合实际上看起来不错。使用客户 ID,您可以提取交易以及交易的各种分支(在 www.mongodb 上有一些对树设计模式的参考。org 如果你想引用它们——请注意你的设计模式确实非常接近标准)。但是,将交易历史嵌入交易存在一个危险。请注意,当前单个文档有 16MB 的限制。如果您保持交易历史子文档精简,您应该能够存储大量历史;但是,如果您的应用类似于微竞价应用,那么 16MB 的限制可能会带来问题;如果是这种情况,那么您需要将交易历史记录存储到另一个集合中的单个文档中。如果有意义,您可以选择在您的交易中存储一些冗余数据,例如最近 10 个出价,如果这样可以让您的应用更容易阅读(相对于必须更新多个目标的可能性)。在任何情况下,如果它是合理的嵌入,因为它将为您的应用程序提供简单性和更快的数据访问。

此外,如果您最终将交易历史嵌入到您的交易中,您的文档将随着每个文档的大小而增长。MongoDB 将文档连续存储在磁盘上,以便快速更新和读取。这意味着如果文档增长超出其当前分配的空间,MongoDB 会将整个文档移动到磁盘上的另一个位置。这可能会减慢更新速度,如果您的应用程序需要大量更新,这可能会引起关注。为防止不及时的文档移动,请查看 mongodb.org 网站上使用填充因子选项和“powersof2”设置。

于 2013-07-22T01:56:14.713 回答