MongoDB

MongoDB
是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的,语法有点类似javascript面向对象的查询语言,它是一个面向集合的,模式自由的文档型数据库。

mongodb与 mysql性能比较

clipboard.png

应用范围和限制

缺点:不支持连表查询,不支持sql语句,不支持事务存储过程等,所以不适合存储数据间关系比较复杂的数据,一般主要是当做一个数据仓库来使用。
适用于:日志系统,股票数据等。 不使用于:电子商务系统等需要连多表查询的功能。

mongoDB的基本概念

文档

文档是mongoDB中数据的基本单元,类似关系数据库的行, 多个键值对有序地放置在一起便是文档。 MongoDB> 中以文档的方式存取记录,如一条记录格式如下:
{ “username”:”Tom”, “age”:10,email:’xiaobai@sohu.com’,’sex’:男} { "username":"Tom" , "age" : "10" }
{“Username”:”Tom”,”age”:10} {“Username”:”Tom” }

注意:

(1)以上是几个不同的文档,MongoDB区分大小写的数据类型,第一个age字段是数字类型,第二个age是字符串类型。
(2)每一个文档尺寸不能超过16M

集合

集合就是一组文档,多个文档组成一个集合,集合类似于 mysql里面的表 。 无模式是指,在同一个集合中可以包含不同格式的文档,如: {
"Name" : "Mongodb" , "Type" : "Nosql" } { "UserName" : "Tom" ,
"age" : 20 , "Gender" : "male" } 以上两个文档可以放在同一个集合中。
在Mysql需要先建表再插入数据, 模式自由(schema-free):意思是集合里面没有行和列的概念,
注意:MongoDB中的集合不用创建、没有结构,所以可以放不同格式的文档。

数据结构体系

clipboard.png

windows怎么安装mongodb呢?

使用管理员命令运行

//安装服务 配置dbpath,logpath
cd d:\wamp64\bin\mongodb-win32-i386-2.0.3\mongodb-win32-i386-2.0.3\bin
mongod –install –logpath d:/mongo/log.txt  --dbpath d:/mongo/data

//启动服务

net start mongodb

//如果服务异常尝试卸载重装   可以查看服务所在路径是否是指定的路径

mongod.exe --remove --servicename mongodb

数据库的操作:

//显示所以的数据库

show dbs;

//指向db库

use db;

查看集合

语法:show tables5、查询集合里面的文档
语法: db.集合名.find() 查询所有 db.集合名.findone()
查询第一个文档 删除集合 语法:db.集合名.drop();
删除数据库语法:db.dropdatabase()

//删除php集合
db.php.drop;

文档的操作:

以下操作集合以php(集合)为例:

//插入文档到php集合中 
db.php.insert({name:’xiaoyi’});
//查看php集合的数据
db.php.find();
//根据条件进行查询
db.php.find(),{age:18};
//取出单条数据

db.php.findone();

//查询集合的前8条数据
db.php.limit(8);
//偏移量的使用  skip  
db.php.find().skip(2).limit(1);
//显示文档的个数  
db.php.count();
//删除文档
db.php.remove({});
//删除指定条件的数据  $lt(<),$gt(>)
db.php.remove({age:{'$gt':25}});
//修改指定的文档
db.php.update({'name':'xiaobao'},{'age':58});

用户管理

//用户添加
//切换到指定的数据库
use stu;
//为其增加用户
db.adduser(’xiaoyi’,’admin’);
如何通过权限验证
(1)选择数据库
    Use stu;
(2)执行db.auth(用户名,密码)
    Db.auth(‘xiaoyi’,’admin’); 
//删除用户和修改密码注意:创建的用户名和密码是存储在各自数据库里面的system.users集合里面的。
//获取到用户信息
Db.system.users.find();
//想要删除用户,则直接删除system.users集合里面文档即可。
Db.system.users.remove({name:’xiaoyi’});

总结说明:

(1)非admin数据库的用户不能使用数据库命令,比如show dbs等。
(2)admin数据库中的用户被视为超级用户(即管理员)。在认证之后,管理员可以读写所有数据库,执行特定的管理命令,
(3)在开启安全检查之前,一定要至少有个管理员账号。
(4)数据库的用户账号以文档的形式存储在system.users集合里面。可以在system.users集合中删掉用户账号文档,就可以删除用户。

MongoDB的索引:

普通单列索引
测试代码:

> for(var i=0;i<200000;i++){ 
... db.java.insert({name:'xiao'+i,age:i}) 
... } 

第一:先检验一下查询性能

var start = new Date()
db.java.find({name:'xiao156789'}) 
var end = new Date() 
end-start

第二:为name创建索引

db.java.ensureIndex({name:1}) 

第三:再执行第一部分代码可以看出有数量级的性能提升
没有添加索引时使用时间是;

Var start=new date();
Db.php.find();
Var end=new Date();
End-start

添加索引

Db.php.ensureIndex({name:1});

添加完成后,再次查询

语法: db.集合名.ensureIndex({键名:1}) 1是升续 -1是降续 多列索引(复合索引) 创建多列索引
db.集合名.ensureIndex({field1:1/-1, field2:1/-1});

db.php.ensureIndex({name:1,age:1});

可以使用db.集合名.getIndexes()查看创建的索引情况。

子文档索引

语法: db.集合名.ensureIndex({filed.subfield:1/-1}); 如下文档可以建立子文档索引
{name:’诺基亚手机1’,price:12.34,spc:{weight:100,area:’纽约’}}
{name:’诺基亚手机2’,price:42.34,spc:{weight:200,area:’伦敦’}}
比如要查询weight等于100的文档。 db.goods.find({‘spc.weight’:100})
根据当前案例,我们建立子文档索引

db.net.ensureIndex({'spc.w':1})

唯一索引:

//保证文档数据的唯一性
Db.php.ensureIndex({name:-1},{unique:true});

//稀疏索引与普通索引两者的区别

clipboard.png

//稀疏索引的建立
Db.php.ensureIndex({email:1},{sparse:true});

查看索引
常用命令:
(1) 查看当前索引状态: db.集合名.getIndexes();

Db.php.getIndexes(); 

clipboard.png

(2)详情查看本次查询使用哪个索引和查询数据的状态信息。

db.php.find({name:’xiao’}).explain() 

clipboard.png

clipboard.png

删除索引

删除单个索引

语法:db.集合名.dropIndex({filed:1/-1});

db.php.dropIndex({name:1});

//删除所有的索引 
Drop.php.dropIndexes();

//获取到集合索引
db.php.getIndexes();

重建索引

一个表经过很多次修改后,导致表的文件产生空洞,索引文件也如此. 可以通过索引的重建,减少索引文件碎片,并提高索引的效率.
类似mysql中的optimize table mysql里面使用optimize table语法:optimize table 表名
db.集合名.reIndex()

Db.php.reIndex();

索引使用注意事项

(1)创建索引的时候,注意1是正序创建索引 -1是倒叙创建索引
(2)索引的创建在提高查询性能的同时会影响插入性能,对于经常查询少插入的文档可以考虑用索引
(3)复合索引要注意索引的先后顺序。
(4)每个键全建立索引不一定就能提高性能,索引不是万能的。
(5)在做排序工作的时候如果是超大数据量也可以考虑加上索引用来提高排序的性能。

mongoDB的导入与导出
(1)导出数据

导入/导出可以操作的是本地的mongodb服务器,也可以是远程的,所以,都有如下通用选项。

利用mongoexport
-h host主机
--port 端口
-d 指明使用的库
-c 指明要导出的集合
-o 指明要导出的文件名
--csv指定导出的csv格式
-q 过滤导出
-f field1 field2 列名
-u username 用户名
-p password 密码

如下操作,

mongoexport.exe -h localhost -d stu -c php -o f:/php.json

导入数据

使用mongoimport命令
-d 待导入的数据库
-c 待导入的集合(不存在会自己创建)
--type csv/json(默认)
--file 备份文件路径

例1: 导入json ./bin/mongoimport -h --port 端口号 -d test -c goods
--file ./goodsall.json 例2: 导入csv ./bin/mongoimport -h --port 端口号 -d test -c goods --type csv -f goods_id,goods_name --file ./goodsall.csv ./bin/mongoimport -h --port 端口号 -d test -c goods
--type csv --headline -f goods_id,goods_name --file ./goodsall.csv

案例:把刚才导出的php.json文件导入到user库里面的php集合里面。

mongoimport.exe -d stu -c java --file f:/php.json

导入成功,进行查看

clipboard.png

主从复制

主从复制是一个简单的数据库同步备份的集群技术。主服务器负责数据的增删改,从服务器同步主服务器实现数据的同步。

1原理图:

clipboard.png

2、实现的注意点;
(1)在数据库集群中要明确的知道谁是主服务器,主服务器只有一台。
(2)从服务器要知道自己的数据源也就是对于的主服务是谁。
(3)--master用来确定主服务器,--slave和--source来控制从服务器。
3、配置步骤:
可以通过不同端口来模拟多台mongodb服务器。

(1)启动主服务器

clipboard.png

(2)启动从服务器

clipboard.png

(3)客户端登陆到主服务器
添加一些数据,测试是否同步到从服务器
如下在主服务器里面,添加了一些文档
第一步:客户端登录到主服务器,添加一些文档

clipboard.png

第二步:登陆到从服务器,查看是否有数据

clipboard.png

如果有数据,则成功了。

php操作mongodb

插入文档:

//(1)新建一个集合python,添加文档,
//注意:在php里面代码操作时,在黑窗口里面使用'.'地方就变成使用‘->’,{}就变成关联数组
//db.python.insert({name:'wawa',age:4})
$m=new Mongo("mongodb://root:root@localhost:8888/admin");
$db=$m->selectDb("stu");//选择数据库
$db->python->insert(array('name'=>'wawa1','age'=>12));
$db->python->insert(array('name'=>'wawa2','age'=>22));
$db->python->insert(array('name'=>'wawa3','spc'=>array(‘w’=>100,’age’=>20)));
$db->python->ensureIndex(array(‘name’=>1,array(‘’)))
echo 'ok';
//查询文档
$data = $db->net->find();
foreach($data as $v){
    echo $v['name'].'---'.$v['age'].'----'.$v['email'].'<br/>';
}
//删除文档
db.net.remove({age:{'$gt':10}})
$res = $db->net->remove(array('age'=>array('$gt'=>10)));r435
//增删改查
//注意,在命令行里面的    .变成->      {}变成数组
//(1)添加一个文档
//$db->php->insert(['name'=>'程咬金','age'=>22]);
//(2)查询文档
//$data = $db->php->find();
//查询年龄等于9的文档
//$data = $db->php->find(['age'=>9]);
//查询年龄大于9的文档db.php.find({age:{'$gt':9}});
//$data = $db->php->find(['age'=>['$gt'=>9]]);
//根据年龄降序显示
//$data = $db->php->find()->sort(['age'=>-1]);
//(3)修改文档,我们直接使用修改器来完成,
//把年龄等于8的名称改名为'李白'
//db.php.update({age:8},{'$set':{'name':'李白'}})
//$db->php->update(['age'=>8],['$set'=>['name'=>'李白']]);
//(4)删除文档
//比如删除年龄等于10的文档
//$db->php->remove(['age'=>10]);
$data = $db->php->find();
foreach($data as $v){
        echo $v['name'].'----'.$v['age'].'<br>';
}

萧逸
709 声望29 粉丝

致力于分享效率工具、有趣好玩的开源项目、技术干货。关注我,带你发现新大陆~