MongoDB - 我应该通过哪种方式建立关系?

时间:2018-04-27 15:25:26

标签: mongodb database-design

我目前正在尝试使用Node.js和MongoDB为我的婚礼构建一个应用程序。我目前正在为婚礼早餐制作一个餐桌规划师,它将像Trello Board一样工作。每位客人都是一个项目,每个餐桌都会像一个trello列表。因此,在构建时,我们可以将客户从未分配的堆中拖放到特定的trello样式板,这将为他们分配位置。

每张早餐桌可容纳多位客人,客人只能坐在一张桌子旁。我是否有点困惑是否在客户模型中包含“表”作为外键,反之亦然。

将'table'作为外键,可以让我轻松查询当前没有表的guest。另一方面,在“表格”模型中将访客作为外键,可以让我轻松查询尚未分配任何访客的表格。

我需要执行上述两个查询才能更新React中的状态。

下面显示了我的Guest模式及其与表模型的关系:

const guestSchema = new mongoose.Schema({
  firstname: {
      type: String,
      required: 'Please provide the first name of the guest',
      trim: true
  },
  surname: {
      type: String,
      required: 'Please provide the surname of the guest',
      trim: true
  },
  attending: {
      type: String,
      default: 'Awaiting RSVP'
  },
  menu: {
      type: String,
      default: 'Awaiting RSVP'
  },
  allergies: {
      type: String,
      default: 'Awaiting RSVP'
  },
  table: {
      type: mongoose.Schema.ObjectId,
      ref: 'Table',
  }
});

const tableSchema = new mongoose.Schema({
  name: {
    type: String,
    required: 'Please provide the name of the table',
    trim: true
  },
  capacity: {
    type: Number,
    required: 'Please provide the capacity of the table',
  }
});

2 个答案:

答案 0 :(得分:0)

这只是一种不同的方法,因为您尝试将文档模型用作主要对象,并将多个集合用于不同类型。它听起来像一张桌子只能拥有这么多人,每个人都只能坐在桌子上。

一张桌子可以有很多人,但每张桌子有一个独特的人

一个人只能是一张桌子的一部分。

我个人认为你的用例并不认为在表格和人物中都有引用是一个问题。尝试创建桥表并且NoSQL不一定符合SQL数据库的相同规范化规则将是愚蠢的。话虽如此,更大规模的应用可能会有所不同。我认为人们普遍认为的问题是,每个人都希望将高层架构和复杂理论推向不会真正从中受益的用例。使用并查看有效的方法,并对您的解决方案如何在更大/更复杂的数据集中进行扩展进行一些研究。

即使您的婚礼上有1000人,我也怀疑这是一个问题。作为一个提醒,只是为了一般的做法,最好考虑一下你需要为你的数据类型使用什么类型的数据库。如果你有很多关系数据,MongoDB 可以以这种方式完成,但与传统的SQL DB相比,它在过去的研究和工作中可能会下降。在选择技术之前,应该考虑这些内容。

由于您使用的是Mongoose,因此您可以轻松地通过ObjectId引用其他对象,并且查询应该是直截了当的。

如果您对用户进行拍打,则可以通过Users集合上的表格查询表格。它不必是双向的,因为您的用户只能拥有一个表,所以似乎没有必要同时执行这两个方法。

这样想。例如,您可能有一个包含10个用户的表。 当您查看用户时,您想要找出他/她所在的表格。这意味着当您查询表集合时,您必须查询可能具有另一个用户数组的每个记录。查找可能比查看每个用户的单个属性的方式慢得多。

只是想深入了解您可以采用的不同方式。我不会说什么是最好的,因为可能还有其他变量我没有考虑到。但是,我可能只是把它放在用户自己身上。找出最适合你的方法。

答案 1 :(得分:0)

我会把表号存放在这个人身上,虽然我不知道你会遇到任何另一个方向的问题。

在设计数据库时,儿童应该(通常)提及他们的父母,而不是相反。在我看来,一张桌子“拥有”坐在桌旁的人(一对多的关系),而不是拥有桌子一部分的人,使桌子成为父母。

如果有人移动表,另一个好处是单点更新。您只需更新来宾记录,而不是从一个表中删除并添加到另一个表。

通常对建模决策有帮助的是在更大的范围内查看问题。想象一下,创建一个人们居住地的数据库。您可能希望拥有街道地址属性的人员和链接到状态记录的字段,该状态记录具有链接到国家/地区记录的字段。一旦你概括和扩展你的问题,通常会有一个更清晰的解决方案。

如果采用这种方法,可以使用聚合来确定哪些表未满。

db.guests.aggregate([ {$group : { _id: '$tableId', seatsFilled : {$sum : 1}}} ])