84669 Lernen von Personen
152542 Lernen von Personen
20005 Lernen von Personen
5487 Lernen von Personen
7821 Lernen von Personen
359900 Lernen von Personen
3350 Lernen von Personen
180660 Lernen von Personen
48569 Lernen von Personen
18603 Lernen von Personen
40936 Lernen von Personen
1549 Lernen von Personen
1183 Lernen von Personen
32909 Lernen von Personen
有一个用户课程预约的项目,因为后端有node来做,所以mongodb是个很好的选择,可是因为课程预约系统存在 用户预约成功后,或取消预约后,会有课程预约信息的事务操作,我对mongo的了解是她不适合用在事务场景里,我对数据库的设计不是很了解,想请问课程预约这样的项目适合用mongodb吗?
MongoDB不适合用于强事务的场景,但很多场景需要的往往不是真的强事务,而可以用最终一致性取而代之。很多强事务也可以通过数据模型设置的技巧转变成MongoDB的文档原子性从而避免强事务。你需要更清楚地描述你所说的事务到底是怎样的场景,才好判断是不是可以避免。对于我自己理解的课程预约场景来说,并不是一个很强的非MongoDB不可的场景,但也不是一个非RDBMS不可的场景。所以要说是不是适合用MongoDB,还是建议具体情况具体分析。=== 2017.4.9 更新 ===根据评论里的更新,做以下补充说明:限制人数这个需求来说可以用MongoDB的文档原子性来解决。我理解的报名这个场景来讲,无非是记录谁报了哪个课程,一共多少人报了,以及控制不要超报名限额。那么课程的数据结构可以设计成类似这样:
{ _id: ObjectId("58e9f6cd58d2c10959c8619a"), title: "MongoDB入门教程", intro: "演示用", createdAt: ISODate("2017-04-09T17:00:00Z"), createdBy: { userId: 12345, name: "MongoDB中文社区" // 其他必要的信息 }, allowedAttendeeQty: 50, // 允许参与的人数 reservations: { qty: 0, // 已预订人数 attendees: [123, 456, 789] // 参与人员ID } }
当有人报名时,可以对这个课程进行更新:
var result = db.class.findAndUpdate( query: { _id: ObjectId("58e9f6cd58d2c10959c8619a"), qty: {$lte: 50} // 保证已报名人数小于50时才报名 }, update: { $inc: { "reservations.qty": 1 // 报名人数+1 }, $push: { "reservations.attendees": 102 // 新报名人员ID } } });
也就是说,按照课程ID来查找这个课程,报名人数小于指定的数量时,会把新的报名人加进去,否则不会做任何更改。那么如何判断报名是否成功呢?findAndModify默认会返回修改之前的文档(也可以返回修改之后的文档)。所以:
findAndModify
if (result.reservations.qty < 50) { // 报名成功 } else { // 报名失败 }
关于findAndModify的用法请参考db.collection.findAndModify()。MongoDB中对一个文档的修改具备原子性,所以不难发现update也可以很好地完成上述任务。关于update和findAndUpdate的比较,可以参考:Compares with update Method
update
findAndUpdate
MongoDB不适合用于强事务的场景,但很多场景需要的往往不是真的强事务,而可以用最终一致性取而代之。很多强事务也可以通过数据模型设置的技巧转变成MongoDB的文档原子性从而避免强事务。你需要更清楚地描述你所说的事务到底是怎样的场景,才好判断是不是可以避免。
对于我自己理解的课程预约场景来说,并不是一个很强的非MongoDB不可的场景,但也不是一个非RDBMS不可的场景。所以要说是不是适合用MongoDB,还是建议具体情况具体分析。
=== 2017.4.9 更新 ===
根据评论里的更新,做以下补充说明:
限制人数这个需求来说可以用MongoDB的文档原子性来解决。我理解的报名这个场景来讲,无非是记录谁报了哪个课程,一共多少人报了,以及控制不要超报名限额。那么课程的数据结构可以设计成类似这样:
当有人报名时,可以对这个课程进行更新:
也就是说,按照课程ID来查找这个课程,报名人数小于指定的数量时,会把新的报名人加进去,否则不会做任何更改。那么如何判断报名是否成功呢?
findAndModify
默认会返回修改之前的文档(也可以返回修改之后的文档)。所以:关于
findAndModify
的用法请参考db.collection.findAndModify()。MongoDB中对一个文档的修改具备原子性,所以不难发现update
也可以很好地完成上述任务。关于update
和findAndUpdate
的比较,可以参考:Compares with update Method