❶ 如何正确的使用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中使用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" : "其他门诊"
}]
}
}
❸ mongodb 集合中 数据 文档 什么意思
简介MongoDB1是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB2是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。3特点它的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有: *面向集合存储,易存储对象类型的数据…
例句:
1.
Some, like mongodb, help to develop open source technologies.
一些工具,比如MongoDB,能够帮助开发开源技术。
❹ mongodb的基本概念
(1)文档
文档是 MongoDB 中数据的基本单位,类似于关系数据库中的行(但是比行复杂)。多个键及其关联的值有序地放在一起就构成了文档。不同的编程语言对文档的表示方法不同,在JavaScript 中文档表示为:
{“greeting”:“hello,world”}
这个文档只有一个键“greeting”,对应的值为“hello,world”。多数情况下,文档比这个更复杂,它包含多个键/值对。例如:
{“greeting”:“hello,world”,“foo”: 3}
文档中的键/值对是有序的,下面的文档与上面的文档是完全不同的两个文档。
{“foo”: 3 ,“greeting”:“hello,world”}
文档中的值不仅可以是双引号中的字符串,也可以是其他的数据类型,例如,整型、布尔型等,也可以是另外一个文档,即文档可以嵌套。文档中的键类型只能是字符串。
(2)集合
集合就是一组文档,类似于关系数据库中的表。集合是无模式的,集合中的文档可以是各式各样的。例如,{“hello,word”:“Mike”}和{“foo”: 3},它们的键不同,值的类型也不同,但是它们可以存放在同一个集合中,也就是不同模式的文档都可以放在同一个集合中。既然集合中可以存放任何类型的文档,那么为什么还需要使用多个集合?这是因为所有文档都放在同一个集合中,无论对于开发者还是管理员,都很难对集合进行管理,而且这种情形下,对集合的查询等操作效率都不高。所以在实际使用中,往往将文档分类存放在不同的集合中,例如,对于网站的日志记录,可以根据日志的级别进行存储,Info级别日志存放在Info 集合中,Debug 级别日志存放在Debug 集合中,这样既方便了管理,也提供了查询性能。但是需要注意的是,这种对文档进行划分来分别存储并不是MongoDB 的强制要求,用户可以灵活选择。
可以使用“.”按照命名空间将集合划分为子集合。例如,对于一个博客系统,可能包括blog.user 和blog.article 两个子集合,这样划分只是让组织结构更好一些,blog 集合和blog.user、blog.article 没有任何关系。虽然子集合没有任何特殊的地方,但是使用子集合组织数据结构清晰,这也是MongoDB 推荐的方法。
(3)数据库
MongoDB 中多个文档组成集合,多个集合组成数据库。一个MongoDB 实例可以承载多个数据库。它们之间可以看作相互独立,每个数据库都有独立的权限控制。在磁盘上,不同的数据库存放在不同的文件中。MongoDB 中存在以下系统数据库。
● Admin 数据库:一个权限数据库,如果创建用户的时候将该用户添加到admin 数据库中,那么该用户就自动继承了所有数据库的权限。
● Local 数据库:这个数据库永远不会被负责,可以用来存储本地单台服务器的任意集合。
● Config 数据库:当MongoDB 使用分片模式时,config 数据库在内部使用,用于保存分片的信息。
❺ 如何删除MongoDB数据库中的文件
一、Insert操作
Insert操作是MongoDB插入数据的基本方法,对目标集合使用Insert操作,会将该文档添加到MongoDB并自动生成相应的ID键。文档结构采用类似JSON的BSON格式。常见的插入操作主要有单条插入和批量插入两种形式。插入时只是简单地将文档存入数据库中,不进行额外的验证,也不会执行代码,所以不存在注入式攻击的可能。
1、单条插入
四、瞬间完成
上面的插入,删除和更新操作都是瞬间完成的,不需要等待数据库响应。这样的实现可以获取高性能,速度非常快,只会受客户端发送速度和网络速度的制约。但由于不会获取服务器状态,所以不能保证操作顺利完成。这对于付费系统,安全性较高的系统是不可行的,此时对这些操作需要使用的安全版本。安全版本会在操作执行后立即运行getLastError命令,来检查是否执行成功。如果失败一般会抛出可捕获的异常,然后可以在代码中处理。
❻ 如何保证文档内容唯一 mongodb
在MongoDB中,如果不特别指定,每个文档都会生成一个唯一的ObjectId作为其主键_id的值。这个值是一个看似随机的串。这个串到底是什么值?为什么MongoDB要使用这个值作为默认主键?它内部又包含了什么样的信息?如果你还不了解,就请看下面文章吧。
MongoDB中数据的基本单元称为文档(Document)。文档是MongoDB的核心概念,多个键极其关联的值有序的放置在一起便是文档。
在一个特定集合内部,需要唯一的标识文档。因此MongoDB中存储的文档都由一个”_id”键,用于完成此功能。这个键的值可以是任意类型的,默认试ObjectId对象。ObjectId对象的生成思路是本文的主题,也是很多分布式系统可以借鉴的思路。
为了考虑分布式,“_id”要求不同的机器都能用全局唯一的同种方法方便的生成它。因此不能使用自增主键(需要多台服务器进行同步,既费时又费力),因此选用了生成ObjectId对象的方法。
ObjectId使用12字节的存储空间,其生成方式如下:
0 1 2 3 4 5 6 7 8 9 10 11
时间戳 机器ID PID 计数器
前四个字节时间戳是从标准纪元开始的时间戳,单位为秒,有如下特性:
时间戳与后边5个字节一块,保证秒级别的唯一性;
保证插入顺序大致按时间排序;
隐含了文档创建时间;
机器ID是服务器主机标识,通常是机器主机名的散列值。
同一台机器上可以运行多个mongod实例,因此也需要加入进程标识符PID。
前9个字节保证了同一秒钟不同机器不同进程产生的ObjectId的唯一性。后三个字节是一个自动增加的计数器(一个mongod进程需要一个全局 的计数器),保证同一秒的ObjectId是唯一的。同一秒钟最多允许每个进程拥有(256^3 = 16777216)个不同的ObjectId。
总结一下:时间戳保证秒级唯一,机器ID保证设计时考虑分布式,避免时钟同步,PID保证同一台服务器运行多个mongod实例时的唯一性,最后的计数器保证同一秒内的唯一性(选用几个字节既要考虑存储的经济性,也要考虑并发性能的上限)。
“_id”既可以在服务器端生成也可以在客户端生成,在客户端生成可以降低服务器端的压力。
❼ mongodb 索引是什么数据结构
MongoDB索引使用B-tree数据结构。
索引支持MongoDB中查询的高效执行。如果没有索引,MongoDB必须执行集合扫描,即扫描集合中的每个文档,以选择与查询语句匹配的文档。如果查询存在适当的索引,MongoDB可以使用索引来限制它必须检查的文档数。
(7)manggodb过滤文档扩展阅读
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中还有其它如哈希索引,地理位置索引以及文本索引,主要用于一些特定场景。