MongoDB嵌入式vs大型数据文档的参考架构

时间:2013-03-14 14:57:48

标签: performance mongodb database-design database-schema

我正在为日志管理系统设计我的第一个MongoDB数据库模式,我想将日志文件中的信息存储到mongoDB,我无法确定应该使用哪种模式 用于大型文档(嵌入式vs参考)。

注意:项目有很多来源,源有很多日志(在某些情况下有超过1 000 000个日志)

  {    
      "_id" : ObjectId("5141e051e2f56cbb680b77f9"),   
      "name" : "projectName",
      "source" : [{
          "name" : "sourceName",
          "log" : [{
              "time" : ISODate("2012-07-20T13:15:37Z"),
              "host" : "127.0.0.1",
              "status" : 200.0,
              "level" : "INFO",
              "message" : "test"
            }, {
              "time" : ISODate("2012-07-20T13:15:37Z"),
              "host" : "127.0.0.1",
              "status" : 200.0,
              "level" : "ERROR",
              "message" : "test"
            }]
        }]
    }

我的重点是从数据库读取数据(不写入)时的性能,例如过滤,搜索,分页等。用户可以按日期,状态等过滤源日志(因此我希望在用户搜索或过滤数据时专注于阅读性能)

我知道MongoDB有16Mbyte的文档大小限制,所以我担心如果我要为一个源提供1 000 000个日志这将如何工作(因为我可以为一个项目提供许多源,并且源可以有许多日志)。当我使用大型文档并希望获得良好的阅读性能时,我应该使用嵌入式或参考架构,有什么更好的解决方案?谢谢

2 个答案:

答案 0 :(得分:3)

你的问题的答案都不是。您应该将模式展平为每个日志条目一个doc,而不是嵌入或使用引用,以便它可以扩展到16MB doc限制之外的任何内容,以便您可以访问MongoDB查询功能的全部功能和性能。

因此,请使用以下方法删除数组字段并将所有内容移至顶级字段:

{    
    "_id" : ObjectId("5141e051e2f56cbb680b77f9"),   
    "name" : "projectName",
    "sourcename" : "sourceName",
    "time" : ISODate("2012-07-20T13:15:37Z"),
    "host" : "127.0.0.1",
    "status" : 200.0,
    "level" : "INFO",
    "message" : "test"
  }, {
    "_id" : ObjectId("5141e051e2f56cbb680b77fa"),   
    "name" : "projectName",
    "sourcename" : "sourceName",
    "time" : ISODate("2012-07-20T13:15:37Z"),
    "host" : "127.0.0.1",
    "status" : 200.0,
    "level" : "ERROR",
    "message" : "test"
}

答案 1 :(得分:1)

我认为在数组中登录可能会变得混乱。如果项目和源实体没有任何属性(键),除了名称和日志不能存储很长时间,您可以使用{{3每个文档只有一个日志:

{_id: ObjectId("5141e051e2f56cbb680b77f9"), p: "project_name", s: "source_name", "time" : ISODate("2012-07-20T13:15:37Z"), "host" : "127.0.0.1", "status" : 200.0, "level" : "INFO", "message" : "test"}

也请参考:capped collection

加盖的藏品保持自然秩序。因此,您不需要时间戳索引来按自然顺序返回日志。在您的情况下,您可能希望从特定源/项目中检索所有日志。您可以创建索引{p:1,s:1}以加快此查询速度。

但我建议你做一些'基准测试'来检查性能。尝试上面的上限收集方法。并使用您建议的完全嵌入式架构尝试分段文档。此技术用于经典http://docs.mongodb.org/manual/use-cases/storing-log-data/问题。因此,只有在自定义大小超过的情况下,您才会在单个文档中存储每个源的这么多日志,并溢出到新文档。