• 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 修复

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


  • 相关阅读:
    POST和GET的区别
    Java设计模式6大原则
    JAVA23种工厂模式
    使用jsp实现用户登录请求
    MVC模式
    使用idea查询数据库内容
    mysql常见错误
    定义外键和建表原则
    CSS制作圆角边框
    2、JS的编写位置
  • 原文地址:https://www.cnblogs.com/xiaomaohai/p/6157757.html
Copyright © 2020-2023  润新知