0

基本数据模型由 3 个对象组成:

A: ObjectId id, String name, List of B objects
B: ObjectId id, String name
C: ObjectId id, reference to B object

类型的对象A并且B很少被创建(可能是每个月的对象之一)。每个A对象将只包含几个(= 1-5)个B对象。如果我使用嵌入,它看起来像这样:

{
  id : ObjectId(...),
  name : "some A name",
  bList : [
    {
      id : ObjectId(...),
      name : "some B name"
    },{
      id : ObjectId(...),
      name : "some other B name"
    }
  ]
}

C 类型的对象将始终如下所示:

{
  id : ObjectId(...),
  bReference : ObjectId(...)
}

我不能将 C 嵌入到 B 中,因为 C 对象的数量可能是无限的(= 连接到单个 B 对象的数百万个条目)。

A 和 B 对象可能每月修改一次。C 对象永远不会被修改。但是 C 对象会被非常频繁地插入(峰值负载应该是每秒大约 20 次插入)。

问题/问题:

每次我查询 C 类型的文档时,我都需要来自引用的 B 文档的一些信息(有时还需要来自 A 文档的信息)。例如,我需要检查是否允许我访问 C 对象:

c = db.c.find({ ... })
a = db.a.find({ bList.id : c.bReference })
// do something with the access permission information from within a.

如果我需要来自 A 和 B 的信息,这似乎很不错。正确的?


但是,如果我只需要 B 文档中的信息(通常是这种情况)怎么办?

c = db.c.find({ ... })
b = db.a.find({ bList.id : c.bReference }, { bList.$ : 1 })

如果我查询多个 C 对象,它们将始终(!)引用同一个 B 对象。使用非嵌入式数据库设计时,查询将如下所示:

c = db.c.find({ ... })
b = db.b.find({ _id : c.bReference })

最重要的问题是:如果我经常这样做,这两种变体之间会不会有巨大的性能差异?


奖金问题:

我可以对所有 A 对象设置唯一约束吗?我想让所有这些 a.bList.id ObjectIds 都是唯一的(我知道它们应该(!)是全局唯一的,但是对 DB 级别的约束让我感觉更安全)

4

1 回答 1

0

通常,您的第一个问题的答案是:视情况而定。如果对象很大(例如每个数百 k),则可能会对性能造成轻微影响。如果对象相对较小,则应该不会有太大差异。

A当然,'slight'、'large'、'small'等都是很模糊的,所以让我详细说明一下:由于and对象很少,B而且它们经常被查询,它们可能会留在RAM中,这很好,所以唯一的潜在瓶颈是序列化器/反序列化器和网络。但是假设您每秒执行 1000 次查询,并且对象大小为 1k,那么这是 1MB/s - 仍然不是特别高的负载。

如果对象的大小为 100k,我们将谈论 100MB/s 或大约 1Gbit/s,这是一个完全不同的游戏 - 对于强大的服务器来说当然不是高负载,但它可能会阻塞 $20/m 的虚拟专用服务器. 再说一次,即使以这种速度,根据您的一致性约束,您可能希望将这些对象缓存一两秒钟,从而显着减少读取的网络负载。

简而言之,每秒执行 20 次操作,没什么好担心的。

正如您在这里的其他答案中看到的那样,我经常建议不要嵌入,但由于该数据很少被修改,嵌入应该没问题。

于 2014-01-22T10:42:52.517 回答