PhD*_*PhD 21 database database-design non-relational-database mongodb cascading-deletes
假设以下"模式/关系"设计,使用级联删除操作删除处理删除的推荐做法是什么?
关系模式:
+---------+ +--------+ | Student |-*--------1-[Enrollment]-1--------*-| Course | +---------+ +--------+
MongoDB的:
+---------+ +--------+ | Student |-*----------------*-| Course | +---------+ +--------+
考虑到学生的课程招生的这一经典设计,具有学生,反之亦然课程集合似乎使用MongoDB的(即没有为关系/报名表)时是合适的数据模型.但是来自关系世界我应该如何处理删除课程的语义?也就是说,当删除课程时,也应删除所有"注册"记录.也就是说,我应该从每个学生记录的集合中删除该课程.看起来我必须触发2个查询:一个用于删除课程,然后从每个学生的集合中删除它.有没有办法让单个查询执行这种"级联删除",如语义而无需额外的查询?数据模型是否需要更改?
注意:对于所有其他用例,上述数据模型工作正常:
=>只会删除该学生以及随之删除的相关课程集.=>的学生只需将其从学生课程集中删除即可=>只是将其添加到相应的"表格"中.唯一棘手的事情是处理删除课程.我应该如何处理MongoDB中的这种情况,因为我来自关系背景,我无法弄清楚这一点.
小智 11
你正在做的是在Mongo中做到这一点的最佳和最佳方式.我处于类似的情况,在完成N:M设计模式的所有可能实现后,也达到了同样的解决方案.
显然,这不是一个mongodb的事情,而是更多的NoSQL概念,其中,变化较少的数据(课程)可以单独保存.并且由于删除课程不会是一个非常频繁的操作,它的可行性足以通过所有记录来删除它.
另一方面,你可以让它成为现实.在您的应用程序逻辑中,只需忽略Student文档中课程文档中根本没有reference_id的课程值.但在这种情况下,您必须确保旧的已删除的Course_id不会被重用.
或者只使用课程文档中的已删除标志,并处理应用程序逻辑中的所有其他内容.
我将根据 Mongo 团队的建议进行回答。我也来自关系数据库,在开始理解这些概念时遇到了一些问题。Mongo 团队建议以“应用程序驱动”模式的思想进行设计,因此您必须首先弄清楚哪些数据块在一起。请记住,Mongo 中没有任何可能的事务概念,即使我们发明了一个处理事务的驱动程序,我们也应该为此实现我们自己的解决方案。这意味着如果我有两个业务对象需要始终同时更新,并且我不能容忍此操作失败,我必须将它们合并为一个文档(原子)。
在您的情况下,您有两个文档,学生和课程,以及两者之间的关系(一名学生注册 N 门课程)。我认为课程不需要一直更改,因此它们可以存储在不同的集合中。但重点是它们之间的关系,在这种情况下,您需要原子地删除一个学生及其注册的所有课程。因此,最合适的解决方案是将关系嵌入到学生中,并保留一个单独的课程集合。当您删除学生时,关系同时被删除:
学生杰森:
{ _id: ObjectId('...'), name:"John", lastname:"Smith",
courses: [ 1, 100, 50, 67 ], ...
}
Run Code Online (Sandbox Code Playgroud)
课程可以是它们之间的单独集合。这是在 Mongo 中处理它的方法。原子操作必须嵌入到单个文档中。我认为课程是一个没有太大变化的课程列表,如果它们是由学生设计的,我们可以稍微改变一下解决方案。
| 归档时间: |
|
| 查看次数: |
13911 次 |
| 最近记录: |