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值