随着Nosql的兴起,一直希望了解这个领域。伴随着新工作的开始,决定好好地学习一下Mongodb,近日无事,故将知识点简单总结一下,以方便日后使用:
一、简单介绍
首先,MongoDB最初是为一个要求数据库能在多台机器间优雅伸缩的平台而开发的,
其次,MongoDB是作为Web应用程序的数据存储设计的。
一点可以区别它和现代数据库系统的是:MongoDB被设计为可水平伸缩的主要数据存储。也为解决关系型数据库的复杂的表关联提供了一种表示丰富、有层级的数据结构。
二、MongoDB的主要特性
1)MongoDB的数据模型是面向文档的。
文档基本上是一组属性名和属性值的集合。属性值的数据类型:字符串、数字、 日期、数组或者其他文档。(丰富的结构和无需定义Schema,降低了数据库的复杂的逻辑设计和提高了应用程序的开发)
2)即时查询
意思是,无需预先定义系统接受的查询类型。无疑,关系型数据库是具有个能力,它们会严格遵照指示执行任何完备的SQL查询,但是,并非所有的数据库都支持动态查询。MongoDB尽量保持着这种能力。
3)二级索引
B树实现,在MongoDB里,每个集合最多可以创建64个索引。
4)复制
MongoDB中,称为副本集(replica set)的拓扑结构提供了复制功能。通过将数据分布在多台机器上以实现冗余,提供自动故障转移的功能,扩展了数据库的读能力。构成于一个主节点和多个从节点。在此,并不做详细讲解,后面会详细介绍。
5)速度和持久性
在数据库系统领域内,写速度和持久性存在一种相反的关系。写速度可以理解为在给定时间内数据库可以处理的插入、更新和删除操作的数量。持久性则是指保持这些写操作结果不变的时间长短。因此,数据库设计者需要在速度和持久性中做出权衡,以平衡两者的关系。
在MongoDB中,我们可以选择写入语义,决定是否开启Journaling日志记录,通过此方式来控制速度和持久性间的平衡。
写操作解读:MongoDB默认所有的写操作都是fire-and-forget的,即:写操作通过TCP套接字发送,不要求数据库应答。如果用户需要获得应答,可以使用特殊的安全模式发起写操作,所有的驱动都提供这个安全模式。在MongoDB2.0中,Journaling日志是默认开启的。所有的写操作都会提交到一个只能追加的日志里。这是运行MongoDB最安全的方式。
6)数据库扩展
垂直扩展:增加硬件,同时也增加了成本;
水平扩展:MongoDB的水平扩展非常易于管理,它通过基于范围的分区机制,即自动分片(auto-sharding)来实现这一设计目标,自动分片机制会自动管理各个节点之间的数据分布。
三、MongoDB的核心服务器和工具
1)核心服务器
执行mongod(windows上是mongodb.exe)可以运行核心服务器。mongod服务器进程使用一个自定义的二进制协议从网络套接字上接受命令。mongod进程的所有数据文件默认都存储在/data/db里。它没有内存等参数的配置,减少了开发者的任务,数据文件是通过mmap()系统调用被映射成了系统的虚拟内存。
2)Javascript Shell
基于Javascript的一个工具,用于管理数据库和操作数据。
3)命令行工具
·mongodump:用原生的BSON格式将数据库的数据保存下来,优势是热备时非常有用。备份后能方便地用mongorestore恢复。
·mongoexport:支持JSON、CSV、TSV数据,通过mongoimport导入,它还能用于大数据集的初始导入。
·mongosniff:一个网络嗅探工具,用来观察发送到数据库的操作。基本就是吧网络上传输的BSON转换为易于人们阅读的Shell语句。
·mongostat:与iostat类似。持续轮询MongoDB和系统以便提供有帮助的统计信息,包括每秒操作数(插入、删除、更新、查询等)、分配的虚拟内存数量以及服务器的连接数。
本文链接
在了解了MongoDB后,这里简单介绍一下对MongoDB的一些简单操作。
MongoDB安装介绍:
http://www.cnblogs.com/czxu/archive/2011/06/13/2080162.html
MongoDB javascript shell 是一个基于javascript的解释器,故是支持js程序的。如下:
for(i=0;i<200000;i++){
db.numbers.save({num:i});
}
---------------------下面介绍一些简单的操作---------------------------------------
use tutorial;
db.users.insert({username:"smith"}); db.users.save({username:"jone"});
db.users.find(); db.uers.find({username:"smith"});
db.users.count();
db.users.update({username:"smith"},{$set:{country:"Canada"}});
db.users.update({username:"smith"},{$unset:{country:1}});
db.users.update({username:"smith"},{$set:{favourites:{city:["Beijing","Chicago"],movies:["American Beauty","....."]}}});
db.users.find({"favourites.movies":"American Beauty"});
向favourites.movies里添加一个新的元素可用如下:$push,$addToSet,后者保证唯一性。
db.users.find({username:"smith"},{$addToSet:{"favourites.movies":"The Maltess Falcon"}},false,true);
参数一:查询条件;参数二:添加元素;参数四:表示是多项更新(multi-update);MongoDB的更新操作默认只会应用于查询选择器匹配到的第一个文档。如果希望操作被应用于匹配到的所有文档,需要显示说明。
db.foo.remove();删除文档中的数据,foo文档本身不会被删除类似:delete/truncate tablem 命令;
db.users.drop();删除文档。
------------------------------------------------------------------------------------------------
其它:
·db.members.find({num:{"$gt":1999995}});
db.members.find({num:{"$gt":20,"$lt":25}});
·db.members.find({num:{"$gt":1999995}}).explain();[BasicCursor:没有使用索引;n:结果个数;nscanned:扫描的个数]
·num的升序索引如下:db.members.ensureIndex({num:1});查看索引创建情况:db.members.getIndexes();
本文链接
以下方式可以获取数据库信息:
show dbs; show collections;
db.stats(); db.members.stats(); db.runCommand({dbstats:1}); db.runCommand({collstats:1});
db.runCommand = db.$cmd.findOne
db.help();
此外,shell还有内置的Tab不全机制;
db.numbers.save;//查看save方法的内部实现。
其它:
对象ID的生成:
每个集合中对于所有的文档必须是唯一的,主键是存放在文档中的_id字段中。由12个字节的特定结构组成的。id=4个字节的时间戳(Unix时间戳)+3字节的机器ID+2字节的进程ID+3字节的计数器。如:4c291865 238d3b 19b2 000001. 大部分驱动是允许提供这个时间戳,提供创建时间,精确到最接近的一秒钟。
BSON:
既是MongoDB的存储格式又是命令格式。所有的文档都以BSON格式存储在磁盘上,所有查询和命令都由BSON文档来指定。故,所有的MongoDB的驱动必须在语言特定的文档描述和BSON之间进行转换。
BSON规范中包含19种类型。
数据库驱动的核心功能如下:创建ID,序列化BSON以及和数据库服务器通信。
本文链接