最近我正在探索NoSQL 数据库。我需要关于如何针对给定问题以最优化、最有效的方式存储数据的建议。我现在的目标是 MongoDB。不过,它应该与 CouchDB 相同。

假设我们有这 3 个模型:

Story:
 id
 title

User:
 id
 name

Vote:
  id
  story_id
  user_id

我希望能够向数据库询问以下问题:

  • 谁给这个故事投票了?
  • 该用户投票了什么?

我在使用关系数据库时进行简单的连接。问题是,我应该如何存储这些对象的数据才能最有效。

例如,如果我将 Vote 对象存储为 Stories 的子集合,则很难获取信息 - “用户投票了什么”。

有帮助吗?

解决方案

我建议将投票存储为故事列表 _id每个用户中的 s。这样,您只需查看列表即可了解用户投票给了哪些故事。要获得为故事投票的用户,您可以执行以下操作:

db.users.find({stories: story_id})

在哪里 story_id 是个 _id 有关故事的内容。如果您在以下位置创建索引 stories 这两个查询都会很快。

其他提示

  • 不要担心你的查询是否有效,直到它开始变得重要
  • 根据下面的引用,你做错了

我一直在思维开关的方式是忘记数据库。在关系数据库世界中,您总是必须担心数据归一化和表结构。抛弃一切。只需布局您的网页即可。将它们全部放置。现在看看他们。您已经在那里2/3了。如果您忘记了数据库大小重要的观念,并且数据不应比您的3/4重复,甚至不必编写任何代码!让您的观点决定您的模型。您不必像在关系世界中那样拿起对象并将它们变为2维度。您现在可以用形状存储对象。

如何用数据存储而不是数据库来思考

好的,您已经给出了规范化的数据模型,就像在 SQL 设置中所做的那样。

据我了解,您不会在 MongoDB 中执行此操作。您可以存储引用,但在一般情况下出于性能原因不这样做。

我绝不是 NoSQL 领域的专家,但为什么不简单地遵循您的需求并将为故事投票的用户 (ids) 存储在故事集合中以及用户拥有的故事 (ids)在用户集合中投票?

在 CouchDB 中这非常简单。一个视图发出:

function(doc) {
 if(doc.type == "vote") {
   emit(doc.story_id, doc.user_id);
 }
}

另一个视图发出:

function(doc) {
 if(doc.type == "vote") {
   emit(doc.user_id, doc.story_id);
 }
}

由于没有连接,两者的查询速度都非常快。如果您确实需要用户数据或故事数据,CouchDB 支持多文档获取。也相当快,是进行“连接”的一种方法。

我最近对 ​​MongoDB 和 CouchDB 进行了很多研究,但我的洞察力有限。不过,当考虑将投票存储在故事文档中时,您可能不得不担心是否会达到 4MB 文档大小限制。即使不这样做,您也可能会不断增加文档的大小,足以导致其移动,从而减慢写入速度(请参阅 MongoDB 中如何调整文档大小)。

对于 CouchDB 来说,这些事情非常简单、优雅,而且一旦计算出视图索引就非常快。然而,就我个人而言,我对在 CouchDB 中执行类似的项目犹豫不决,因为基准测试表明,随着数据库的增长(以及视图索引的增长),它的速度会逐渐减慢到相当大的程度。我希望看到一些最新的基准测试显示随着数据库大小的增加 CouchDB 的性能。我想尝试 MongoDB 或 CouchDB,但 SQL 看起来仍然如此高效和合乎逻辑,所以我会继续使用它,直到项目完全符合诱惑。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top