MongoDB是一种非关系型数据库,说白了就是关系型数据库的阉割版,通过减少不用或者很少用到的功能,达到大幅度提升性能的目的。关系型数据库就是建立在关系模型的基础上的数据库,比如Mysql。
MongoDB简介:
MongoDB是一个基于分布式文件存储的数据库,由C++语言编写。目的是为WEB应用提供扩展的高性能的数据存储解决方案。MongoDB是一个介于关系型数据库和非关系型数据库之间的产品,是非关系型数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。
安装MongoDB
到官网下载安装包https://www.mongodb.com/,下载好了后直接打开安装就好
安装好了后还需要配置环境:
在安装盘下找到bin目录,我的是安装在默认c盘的:C:\Program Files\MongoDB\Server\3.6\bin
将该路径复制出来,找到桌面上的计算机图标,右键->属性->高级系统设置->环境变量->点击PATH所在那条内容,变绿->编辑->将刚才复制的路径粘贴到最后面,记住,用分号和前面的隔开->点击确定,保存
新建一个文件夹:
在安装的根目录里建立新文件夹data/db,我的安装在c盘,所以建c盘下的:C:\data\db
好了,这样就算是把数据库的环境建好了,开始玩起来吧!
---------------------------------------------------------------------------------------------------------------------------------
打开控制面板,开始正式使用MongoDB
1、启动数据库命令:mongod
2、打开另一个面板,和数据库建立连接:mongo
下面介绍一下MongoDB的命令:
show dbs 查看有多少个数据库(如果数据库中没有集合则不会显示该数据库)
use school 进入school数据库,如果没有则新建并进入
show collections 进入数据库后查看该数据库里有哪些集合
db 查看此时在哪个数据库中
db.集合名.insert() 往指定集合中插入数据,没有该集合则新建
db.集合名.find() 查看集合中的数据
db.集合名.findOne() 只看第一行数据
db.集合名.update({name: '小米'},{'age',40}) 查找name为小米的数据,并把其age改成40
db.集合名.remove({name: '小米'}) 删除name为小米的数据
db.集合名.drop() 删除整个集合
db.dropDatabase() 删除数据库(必须先进入要删除的数据库)
我们可以用js执行相关命令,更加方便快捷:
命令行执行 load(./xx.js)或者 mongo xx.js 即可,前提是必须先与对应数据库连接上,用var db=connect('数据库名')yufa
在插入数据的时候切记循环插入,那样效率特别底下,最好的方法是批量插入:
不好的方法
var db = connect('log'); for(var i=0;i<1000;i++) { db.login.insert({"num": i}); }
好的方式
var db = connect('log'); var dataArr = []; for(var i=0;i<1000;i++) { dataArr.push({"num": i}); } db.login.insert(dataArr);
update 更新命令
遵循db.集合名.update(查找条件,修改条件)的格式,两者都是对象
$set 修改指定键值
已经插入workMates集合中的一条数据
var workMate3 = { name: '红米', age: 25, sex: 0, job: 'Andriod', skill: { skillOne: 'Oc', skillTwo: 'Ot' }, regeditTime: new Date() };
db.workMates.update({name: '哈哈哈'},{$set: {age: 19,'skill.skillOne': '搞笑'}}); // 用name定位,找到对应的数
$unset 删除指定值
db.workMates.update({name: '哈哈哈'},{$unset: {sex: ''}});
upsert选项 如果没有年龄选项则添加上,upsert为false时不添加
db.workMates.update({name:'xiaoWang'},{$set:{age:20}},{upsert:true})
$push 对数组进行操作
已有数据:
workMate3 = { name: '红米', age: 25, sex: 0, job: 'Andriod', skill: { skillOne: 'Oc', skillTwo: 'Ot' }, interest: ['吃饭','睡觉','打豆豆'], regeditTime: new Date() };
db.workMates.update({name: '红米'},{$push: {interest: '看电影'}}); // 往interest数组里添加元素
db.workMates.update({name: '红米',interest: {$ne: '看书'}},{$push: {interest:'玩游戏'}});// $ne 如果有看书,则不进行后面的push操作,没有则push
db.workMates.update({name: '红米'},{$addToSet: {interest: '打架'}});// $addToSet 如果有打架,则不进行后面的push操作,没有则push $ne的升级版
var newInterest = ['跳舞','做饭','唱歌']; // $each 批量插入 db.workMates.update({name: '红米'},{$addToSet: {interest: {$each: newInterest}}});
db.workMates.update({name: '红米'},{$pop: {interest: -1}});// $pop 删除一个值 -1:从头部删除,1:从尾部删除
db.workMates.update({name: '红米'},{$set: {'interest.1': '睡懒觉'}});// 定位修改数组 修改第二位值find() 查找命令
遵循db.集合名.find(查找条件,显示条件)的格式,两者都是对象
db.workmates.find( {'skill.skillOne': 'HTML+CSS'}, // 查找第一项技能为HTML+CSS对应的数据 {name: true,'skill.skillOne': true,_id: false} // 显示name、第一项技能,不显示_id(默认显示的) );
修饰符
小于($lt):英文全称less-than 小于等于($lte):英文全称less-than-equal 大于($gt):英文全称greater-than 大于等于($gte):英文全称greater-than-equal 不等于($ne):英文全称not-equal db.workmates.find( {age: {$gt: 25,$lt: 28}}, // 年龄大于25,小于28的数据 {name: true,'skill.skillOne': true,_id: false,age: true} ); // $in 一个key值多个value查询 db.workmates.find( {age: {$in: [28,33]}}, // 年龄为28和33的 {name: true,age: true,_id: false} ); // $or 或者 查询多个键值 db.workmates.find( {$or: [ {age: {$gte: 30}}, {'skill.skillThree': 'PHP'} ]}, {name: true,age: true,'skill.skillThree': true,_id: false} ); // $and 和 db.workmates.find( {$and: [ {age: {$gte: 30}}, {'skill.skillThree': 'PHP'} ]}, {name: true,age: true,'skill.skillThree': true,_id: false} );
按数组查找
// 含有指定数组的数据 db.workmates.find( {interest: ['画画','聚会','看电影']}, // 有[]表示完全匹配 {name: true,age:true} ); // 只匹配数组中的一项 db.workmates.find( {interest: '画画'}, {name: true,age:true,interest:true,_id:false} ); // $all 匹配其中指定项数 db.workmates.find( {interest: {$all:['画画','聚会']}}, {name: true,age:true,interest:true,_id:false} ); // $in 或者 db.workmates.find( {interest: {$in:['画画','聚会']}}, {name: true,age:true,interest:true,_id:false} ); // $size 数量为指定值的数据 db.workmates.find( {interest: {$size:5}}, {name: true,age:true,interest:true,_id:false} ); // $slice 切片显示 -1显示最后一项 db.workmates.find( {interest: {$size:5}}, {name: true,age:true,interest:{$slice: 2},_id:false} );
find(query,fileds).limit(num).skip(num).sort(obj)
query 查询条件
fileds 显示条件
limit 返回数量,参数为数字
skip 跳过多少条数据,参数为数字
sort 排序方式,参数为对象,1:从小到大,-1:从大到小
// limit(2)每页显示两条 从第一条数据开始排序skip(0) sort({age: 1})按年龄从小到大排序 db.workmates.find( {}, // 不设查询条件 {name: true,age:true} ).limit(2).skip(0).sort({age: 1});
数据索引
一般数据库中的数据都是有索引的,这样方便查找,那么首先让我们模拟一个数据库,往里面插入上百万条数据
新建test.js
// 获取随机数 function getRandomNum(max,min) { let range = max - min; let randomNum = Math.round(Math.random() * range) + min; return randomNum; } // 获取随机姓名 function getRandomName(max,min) { let nameArr = '1234567890qwertyuiopasdfghjklzxcvbnm_-*\/?~.'.split(''); let randomName = ''; for(let i=0;i<getRandomNum(max,min);i++) { randomName += nameArr[getRandomNum(0,nameArr.length)]; } return randomName; } // 批量插入200w数据 let infoArr = []; let startTime = new Date().getTime(); for(let i=0;i<2000000;i++) { infoArr.push({ username: getRandomName(8,16), regeditTime: new Date(), randomNum0: getRandomNum(100000,99999999), randomNum1: getRandomNum(100000,99999999), randomNum2: getRandomNum(100000,99999999), randomNum3: getRandomNum(100000,99999999), randomNum4: getRandomNum(100000,99999999), randomNum5: getRandomNum(100000,99999999), randomNum6: getRandomNum(100000,99999999), randomNum7: getRandomNum(100000,99999999), randomNum8: getRandomNum(100000,99999999), randomNum9: getRandomNum(100000,99999999), randomNum10: getRandomNum(100000,99999999) }); } let endTime = new Date().getTime() - startTime; let db = connect('info'); // 和info数据库建立连接 db.infonum.insert(infoArr); // 往infonum集合里插入数据 print('insert succeed' + endTime);
在命令行运行load('./test.js')将数据插入库中
建立索引
db.ensureIndex({username:1})
查看现有索引
db.infonum.getIndexes()当数据量小于10000条时尽量不要使用索引,因为此时对于搜索性能的提升效果不明显。一组数据可以有多个索引,称为符合索引
通过索引查询数据:
db.randomInfo.find({username: 'wy~wf836al/',randomeNum0: 131455});
删除索引
db.randomInfo.dropIndex('randNum0_1');// 索引的唯一ID 填写的值不是索引字段的key值,而是对应的name值