嵌套信息的mongodb数据模型更好

问题描述 投票:1回答:1

我正在为mango db设计一些数据模型,我有一些类似于json的要求。

Single_Collection。

{

"collegeid": 1234,
"Name": "aaaa",
 "otherinfo": 1,

"studnet":[
    {
        "stdid": 1,
        "name": "n1"
    },
    {
        "stdid": 2,
        "name": "n2"
    }
]
}

两个收藏。

  1. 学院信息 { "collegeid": 1234, "Name": "aaaa", "otherinfo": 1 }

学生信息集

    {
    "collegeid": 1234,
    "stdid": 1,
    "name": "n1"
    }

    {
    "collegeid": 1234,
    "stdid": 2,
    "name": "n2"
    }

哪个是阅读表现的更好的方式(单个收集或分离出来),我有更多阅读像给定的学生ID找到大学ID。学生证名单会很大。

我还执行更多的学生插入操作

mongodb mongodb-query data-modeling
1个回答
1
投票

IMO,每个模型设计都有自己的优点和缺点,我们所说的“更好的方式”取决于您的使用案例(如何查询数据?您是否需要一开始的所有数据?您需要分页吗?等等。 。)

让我们从您的要求开始。

你的要求

  1. 鉴于大学身份证,找出这所大学的学生。
  2. 给出学生证,找出他的大学身份证。

对象之间的关系

显然大学和学生是1:m的映射,因为一个大学里的很多学生但每个学生只能留在一所大学。

我将向您展示一些不同的模型设计,并为每个型号提供优点和缺点。

方法1 - 将学生嵌入大学

这是您作为单个集合提到的设计。

{
   "collegeid":1234,
   "Name":"aaaa",
   "otherinfo":1,
   "studnet":[
      {
         "stdid":1,
         "name":"n1"
      },
      {
         "stdid":2,
         "name":"n2"
      }
   ]
}

优点:

  1. 非常自然的模型供人阅读和前端显示。
  2. 在装载学院和所有学生时,表现良好。因为存储在引擎中的数据是连续的。引擎需要更少的I / O来做到这一点。

缺点:

  1. 如果你在大学里有大量的学生,那么文件的大小就会非常大。如果经常添加/删除/更新学生,效率会很低。
  2. 没有一种快速的方法来实现要求(2)。由于我们只维护大学 - >学生的映射,您必须浏览所有文档以找出哪个大学包含指定的学生ID。

方法2 - 学生参考大学

这是您作为两个集合提到的设计。它类似于RDBMS表,学生模型拥有其大学的参考关键点。

  1. 大学收藏:
{
   "collegeid":1234,
   "Name":"aaaa",
   "otherinfo":1
}
  1. 学生收藏:
{
   "collegeid":1234,
   "stdid":1,
   "name":"n1"
}
{
   "collegeid":1234,
   "stdid":2,
   "name":"n2"
}

优点:

  1. 可以达到要求(1)和(2)。请记住在"collegeid""stdid"字段上添加索引。
  2. 每个文档都可以保持小尺寸,引擎很容易存储数据。

缺点:

  1. 学院和学生是分开的。如果加载一所大学及其所有学生(需要两个查询),它将比方法1慢。
  2. 在UI中显示之前,您需要自己将大学和学生合并在一起。

方法3 - 大学和学生的重复数据

这种方法看起来像我们混合方法1和方法2.我们有两个集合:大学将其学生嵌入其中,并且还有一个独立的学生集合。因此,学生数据在两个馆藏中都是重复的。

  1. 大学收藏:
{
   "collegeid":1234,
   "Name":"aaaa",
   "otherinfo":1,
   "studnet":[         // duplicated here!
      {
         "stdid":1,
         "name":"n1"
      },
      {
         "stdid":2,
         "name":"n2"
      }
   ]
}
  1. 学生收藏:
{
   "collegeid":1234,
   "stdid":1,
   "name":"n1"
}
{
   "collegeid":1234,
   "stdid":2,
   "name":"n2"
}

优点:

  1. 你有方法1和方法2的所有优点。

缺点:

  1. 大学收藏中的文件将变得非常大。
  2. 你必须自己保持大学收集和学生收集的数据同步。

方法4 - 大学(仅限学生ID)和学生的重复数据

这是方法3的变体。我们假设您的用例是:

  1. 用户可以搜索大学。
  2. 用户点击搜索结果中的一个大学。
  3. 新UI向用户显示所有学生ID(可能在网格或列表中)。
  4. 用户单击一个学生ID。
  5. 系统加载指定学生的完整数据,并在另一个UI中显示给用户。

简而言之,用户在开始时不需要所有学生的完整数据,他只需要学生的基本信息(例如学生ID)。如果用户接受此类方案,您可以使用以下型号:

  1. 大学收藏:
{
   "collegeid":1234,
   "Name":"aaaa",
   "otherinfo":1,
   "studnetIds":[1, 2]  // only student IDs are duplicated
}
  1. 学生收藏:
{
   "collegeid":1234,
   "stdid":1,
   "name":"n1"
}
{
   "collegeid":1234,
   "stdid":2,
   "name":"n2"
}

学院只有学生证。与方法3相比,这是不同的。

优点:

  1. 可以达到要求(1)和(2)。
  2. 您不必担心大学文档会变得庞大。因为它只拥有学生证。
  3. 如果用户接受上述方案,这将是性能/复杂/数据大小平衡的更好设计。

缺点:

  1. 适用于指定的用例,如果将来要求更改,将打破方案,此模型将不好。

摘要

  1. 您应该非常清楚您的用例。
  2. 根据用例,比较方法,看看您是否可以接受利弊。
  3. 负载测试很重要!
© www.soinside.com 2019 - 2024. All rights reserved.