㈠ 如何正确的使用MongoDB并优化其性能
数据库性能对软件整体性能的影响是不言而喻的,那么,当我们使用MongoDB时改如何提高数据库性能呢?
1.范式化与反范式化
在项目设计阶段,明确集合的用途是对性能调优非常重要的一步。
从性能优化的角度来看,集合的设计我们需要考虑的是集合中数据的常用操作,例如我们需要设计一个日志(log)集合,日志的查看频率不高,但写入频率却很高,那么我们就可以得到这个集合中常用的操作是更新(增删改)。如果我们要保存的是城市列表呢?显而易见,这个集合是一个查看频率很高,但写入频率很低的集合,那么常用的操作就是查询。
对于频繁更新和频繁查询的集合,我们最需要关注的重点是他们的范式化程度,在上篇范式化与反范式化的介绍中我们了解到,范式化与反范式化的合理运用对于性能的提高至关重要。然而这种设计的使用非常灵活,假设现在我们需要存储一篇图书及其作者,在MongoDB中的关联就可以体现为以下几种形式:
1.完全分离(范式化设计)
示例1:
View Code
{
"_id" : ObjectId("5124b5d86041c7dca81917"),
"title" : "如何使用MongoDB",
"author" : [
ObjectId("144b5d83041c7dca84416"),
ObjectId("144b5d83041c7dca84418"),
ObjectId("144b5d83041c7dca84420"),
]
}
我们将作者(comment) 的id数组作为一个字段添加到了图书中去。这样的设计方式是在非关系型数据库中常用的,也就是我们所说的范式化设计。在MongoDB中我们将与主键没有直接关系的图书单独提取到另一个集合,用存储主键的方式进行关联查询。当我们要查询文章和评论时需要先查询到所需的文章,再从文章中获取评论id,最后用获得的完整的文章及其评论。在这种情况下查询性能显然是不理想的。但当某位作者的信息需要修改时,范式化的维护优势就凸显出来了,我们无需考虑此作者关联的图书,直接进行修改此作者的字段即可。
2.完全内嵌(反范式化设计)
示例2:
View Code
{
"_id" : ObjectId("5124b5d86041c7dca81917"),
"title" : "如何使用MongoDB",
"author" : [
{
"name" : "丁磊"
"age" : 40,
"nationality" : "china",
},
{
"name" : "马云"
"age" : 49,
"nationality" : "china",
},
{
"name" : "张召忠"
"age" : 59,
"nationality" : "china",
},
]
}
在这个示例中我们将作者的字段完全嵌入到了图书中去,在查询的时候直接查询图书即可获得所对应作者的全部信息,但因一个作者可能有多本著作,当修改某位作者的信息时时,我们需要遍历所有图书以找到该作者,将其修改。
3.部分内嵌(折中方案)
示例3:
View Code
{
"_id" : ObjectId("5124b5d86041c7dca81917"),
"title" : "如何使用MongoDB",
"author" : [
{
"_id" : ObjectId("144b5d83041c7dca84416"),
"name" : "丁磊"
},
{
"_id" : ObjectId("144b5d83041c7dca84418"),
"name" : "马云"
},
{
"_id" : ObjectId("144b5d83041c7dca84420"),
"name" : "张召忠"
},
]
}
这次我们将作者字段中的最常用的一部分提取出来。当我们只需要获得图书和作者名时,无需再次进入作者集合进行查询,仅在图书集合查询即可获得。
这种方式是一种相对折中的方式,既保证了查询效率,也保证的更新效率。但这样的方式显然要比前两种较难以掌握,难点在于需要与实际业务进行结合来寻找合适的提取字段。如同示例3所述,名字显然不是一个经常修改的字段,这样的字段如果提取出来是没问题的,但如果提取出来的字段是一个经常修改的字段(比如age)的话,我们依旧在更新这个字段时需要大范围的寻找并依此进行更新。
在上面三个示例中,第一个示例的更新效率是最高的,但查询效率是最低的,而第二个示例的查询效率最高,但更新效率最低。所以在实际的工作中我们需要根据自己实际的需要来设计表中的字段,以获得最高的效率。
㈡ mongodb 索引是什么数据结构
MongoDB索引使用B-tree数据结构。
索引支持MongoDB中查询的高效执行。如果没有索引,MongoDB必须执行集合扫描,即扫描集合中的每个文档,以选择与查询语句匹配的文档。如果查询存在适当的索引,MongoDB可以使用索引来限制它必须检查的文档数。
(2)mongodb关键词过滤扩展阅读
MongoDB索引的类型
1、单字段索引(Single Field Index)
这个是最简单最常用的索引类型,比如我们上边的例子,为id建立一个单独的索引就是此种类型。
2、复合索引(Compound Index)
索引field的先后顺序很关键,影响有两方面:
(1)MongoDB在复合索引中是根据prefix排序查询,就是说排在前面的可以单独使用。
(2)过滤出的document越少的field越应该放在前面,比如此例中id如果是唯一的,那么就应该放在最前面,因为这样通过id就可以锁定唯一一个文档。而如果通过city或者score过滤完成后还是会有大量文档,这就会影响最终的性能。
索引的排序顺序不同:复合索引最末尾的field,其排序顺序不同对于MongoDB的查询排序操作是有影响的。
3、多key索引(Multikey Index):主要针对数据类型为数组的类型。
4、其它类型索引:另外,MongoDB中还有其它如哈希索引,地理位置索引以及文本索引,主要用于一些特定场景。
㈢ MongoDB问题,下载完配置好服务可以连接但就是无法进入数据库似乎缺少什么东西但不知道怎么解决
@MongoDB安装后的一些简要配置:
1)在和bin目录同级的目录下面建一个data文件夹,data文件夹下面分别建立db和log文件夹来存储数据文件和日志文件【ps:也可以建立其他文件夹,自己知道在什么地方即可】
2)在和bin目录同级的目录下面建一个mongo.config文件(编码格式为utf8无bom格式,否则会报错),作为mongodb的配置文件。[ps:在启动的时候会用到]
---mongo.config文件内容如下:
##数据文件
dbpath=D:\mongodb\data\db
##日志文件
logpath=D:\mongodb\data\log\mongo.log
#错误日志采用追加模式,配置这个选项后mongodb的日志会追加到现有的日志文件,而不是从新创建一个新文件
logappend=true
#启用日志文件,默认启用
journal=true
#这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false
㈣ PHP操作MongoDB,怎么把一个集合转为数组
简单的格式匹配用脚本或者批处理就行了。
linux shell可以很容易的过滤出你想要的关键字,windows下的DOS批处理应该也可以。
㈤ mongoDB聚合查询中$unwind为什么拆分的不彻底
mongodb中使用aggregate可以返回数组字段数组的指定索引的元素参考语句: {$match:{'id':15}}, {$project:{id:1,"default":1}}, {$unwind:"$default.styles"}, {$match:{'default.styles.status':1}}, {$group:{_id:"$_id","defaults":{$push:"$default.styles"}}} 解释: 1:过滤数据{$match:{'id':15}} 2:获取想要的列{$project:{id:1,"default":1}} 3:获取展开后数组字段{$unwind:"$default.styles"} 4:条件查询数组元素{$match:{'default.styles.status':1}} 5:分组后保存结果{$group:{_id:"$_id","defaults":{$push:"$default.styles"}}}
㈥ 使用SpringMVC + MongoDB时,用or条件匹配关键字时遇到的问题
使用SpringMVC + MongoDB时,用or条件匹配关键字时遇到的问题如下:
在使用SpringMVC框架时,配置web.xml文件时,springDispatcherServlet的配置:
㈦ mongodb 一个文档内数组中同一个字段 同时大于或小于一个值,如何写查询条件
mongodb中使用aggregate可以返回数组字段数组的指定索引的元素
参考语句:
{$match:{'id':15}},
{$project:{id:1,"default":1}},
{$unwind:"$default.styles"},
{$match:{'default.styles.status':1}},
{$group:{_id:"$_id","defaults":{$push:"$default.styles"}}}
解释:
1:过滤数据{$match:{'id':15}}
2:获取想要的列{$project:{id:1,"default":1}}
3:获取展开后数组字段{$unwind:"$default.styles"}
4:条件查询数组元素{$match:{'default.styles.status':1}}
5:分组后保存结果{$group:{_id:"$_id","defaults":{$push:"$default.styles"}}}
数据结构如下:
{
"_id" : ObjectId("55dad346ea23e7c11beefce5"),
"id" : 11.0,
"default" : {
"style" : "普通会诊",
"alias" : "",
"money" : "0",
"styles" : [{
"code" : 1,
"style" : "普通会诊",
"alias" : "一般会诊",
"money" : 100,
"status" : 1,
"remark" : "需要患者亲自来到医院"
} {
"code" : 6,
"style" : "夜间门诊",
"alias" : "夜间门诊",
"money" : 100,
"status" : 0,
"remark" : "夜间门诊"
}, {
"code" : 7,
"style" : "其他门诊",
"alias" : "其他门诊",
"money" : 10,
"status" : 0,
"remark" : "其他门诊"
}]
}
}