简体   繁体   English

在 MongoDB 中设计多对多关系(而不是关系表)

[英]Designing Many-to-Many relationships in MongoDB (instead of relational tables)

Using a classic example - Suppose that we have an application which has a Courses collection and a Students collection, while each student can participate in many courses, and each course can have many participants.使用一个经典的例子——假设我们有一个应用程序,它有一个 Courses 集合和一个 Students 集合,而每个学生可以参加很多课程,每个课程可以有很多参与者。 We will need to query all the courses that one student participates in efficiently, But we also need to query the students those are participating in a single course.我们将需要查询一个学生有效参与的所有课程,但我们还需要查询正在参加单个课程的学生。

I know that using relational database to handle this will be the optimal solution, but for now I just want to use one type of databases which is MongoDB, now I want to ask if this schema design could work efficiently?我知道使用关系数据库来处理这将是最佳解决方案,但现在我只想使用一种类型的数据库,即 MongoDB,现在我想问一下这种架构设计是否可以有效地工作? what is the cons and pros of using it?使用它的优缺点是什么? and which design could be better?哪个设计会更好?

User: {
   _id,
   //...properties
}

Course: {
   _id,
   //...properties
}

CourseParticipate: {
   _id,
   userId,
   courseId,
   //...properties
}

CourseAdmin: {
   _id,
   userId,
   courseId,
   //...properties
}

Now I like this design because in the future if I have the ability to work with multiple databases, it will be easy to transfer these collections to a relational DB (or not?), I also like it becayse it is fast to write the data and to remove the relations between the objects, but it will make the reading queries a little bit slower(or a lot?) as I can see.现在我喜欢这个设计,因为将来如果我有能力使用多个数据库,很容易将这些 collections 转移到关系数据库(或不?),我也喜欢它,因为它写入数据很快并删除对象之间的关系,但正如我所见,它会使阅读查询慢一点(或很多?)。

Because I never seen this design before in the internet, I already know that there is better solutions (I hope that I don't hear heartful comments and answers because I'm new).因为我之前在网上没见过这个设计,所以我已经知道有更好的解决方案(我希望我没有听到发自内心的评论和回答,因为我是新人)。

I also want to hear from you whether Neo4j can handle this problem or not?我也想听听你说 Neo4j 能不能解决这个问题? and what relational DBs works the best next to MongoDB?什么关系数据库在 MongoDB 旁边效果最好?

Links to documentations and articles will be very helpful!文档和文章的链接将非常有帮助! Thanks!谢谢!

This is a case of having the data with Many-to-Many relationship.这是具有多对多关系的数据的情况。 I would think there are few thousand students and a few hundred courses in your database.我认为您的数据库中有几千名学生和几百门课程。

To start with I can use the following design with course details embedded with each student as an array of sub-documents called as courses .首先,我可以使用以下设计,每个学生都嵌入课程详细信息,作为称为courses的子文档数组。

- students collection
id:
name:
courses: [ { id: 1, name: },  { id: 5, name: }, ... ]

- courses collection
id:
name:
description:

Note, the course id and name are stored in both collections.请注意,课程 ID 和名称都存储在 collections 中。 This is duplication of data.这是数据的重复。 This should be okay, as the duplicated details do not change often (or may not change at all).这应该没问题,因为重复的细节不会经常更改(或可能根本不会更改)。

Query all courses a student is enrolled into, for example: db.students.find( { name: "John" } ) .查询学生注册的所有课程,例如: db.students.find( { name: "John" } ) This will return one student document with the matching name and all the courses (the array field).这将返回一个具有匹配名称的学生文档和所有课程(数组字段)。 See db.collection.find .请参阅db.collection.find

Query all students enrolled into a particular course: db.students.find( { "courses.name": "Java Programming" } ) .查询所有注册特定课程的学生: db.students.find( { "courses.name": "Java Programming" } ) This will return all the student documents who have the course name matching the criteria "java Programming".这将返回课程名称与标准“java Programming”匹配的所有学生文档。 See Query an Array of Embedded Documents .请参阅查询嵌入式文档数组

Further, you can use projection to exclude and include fields from the result.此外,您可以使用投影从结果中排除和包含字段。

NOTES:笔记:

  • You can embed students info within the courses collection, instead of the courses into the students.您可以将学生信息嵌入课程集合中,而不是将课程嵌入学生中。 The queries will be similar to the above ones, but you will be querying the courses collection.查询将与上述查询类似,但您将查询课程集合。 It depends upon your use case.这取决于您的用例。
  • You can just store the course id field in the courses array, of the students collection;您可以将课程 ID 字段存储在学生集合的课程数组中; this is the case where you have course name field changes often.这是您经常更改课程名称字段的情况。 The queries will use Aggregation $lookup (a "join" operation) to get the course and from the courses collection.查询将使用 Aggregation $lookup (“加入”操作)来获取课程并从课程集合中获取。
  • Information on Data Model Design for document based MongoDB data. 数据信息 Model 基于文档的 MongoDB 数据的设计

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM