本学习笔记是来源于学习B站上的尚硅谷和黑马的MongoDB教学视频而做的知识总结。
一、数据库(Database)
数据库是按照数据结构来组织、存在和管理数据的仓库。说白了,数据库就是存在数据的仓库。
二、数据库分类
主要分为两种:
(1)关系型数据库
MySQL、Oracle、DB2、SQL Server。。。
关系型数据库中全都是表
(2)非关系型数据库(No SQL=Not Only SQL)
MongoDB、Redis。。。
键值对数据库
文档数据库MongoDB
三、MongoDB简单介绍
1、MongoDB是什么
MongoDB的数据模型是面向文档的,所谓文档是一种类似于JSON的结构,简单理解MongoDB这个数据库中存的是各种各样的JSON(BSON,Binary JSON,也就是二进制JSON)。
2、MongoDB中的三个概念
(1)数据库(database)
数据库是一个仓库,在仓库中可以存放集合。
(2)集合(collection)
集合类似于数组,在集合中可以存放文档。集合就是一组文档,可以是各种各样的,没有格式要求。
(3)文档(document)
文档是数据库中的最小单位,我们可以存储和操作都内容都是文档。类似于JS中的对象,在MongoDB中每一条记录都是一个文档。
总结起来就是,多个文档组成集合,多个集合组成数据库。
注意,在MongoDB中,数据库和集合都不需要手动创建,当我们创建文档时,如果文档所在的集合或数据库不存在会自动创建数据库和集合。
四、MongoDB的安装
1、MongoDB的安装
我们在Linux上安装MongoDB,在官网上下载相关安装包即可。
执行命令启动服务:/usr/bin/mongod --config /etc/mongodb.conf
在mongodb.conf配置文件中指定数据的存储路径:dbpath=/var/lib/mongodb
日志目录:logpath=/var/log/mongodb/mongodb.log
注意,版本的选择:
MongoDB的版本命名规范如:x.y.z;
y为奇数时表示当前版本为开发版,如:1.5.2、4.1.13;
y为偶数时表示当前版本为稳定版,如:1.6.3、4.0.10;
z是修正版本号,数字越大越好。
注意,MongoDB的配置文件参考:
https://docs.mongodb.com/manual/reference/configuration-options/
https://docs.mongodb.com/manual/reference/parameters/
2、MongoDB客户端工具
推荐使用几个MongoDB客户端工具,图像化界面,容易使用
(1)MongoDB Compass
地址:https://www.mongodb.com/download-center/v2/compass?initial=true
(2)NoSQL Manager for MongoDB
(3)RoboMongo
3、停止关闭服务
有两种方式,分别为快速关闭和标准关闭
(1)快速关闭,即通过kill命令直接杀死mongod 进程,但是数据可能会出错。
如果数据损坏了,可以通过如下操作来恢复数据:
第一、删除lock文件:rm -f /数据存储目录/*.lock
第二、修复数据:/usr/bin/mongod --repair --dbpath=/数据存储目录/
(2)标准关闭方法(数据不容易出错,但麻烦),也就是通过MongoDB客户端中的shutdownServer命令来关闭服务,如下:
//#切换到admin库
use admin
//关闭服务
db.shutdownServer()
五、MongoDB的基本操作
1、基本指令
显示当前的所有数据库: show dbs / show databases
进入到指定的数据库中:use 数据库名
显示当前所处的数据库名称:db
显示数据库中所有的集合:show collections
创建一个新的集合:db.createCollection()
删除集合:db.collection.drop()
2、基本CRUD增删改查指令
(0)查询文档
db.collection.find()
- 可以根据指定条件从集合中查询所有符合条件的文档
- 返回的是一个数组
db.collection.findOne()
- 查询第一个符合条件的文档
- 返回的是一个对象
db.collection.find().count()
- 查询符合条件的文档的数量
(1)插入文档
db.
- 向集合中插入一个文档
- 例子:向test数据库中的,stus集合中插入一个新的学生对象
{name:"孙悟空",age:18,gender:"男"}
db.stus.insert({name:"孙悟空",age:18,gender:"男"})
db.collection.insertOne()
- 向集合中插入一个文档
db.collection.insertMany()
- 向集合中插入多个文档
(2)修改数据库中的文档
db.collection.update()
- 可以修改、替换集合中的一个或多个文档
db.collection.updateOne()
- 修改集合中的一个文档
db.collection.updateMany()
- 修改集合中的多个文档
db.collection.replaceOne()
- 替换集合中的一个文档
(3)删除集合中的文档
db.collection.remove()
- 删除集合中的一个或多个文档(默认删除多个)
db.collection.deleteOne()
- 删除集合中的一个文档
db.collection.deleteMany()
- 删除集合中的多个文档
- 清空一个集合
db.collection.remove({})
- 删除一个集合
db.collection.drop()
- 删除一个集合
db.dropDatabase()
- 删除一个数据库
3、复杂一点的操作命令
(1)投影查询
如果要查询结果返回部分字段,则需要使用投影查询(不显示所有字段,只显示指定的字段)。
(2)覆盖修改、局部修改、批量修改、列值增长的修改
(3)统计查询、分页列表查询、排序查询
(4)更多查询-正则表达式查询、比较查询、包含查询、条件连接查询。
4、常用命令总结:
选择切换数据库:use articledb
插入数据:db.comment.insert({bson数据})
查询所有数据:db.comment.find();
条件查询数据:db.comment.find({条件})
查询符合条件的第一条记录:db.comment.findOne({条件})
查询符合条件的前几条记录:db.comment.find({条件}).limit(条数)
查询符合条件的跳过的记录:db.comment.find({条件}).skip(条数)
修改数据:db.comment.update({条件},{修改后的数据}) 或db.comment.update({条件},{$set:{要修改部分的字段:数据})
修改数据并自增某字段值:db.comment.update({条件},{$inc:{自增的字段:步进值}})
删除数据:db.comment.remove({条件})
统计查询:db.comment.count({条件})
模糊查询:db.comment.find({字段名:/正则表达式/})
条件比较运算:db.comment.find({字段名:{$gt:值}})
包含查询:db.comment.find({字段名:{$in:[值1,值2]}})或db.comment.find({字段名:{$nin:[值1,值2]}})
条件连接查询:db.comment.find({$and:[{条件1},{条件2}]})或db.comment.find({$or:[{条件1},{条件2}]})
六、MongoDB的索引
1、索引的类型
(1)单字段索引
MongoDB支持在文档的单个字段上创建用户定义的升序/降序索引,称为单字段索引(Single Field Index)。
说明,主键_id就是单字段索引
(2)复合索引
MongoDB还支持多个字段的用户定义索引,即复合索引(Compound Index)。
复合索引中列出的字段顺序具有重要意义。例如,如果复合索引由{ userid: 1, score: -1 } 组成,则索引首先按userid正序排序,然后在每个userid的值内,再在按score倒序排序。
(3)其他索引
地理空间索引(Geospatial Index)、文本索引(Text Indexes)、哈希索引(Hashed Indexes)。
2、索引的查看、创建和移除
(1)查看索引: db.emp.getIndexes();
(2)创建索引: db.collection.createIndex(keys, options)
(3)删除索引: db.collection.dropIndex(index)
(4)删除所有的索引: db.collection.dropIndexes()
3、索引的使用
(1)执行计划
分析查询性能(Analyze Query Performance)通常使用执行计划(解释计划、Explain Plan)来查看查询的情况,如查询耗费的时间、是否基于索引查询等。
那么,通常,我们想知道,建立的索引是否有效,效果如何,都需要通过执行计划查看。
db.collection.find(query,options).explain(options)
关键点看: "stage" : "COLLSCAN", 表示全集合扫描,"IXSCAN" ,基于索引的扫描
(2)涵盖的查询
当查询条件和查询的投影仅包含索引字段时,MongoDB直接从索引返回结果,而不扫描任何文档或将文档带入内存。 这些覆盖的查询可以非常有效。
七、基础练习
//1.进入my_test数据库
use my_test
//2.向数据库的user集合中插入一个文档
db.user.insert({
username:"sunwukong"
});
//3.查询user集合中的文档
db.user.find();
//4.向数据库的user集合中插入一个文档
db.user.insert({
username:"zhubajie"
});
//5.查询数据库user集合中的文档
db.user.find();
//6.统计数据库user集合中的文档数量
db.user.find().count();
//7.查询数据库user集合中username为sunwukong的文档
db.user.find({username:"sunwukong"});
//8.向数据库user集合中的username为sunwukong的文档,添加一个address属性,属性值为huaguoshan
db.user.update({username:"sunwukong"}, {$set:{address:"huaguoshan"}});
//9.使用{username:"tangseng"} 替换 username 为 zhubajie的文档
//db.user.replaceOne({username:"zhubajie"}, {username:"tangseng"});
db.user.update({username:"zhubajie"}, {$set:{username:"tangseng"}});
//10.删除username为sunwukong的文档的address属性
db.user.update({username:"sunwukong"}, {$unset:{address:1}});
//11.向username为sunwukong的文档中,添加一个hobby:{cities:["beijing","shanghai","shenzhen"] , movies:["sanguo","hero"]}
//在MongoDB的文档中的属性值也可以是一个文档,当一个文档的属性值是一个文档时,称这个文件为内嵌文档
db.user.update({username:"sunwukong"}, {$set:{hobby:{cities:["beijing","shanghai","shenzhen"] , movies:["sanguo","hero"]}}});
//12.向username为tangseng的文档中,添加一个hobby:{movies:["A Chinese Odyssey","King of comedy"]}
db.user.update({username:"tangseng"}, {$set:{hobby:{movies:["A Chinese Odyssey","King of comedy"]}}});
//13.查询喜欢电影hero的文档
//MongoDB支持直接通过内嵌文档的属性进行查询,如果查询内嵌文档可以通过.的形式匹配
//如果要通过内嵌文档对文档进行查询,此时属性名必须使用引号(单引号、双引号都可以)
db.user.find({"hobby.movies":"hero"});
//14.向tangseng中添加一个新的电影Interstellar
//$push,用于向数组中添加一个新的元素
//$addToSet向数组中添加有一个新的元素,如果数组中已经有了这个元素,则不会再添加了
//db.user.update({username:"tangseng"}, {$push:{"hobby.movies":"Interstellar"}});
db.user.update({username:"tangseng"}, {$addToSet:{"hobby.movies":"Interstellar"}});
//15.删除喜欢beijing的用户
db.user.remove({"hobby.cities":"beijing"});
//16.删除user集合
//db.user.remove({});
db.user.drop();
show dbs;
//17.向numbers中插入20000条数据
//13.2s
for(var i=1; i<=20000; i++) {
db.numbers.insert({num:i});
}
db.numbers.find();
db.numbers.remove({});
//0.1s
var arr = [];
for(var i=1; i<=20000; i++) {
arr.push({num:i});
}
db.numbers.insert(arr);
//18.查询numbers中num为500的文档
db.numbers.find({num:500});
//19.查询numbers中num大于5000的文档
db.numbers.find({num:{$gt:5000}});
db.numbers.find({num:{$eq:5000}});
//20.查询numbers中num小于30的文档
db.numbers.find({num:{$lt:30}});
//21.查询numbers中num大于40小于50的文档
db.numbers.find({num:{$gt:40, $lt:50}});
//22.查询numbers中num大于19996的文档
db.numbers.find({num:{$gt:19996}});
//23.查看numbers集合中的前10条数据
//db.numbers.find({num:{$lte:10}});
//在开发中我们绝对不会进行不带条件的查询
db.numbers.find().limit(10).sort({num:1});
//24.查看numbers集合中的第11条到20条数据
//skip(), limilt(), sort()三个放在一起执行的时候,执行的顺序是先 sort(), 然后是 skip(),最后是显示的 limit(),和命令编写顺序无关。
db.numbers.find().limit(10).skip(10).sort({num:1});
//25.查看numbers集合中的第21条到30条数据
db.numbers.find().limit(10).skip(20).sort({num:1});
//26.将dept和emp集合导入到数据库中
db.dept.find();
db.emp.find();
//27.查询工资小于2000的员工
db.emp.find({sal:{$lt:2000}});
//28.查询工资在1000-2000之间的员工
db.emp.find({sal:{$gt:1000, $lt:2000}});
//29.查询工资小于1000或大于2500的员工
db.emp.find({$or:[{sal:{$lt:1000}}, {sal:{$gt:2500}}]});
//30.查询财务部的所有员工
var depno = db.dept.find({dname:"财务部"})[0].deptno;
db.emp.find({depno:depno});
//31.查询销售部的所有员工
var depno = db.dept.find({dname:"销售部"})[0].deptno;
db.emp.find({depno:depno});
//32.查询所有mgr为7698的所有员工
db.emp.find({mgr:7698});
//33.为所有薪资低于1000的员工增加工资400元
db.emp.update({sal:{$lte:1000}}, {$inc:{sal:400}}, {multi:true});
db.emp.find({sal:{$lte:1000}});
第一步,基础篇结束,请看:
尚硅谷+黑马MongoDB视频学习笔记(二)
https://blog.csdn.net/ok_wolf/article/details/106631589