zoukankan      html  css  js  c++  java
  • MongoDB入门

    《MongoDB权威指南》的读书笔记。

    1 开始使用MongoDB

    1.1 启动MongoDB

    Windows平台下在Cygwin中启动MongoDB,要注意的是:

    • 需要手动创建/data/db文件夹 mkdir -p /data/db
    • 要为/data/db设置正确的权限 chown -R user:group /data

    现在就可以启动MongoDB了。我是将data文件夹建在MongoDB文件夹里了,所以可以使用dbpath参数指定目录。

    ./mongod --dbpath ../data/db &
    

    MongoDB的Shell是一个功能完备的JavaScript解释器,可以运行任何JavaScript程序。Shell会在启动时自动连接到本地的MongoDB服务器。

    ./mongo
    

    1.2 核心概念

    1.2.1 文档

    文档是MongoDB的核心概念,由多个键及其关联的值有序地放在一起便是文档。对应关系型数据库中行的概念。集合就是一组文档,就如同数据库表。但集合是无模式的,这意味着一个集合里面的文档可以是各式各样的。

    1.2.2 集合

    在关系型数据库中,如果要保存people其address,一般会拆分成两个表中的两行。在MongoDB中,就可以将address文档直接嵌入people文档中。这样做也有坏处,因为MongoDB会储存更多重复的数据,这样是反规范化的。

    1.2.3 ObjectId

    在客户端生成体现了MongoDB的设计理念:能从服务器端转移到驱动程序来做的事,就尽量转移。这种理念背后的原因是,即便是像MongoDB这样的可扩展数据库,扩展应用层也要比扩展数据库层容易得多。此外在客户端生成ObjectId,驱动程序能够提供更加丰富的API。

    1.3 数据类型

    MongoDB的文档类似于JSON。但JSON仅有6中数据类型,表现力有限。MongoDB在保留JSON基本的键/值对的基础上,添加了一些其他数据类型。

    2 插入、更新、删除及查询文档

    2.1 插入

    当执行插入时,使用的驱动程序会将数据转换成BSON的形式。数据库解析BSON,检验是否包含“_id”并且文档不超过4MB,除此之外不做别的数据验证,就只是简单地将文档原样存入数据库中。坏处是允许插入无效的数据,好处是让数据库更加安全,远离注入式攻击。

    db.blog.insert({"title" : "Hello MongoDB", "author" : "cdai"})
    
    db.blog.find()
    { "_id" : ObjectId("514580655da8aea55cb4b7a8"), "title" : "Hello MongoDB", "author" : "cdai" }
    

    2.2 更新

    2.2.1 文档整体替换

    当模式结构发生较大变化,完全用一个新文档替代匹配的文档。

    db.blog.update({"author" : "cdai"}, {"username" : "cdai", "comments" : ["good"]})
    
    db.blog.find()
    { "_id" : ObjectId("514580655da8aea55cb4b7a8"), "username" : "cdai", "comments" : [ "good" ] }
    

    2.2.2 $set修改器

    如果键不存在就创建它,这对更新模式,增加用户定义的键来说非常方便。

    db.blog.update({"username" : "cdai"}, {"$set" : {"pageviews" : 52}})
    
    db.blog.find()
    { "_id" : ObjectId("514580655da8aea55cb4b7a8"), "comments" : [ "good" ], "pageviews" : 52, "username" : "cdai" }
    

    2.2.3 $inc修改器

    $inc只能用于整数、长整数或双精度浮点数。

    db.blog.update({"username" : "cdai"}, {"$inc" : {"pageviews" : 1}})
    
    db.blog.find()
    { "_id" : ObjectId("514580655da8aea55cb4b7a8"), "comments" : [ "good" ], "pageviews" : 53, "username" : "cdai" }
    

    2.2.4 $push修改器

    $push会向已有的数组末尾加入一个元素,要是不存在会创建一个新数组。

    db.blog.update({"username" : "cdai"}, {"$push" : {"comments" : "not bad"}})
    
    db.blog.find()
    { "_id" : ObjectId("514580655da8aea55cb4b7a8"), "comments" : [ "good", "not bad" ], "pageviews" : 53, "username" : "cdai" }
    

    2.2.5 修改器速度

    $inc能就地修改,因为不需要改变文档的大小。而数组修改器可能更改了文档的大小,就会慢一些。MongoDB预留了些补白给文档,来适应大小变化。但是要是超出了原来的空间,最后还是要分配一块新的空间。

    2.3 删除

    删除集合里所有数据。不会删除集合本身,原有的索引也会保留。

    db.blog.remove()
    

    删除集合。速度很快,整个集合都被删除,所有的索引也都不见了。

    db.drop_collection("blog")
    

    2.4 查询

    2.4.1 指定返回的键

    find或findOne函数的第二个参数指定想要/剔除的键。

    db.blog.find({"username" : "cdai"}, {"pageviews" : 1})
    { "_id" : ObjectId("514580655da8aea55cb4b7a8"), "pageviews" : 53 }
    
    db.blog.find({"username" : "cdai"}, {"pageviews" : 0})
    { "_id" : ObjectId("514580655da8aea55cb4b7a8"), "comments" : [ "good", "not bad" ], "username" : "cdai" }
    

    2.4.2 查询范围

    $lt、$lte、$gt、$gte就是全部的比较运算符。

    db.blog.findOne({"pageviews" : {"$gte" : 1, "$lte" : 100}})
    {
            "_id" : ObjectId("514580655da8aea55cb4b7a8"),
            "comments" : [
                    "good",
                    "not bad"
            ],
            "pageviews" : 53,
            "username" : "cdai"
    }
    

    类似的运算符还有$ne、$in、$not、$or等,用法类似,就不一一介绍了。

    2.4.3 正则表达式

    MongoDB使用Perl兼容的PCRE库来匹配正则表达式。

    db.blog.find({"username" : /dai/i})
    { "_id" : ObjectId("514580655da8aea55cb4b7a8"), "comments" : [ "good", "not bad" ], "pageviews" : 53, "username" : "cdai" }
    

    2.4.4 查询数组

    2.4.5 查询内嵌文档

    3 创建索引

    MongoDB的索引几乎与传统的关系型数据库索引一模一样。

    db.blog.ensureIndex({"username" : 1})
    Sun Mar 17 15:41:46 [conn4] build index test.blog { username: 1.0 }
    Sun Mar 17 15:41:46 [conn4] build index done.  scanned 1 total records. 0.036 secs
    

    如果索引包含N个键,则对于前几个键的查询都会有帮助。比如有个索引{"a" : 1, "b" : 1, "c" : 1},实际上是有了{"a" : 1},{"a" : 1, "b" : 1}和{"a" : 1, "b" : 1, "c" : 1}三个索引。

    有些时候最有效的方法居然是不使用索引。一般来说,要是查询返回集合中一半以上的结果,用表扫描会比几乎每条文档都要查索引要高效一些。

    所以,建立索引时要考虑如下问题。 (1)会做什么样的查询?其中哪些键需要索引? (2)每个键的索引方向是怎样的? (3)如何应对扩展?有没有种不同的键的排列可以使常用数据更多地保留在内存中?

    4 管理MongoDB

    4.1 监控页面

    通过–rest选项开启REST支持,可以更好地使用监控页面。

    ./mongod --dbpath ../data/db/ --rest &
    

    4.2 停止MongoDB

    使用kill或kill -2停止MongoDB,会等到当前运行的操作或者文件预分配完成,关闭所有打开的链接,将缓存的数据刷新到磁盘,最后停止。千万不要向运行中的MongoDB发送SIGKILL(kill -9)信号。这会导致上面的步骤全被忽略,数据库直接关闭。

    use admin
    switched to db admin
    db.shutdownServer()
    

    4.3 备份和修复

    4.3.1 停机备份

    在运行MongoDB时复制数据目录不太安全,所以就得先把服务器关了,再复制数据目录。假设服务器安全关闭了,数据库目录中就是关闭那一刻数据的快照。

    4.3.2 mongodump

    mongodump使用普通的查询机制,所以产生的备份不一定是服务器数据的实时快照。服务器在备份过程中处理写入时尤为明显。

    4.3.3 fsync

    fsync命令会强制服务器将所有缓冲区写入磁盘。还可以选择上锁对数据库的进一步写入,直到释放锁为止。要是数据库运行在有快照功能的文件系统上,这个会很有用。

    4.3.4 从属备份

    因为不太在乎从属服务器的性能或是能不能读写,于是就能随意选择上面的3种备份方式。

    4.3.5 修复

    修复数据库的过程实际上非常简单:将所有的文档导出然后马上导入,忽略那些无效的文档。完成以后,会重新建立索引。修复数据库还能起到压缩数据的作用。闲置的空间(删除大量文档后腾出的空间)在修复后被重新回收。


  • 相关阅读:
    基础总结深入:数据类型的分类和判断(数据、内存、变量) 对象 函数 回调函数 IIFE 函数中的this 分号
    BOM 定时器 通过修改元素的类来改变css JSON
    事件 事件的冒泡 事件的委派 事件的绑定 事件的传播
    DOM修改 使用DOM操作CSS
    包装类 Date Math 字符串的相关的方法 正则表达式 DOM DOM查询
    数组 call()、apply()、bind()的使用 this arguments
    autocad 二次开发 最小包围圆算法
    win10 objectarx向导在 vs2015中不起作用的解决办法
    AutoCad 二次开发 jig操作之标注跟随线移动
    AutoCad 二次开发 文字镜像
  • 原文地址:https://www.cnblogs.com/xiaomaohai/p/6157757.html
Copyright © 2011-2022 走看看