V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐工具
RoboMongo
推荐书目
50 Tips and Tricks for MongoDB Developers
Related Blogs
Snail in a Turtleneck
013231
V2EX  ›  MongoDB

對於關係數據庫中的 INNER JOIN, MongoDB 有什麼好的解決方案嗎?

  •  
  •   013231 · 2014-06-17 00:01:04 +08:00 · 4496 次点击
    这是一个创建于 3811 天前的主题,其中的信息可能已经有所发展或是发生改变。
    不少文章中建議用embedded document或manual references解決問題, 但這顯然不適用於所有場景.
    以如下場景為例:
    有collection cars, 記錄的是每輛汽車的信息:
    {_id:...,
    owner:...,
    plate_number:...,
    location:...,
    model:<model_id>,
    ...
    }
    另一個collection models, 記錄的是每種汽車型號的參數:
    {_id:<model_id>,
    name:...,
    transmission:...,
    displacement:...,
    seats:...,
    ...
    }
    cars和models中的記錄數都是數萬條. 現在需要檢索出所有排量少於2L的自動擋車輛. 對於關係數據庫, 可以使用INNER JOIN非常簡單的解決這個問題, 但在MongoDB中麻煩許多.
    如果想用embedded document解決問題, 就要將原本存於models的型號參數放入cars, 這顯然不是一個好主意.
    如果用manual references,可以先查詢出符合條件的型號列表, 再查找相應車輛:
    modelLst = models.find({transmission: 'A', displacement: {$lt: 2}}, {_id: 1}).map(function(item) {return item['_id']})
    cars.find({model: {$in: modelLst}})
    這樣做也有一個問題: $in查詢花費的時間和modelLst的長度是O(n)關係, 當modelLst較大時, 這個查詢會花費過多的時間. 在cars的model上建立索引不能解決此問題.

    對於以上場景, 你們會如何處理?
    4 条回复    2014-06-17 11:18:40 +08:00
    breeswish
        1
    breeswish  
       2014-06-17 00:33:21 +08:00
    所以MongoDB才叫做非关联数据库。

    一般使用专业的ODM框架都可以无痛地解决这种问题
    love
        2
    love  
       2014-06-17 05:58:20 +08:00 via Android
    將原本存於models的型號參數放入cars, 這顯然不是一個好主意

    为查询建模,这在mongodb就是正解啊,那里不好了?
    013231
        3
    013231  
    OP
       2014-06-17 09:28:38 +08:00
    @love 產生大量數據冗餘, 提高維護複雜度.
    love
        4
    love  
       2014-06-17 11:18:40 +08:00
    @013231 实际用用你会发现这不是问题。NOSQL就是用空间换时间,得到随意扩展容量的能力。如果你要用sql方式也不是不可以,直接弄个二层循环手工join就行,效率降到sql水平而已,也不能平稳扩展。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3291 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 04:51 · PVG 12:51 · LAX 20:51 · JFK 23:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.