搜尋

首頁  >  問答  >  主體

課程預約系統適合mongodb的場景嗎?

有一個使用者課程預約的項目,因為後端有node來做,所以mongodb是個很好的選擇,可是因為課程預約系統存在使用者預約成功後,或取消預約後,會有課程預約資訊的事務操作,我對mongo的了解是她不適合用在事務場景裡,我對資料庫的設計不是很了解,想請課程預約這樣的專案適合用mongodb嗎?

巴扎黑巴扎黑2789 天前746

全部回覆(1)我來回復

  • 给我你的怀抱

    给我你的怀抱2017-05-02 09:27:40

    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預設會傳回修改之前的文件(也可以傳回修改之後的文件)。所以:

    if (result.reservations.qty < 50) {
        // 报名成功
    } else {
        // 报名失败
    }

    關於findAndModify的用法请参考db.collection.findAndModify()。MongoDB中对一个文档的修改具备原子性,所以不难发现update也可以很好地完成上述任务。关于updatefindAndUpdate的用法請參考db.collection.findAndModify()。 MongoDB中對一個文件的修改具備原子性,所以不難發現update也可以很好地完成上述任務。關於updatefindAndUpdate的比較,可以參考:Compares with update Method

    回覆
    0
  • 取消回覆