MongoDB 入门
一、 MongoDB简介
MongoDB是一个面向文档的数据库系统。使用C++编写,不支持SQL,但有自己功能强大的查询语法。
MongoDB使用BSON作为数据存储和传输的格式。BSON是一种类似JSON的二进制序列化文档,支持嵌套对象和数组。
MongoDB很像MySQL,document对应MySQL的row,collection对应MySQL的table。
二、 Windows下MongoDB操作
MongoDB在Windows上的安装运行很方便。直接下载、解压,然后运行bin/mongod 即可启动服务器,运行bin/mongo 即可运行命令行客户端。
2-1、 下载与解压
项目主页:http://www.mongodb.org/downloads。
下载对于版本,解压并抽取相关的bin目录到C:\MongoDB下(这个任意选择)。
在启动MongoDB之前,我们必须新建一个存放mongoDB数据和日志的目录。数据库目录:C:\MongoDB\data\db\,日志目录:C:\MongoDB\data\。
2-2、 运行服务端
打开CMD窗口,进入到C:\MongoDB\bin目录下,运行服务端mongod.exe
C:\>cd C:\MongoDB\bin C:\MongoDB\bin>mongod.exe --dbpath=C:\MongoDB\data\db --directoryperdb --logpath =C:\MongoDB\data\logs --logappend解释如下:
日志文件为C:\MongoDB\data\logs,以及添加方式记录(追加)。
数据目录为C:\MongoDB\data\db,并且每个数据库将储存在一个单独的目录(--directoryperdb)。
服务端要一直运行。Ctrl+C可中断。
一般来说,如果觉得很麻烦,可以只指定--dbpath即可,如:
mongod.exe --dbpath=C:\MongoDB\data
2-3、 运行客户端
再打开一个CMD窗口,进入到C:\MongoDB\bin目录下,运行客户端mongo.exe来登录MongoDB。(要保持服务端mongod.exe的窗口不关闭)
解释:
运行mongo启动shell
shell会在启动时自动连接MongoDB服务器,默认连接test数据库,并将这个数据库连接赋值给全局变量db,这个变量是MongoDB的主要入口点。
shell是功能完备的Javascript解释器,可以运行任何Javascript程序。
我们可以测试一下:
还可以充分利用Javascript的库,如
2-4、 测试操作
MongoDB使用GridFS来储存大文件。每个BSON对象大小不能超过4MB。
字段名限制:不能以“$”开头;不能包含“.”;“_id”是系统保留的字段,但用户可以自己储存唯一性的数据在字段中。
MongoDB为每个数据库分配一系列文件。每个数据文件都会被预分配一个大小,第一个文件名字为“.0”,大小为64MB,第二个文件“.1”为128MB,依此类推,文件大小上限为2GB。如下:
基本概念:
MongoDB有databases(相当于Mysql的数据库)组成,databases有collections组成(collection相当于Mysql的表) collections有documents组成(document相当于Mysql的行),documents由fields组成(fields相当于Mysql的列)
MongoDB没有新建数据库的命令,只要进行insert或其它操作,MongoDB就会自动帮你建立数据库和collection。当查询一个不存在的collection时也不会出错,Mongo会认为那是一个空的collection。
一个对象被插入到数据库中时,如果它没有ID,会自动生成一个“_id”字段,为12字节(24位)16进制数。
那么_id是如何产生的呢?
12字节按照如下方式产生:
前4个字节是从标准纪元开始的时间戳,单位为妙
#时间戳与随后的5个字节组合起来,提供了秒级别的唯一性
#接下来的3个字节是所在主机的唯一标识符。通常是极其主机名的散列值->>是不同主机生成不同的_id
#下面的两个字节来自于进程标识符(PID)->>确保同一机器并发的多个进程产生不同的_id
#前9个字节保证了,同一秒钟不同机器不同进程产生的_id唯一,后3个字节就是一个计数器,确保相同进程同一秒产生的_id也唯一。
同一秒钟最多允许每个进程拥有256的3次方个不同的_id
当然如果插入文档不带_id,则系统会帮你自动创建一个,如果自己指定了就用自己指定的。
Mongon命令行客户端的脚本语法:
show dbs // 列出所有数据库
use memo // 使用数据库memo。即使这个数据库不存在也可以执行,但该数据库不会立刻被新建,要等到执行了insert等的操作时,才会建立这个数据库。
show collections // 列出当前数据库的collections(当前数据库下的表)
db // 显示当前数据库
show users // 列出用户
新建数据库与数据集合:
show dbs可以看到当前数据库有admin,local,test 介绍如下:
admin:从权限角度来看,这是‘root'数据库.要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。
有些服务器命令也只能从这个数据库运行,如关闭服务器
local:这个数据库永远不会被复制,可以用来存储于本地单台服务器的任意集合
test:客户端启动时自动连接到这个数据库,所以开始db指向的是test
##use test2 ->>此时db指向test2 db.createCollection('t_test')->创建collection(即相当于在数据库test2中新建t_test表),用show collections //可查看到新建的test2
插入数据:(插入数据的方式有很丰富)
###db.XXX.save():
###db.XXX.insert()
查询数据:
$lt ->less then 小于
$lte ->less than and equal 不大于
$gt ->greater then 大于
$gte ->greater then and equal 不小于
$ne ->not equal 不等于
MongoDB的查询语法很强大,类似于SQL的条件查询。例如,很多SQL可以做的,它都可以做:
db.foo.find() // select * from foo db.foo.find().limit(10) // select * from foo limit 10 db.foo.find().sort({x:1}) // select * from foo order by x asc 1:升序 -1:降序 db.foo.find().sort({x:1}).skip(5).limit(10) // select * from foo order by x asc limit 5, 10 db.foo.find({x:10}) // select * from foo where x = 10 db.foo.find({x: {$lt:10}}) // select * from foo where x <= 10 db.foo.find({}, {y:true}) // select y from foo 一些SQL不能做的,MongoDB也可以做: db.foo.find({"address.city":"gz"}) // 搜索嵌套文档address中city值为gz的记录 db.foo.find({likes:"math"}) // 搜索数组 db.foo.ensureIndex({"address.city":1}) // 在嵌套文档的字段上建索引
更新数据:
db.foo.update({},{})更新对象,第一个参数是查询对象,第二个是替代的,可以在第二个对象里指定更新哪些字段,要使用$set。
"$set"用来指定一个键的值。如果这个键不存在,则创建它,如果存在则更新
删除条件查询:
删除数据集合(表):
删除当前数据库:
db.foo.remove()是用来删除数据,只删除匹配的对象
增加field:
$push:增加数组元素
如下面people集合笨没有addr field,使用$push添加->>如果没有addr就增加addr field,如果有了,就增加数组元素
$pop:减少数组元素
or,and和exists的用法:
解释如下:
> db.people.find({"name":"yhb",$or:[{"age":18},{"age":20}]}) //找出name为yhb,age为18或者20的
db.people.find({"addr":{$exists:false}}) //找出不存在addr field
来点复杂的吧:
找出people中name为yhb,年龄为18,或者name为lwy,name为19的
解释一下:
db.people.find({$or:[{"name":"yhb","age":18},{"name":"lwy","age":19}]}) //{"name":"yhb","age":18}其实就是and的关系
db.people.find({$or:[{$and:[{"name":"yhb"},{"age":18}]},{$and:[{"name":"lwy"},{"age":19}]}]}) //用and明说了一下,其实是一样的
主要就是注意用法就好了,就是嵌套而已
如果是or: ->> {$or:[{条件1},{条件2}]} 如果是and: ->> {$and:[{条件1},{条件2}]}
索引:
db.foo.ensureIndex({productid:1}) // 在productid上建立普通索引
db.foo.ensureIndex({district:1, plate:1}) // 多字段索引
db.foo.ensureIndex({productid:1}, {unique:true}) // 唯一索引
总的来说,使用mongodb可以满足常见的增删改差,但是不能完成复杂的跨表级联查询,mongodb努力使数据变得简单紧凑。
2-5、 备份与恢复
二进制数据格式,常用于备份、还原。
Mongodb的备份工具 mongodump:
事例:下图把备份数据库test中所有的数据集合(表)
MongoDB的数据恢复工具 mongorestore:
事例:恢复数据库test中的表t002的数据
2-6、 数据导出、导入
json或cs v格式,每次一个collection
数据导出:
数据导入:
2-7、 安全与认证
use test2 // 选择数据库test2
db.addUser("username", "password"); // 普通权限,可读写
db.addUser("username", "password", true); // 只可读,不可写
db.system.users.remove({user: “username”}); // 删除用户
现在重启服务器,加入--auth选项,开启安全检查
然后用客户端连接:
注意:那个用哪个数据库的账号认证就必须先切换到对应的数据库