Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用基于文档的nosql(mongodb、couchdb和riak等)查询关系数据的性能_Mongodb_Couchdb_Rdbms_Riak_Nosql - Fatal编程技术网

使用基于文档的nosql(mongodb、couchdb和riak等)查询关系数据的性能

使用基于文档的nosql(mongodb、couchdb和riak等)查询关系数据的性能,mongodb,couchdb,rdbms,riak,nosql,Mongodb,Couchdb,Rdbms,Riak,Nosql,为了跟进我的问题,我读了几篇关于这个主题的文章: 他们似乎认为nosql可以处理规范化的关系数据 让我们继续我之前的例子,一个CMS系统,它有两种类型的数据:article和authors,其中article有一个对author的引用(通过ID) 以下是系统需要支持的操作: 按id和作者一起获取文章 按特定作者获取所有文章 查找前10篇文章,作者按创作日期排序 如果相同的数据存储在RDBMS上,与相同的操作相比,我想了解这些操作的性能特别是,请指定操作是否使用MapReduce,是否需要多次

为了跟进我的问题,我读了几篇关于这个主题的文章:

他们似乎认为nosql可以处理规范化的关系数据

让我们继续我之前的例子,一个CMS系统,它有两种类型的数据:article和authors,其中article有一个对author的引用(通过ID)

以下是系统需要支持的操作:

  • 按id和作者一起获取文章
  • 按特定作者获取所有文章
  • 查找前10篇文章,作者按创作日期排序
  • 如果相同的数据存储在RDBMS上,与相同的操作相比,我想了解这些操作的性能特别是,请指定操作是否使用MapReduce,是否需要多次访问nosql存储(链接),或

    我想只讨论基于文档的nosql解决方案,如mongodb、couchdb和riak

    编辑1:


    在Riak和Mongodb上可用。对于Mongodb,您不会将嵌入文档用于作者记录。因此,预连接已退出,它是到数据库的多次访问。但是,您可以缓存作者,并且只需要对每条记录进行第二次访问。您指出的查询在MongoDB中非常简单

    var article = db.articles.find({id: article_id}).limit(1);
    var author = db.authors.find({id: article.author_id});
    
    如果您使用ORM/ODM来管理应用程序中的实体,这将是透明的。不过去db要两次。他们的反应应该很快,但两个点击根本不应该被注意到

    查找给定作者的文章正好相反

    var author = db.authors.find({id: author_name}).limit(1);
    var articles = db.articles.find({author_id: author.id});
    
    同样,两个查询(但单个作者获取)应该很快,并且可以很容易地缓存

    var articles = db.articles.find({}).sort({created_at: 1}).limit(10);
    var author_ids = articles.map(function(a) { return a.author_id });
    var authors = db.authors.find({id: { '$in': authors_ids }});
    
    最后,还是两个查询,只是稍微复杂一点。您可以在mongo shell中运行这些命令,以查看结果

    我不确定这是否值得写一个地图来完成。几次快速往返可能会有更多的延迟,但mongo协议相当快。我不会过分担心的

    最后,这样做的实际性能影响。。。因为理想情况下,您只需要查询文档中的索引字段,所以应该非常快。唯一的额外步骤是第二次往返以获取其他文档,这取决于应用程序和数据库的结构,这可能根本不是什么大问题。您可以告诉mongo只评测超过给定阈值的查询(打开时默认为100或200毫秒),这样您就可以关注随着数据的增长程序所花费的时间

    RDMS不提供的一种适合您的方法是更容易地分解数据。当您将应用程序扩展到CMS之外以支持其他内容,但使用相同的身份验证存储时,会发生什么情况?它现在正好是一个完全独立的数据库,在许多应用程序中共享。跨dbs执行这些查询要简单得多——使用RDMS存储,这是一个复杂的过程

    我希望这对您的NoSQL发现有所帮助

    按id和作者一起获取文章

    SQL

    • 1查询
    • 2索引查找
    • 2数据查找
    • 返回的数据=文章+作者
    MongoDB

    • 2查询
    • 2索引查找
    • 2数据查找
    • 返回的数据=文章+作者
    按特定作者获取所有文章

    SQL

    • 1查询
    • 1索引查找
    • N数据查找
    • 返回的数据=N个项目
    MongoDB

    • 1查询
    • 1索引查找
    • N数据查找
    • 返回的数据=N个项目
    查找前10篇文章,作者按创作日期排序

    SQL

    • 1查询
    • 2索引查找
    • 11到20个数据查找(文章然后是唯一作者)
    • 返回的数据=10篇文章+10位作者
    MongoDB

    • 2个查询(
      articles.find().sort().limit(10)
      authors.find({$in:[article\u authors]})
    • 2索引查找
    • 11到20个数据查找(文章然后是唯一作者)
    • 返回的数据=10篇文章+1到10位作者

    摘要

    在两种情况下,MongoDB需要一个额外的查询,但在下面执行大部分相同的工作。在某些情况下,MongoDB通过网络返回的数据较少(没有重复条目)。联接查询往往受到以下要求的限制:所有要联接的数据都位于同一个框中。如果作者和文章位于不同的位置,则您最终会执行两个查询

    MongoDB倾向于获得更好的“原始”性能,因为它不会在每次写入时刷新到磁盘(因此它实际上是一种“持久性”权衡)。它还有一个更小的查询解析器,因此每个查询的活动更少


    从基本性能的角度来看,这些东西非常相似。它们只是对您的数据和您想要进行的权衡做出了不同的假设。

    只是想为任何可能好奇的人提供一个CouchDB答案。:)

    正如上面第一个答案中提到的,将author文档嵌入到article文档中是不明智的,因此下面的示例假设两种文档类型:articles和authors

    CouchDB使用通常用JavaScript编写的MapReduce查询(但Python、Ruby、Erlang和其他可用)。MapReduce查询的结果在第一次请求时存储在一个索引中,该存储的索引用于将来的所有查找。对数据库的更改将在进一步请求时添加到索引中

    CouchDB的API完全基于HTTP,因此对数据库的所有请求都是各种URL上的HTTP动词(GET、POST、PUT、DELETE)。我会的 GET /db/{article_id} GET /db/{author_id}
    function (doc) {
      if (doc.type === 'article') {
        emit(doc.author_id, doc);
      }
    }
    
    GET /db/_design/cms/_view/articles_by_author?key="{author_id}"
    function (doc) {
      function arrayDateFromTimeStamp(ts) {
        var d = new Date(ts);
        return [d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds()];
      }
    
      var newdoc = doc;
      newdoc._id = doc.author_id;
      newdoc.created_at = arrayDateFromTimeStamp(doc.created_at);
    
      if (doc.type === 'article') {
        emit(newdoc.created_at, newdoc); 
      }
    }
    
    GET /db/_design/cms/_view/articles_by_date?descending=true&limit=10&include_docs=true {"rows":[ { "id":"article_id", "key":[2011, 9, 3, 12, 5, 41], "value":{"_id":"author_id", "title":"..."}, "doc":{"_id":"author_id", "name":"Author Name"} } ]}