MongoDB基础知识~

引入MongoDB:

在面对高并发,高效率存储和访问,高扩展性和高可用性等的需求下,我们之前所学习过的关系型数据库(MySql,sql server…)显得有点力不从心,而这些需求在我们的生活中也是随处可见的,例如在社交中,使用它存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人地点等功能。在游戏中,使用它存储游戏用户信息,用户的装备,积分等直接以内嵌文档的形式存储,方便查询,高效率存储和访问。还有我们熟悉的物流,使用它存储订单信息,订单状态在运送过程中会不断的更新,以内嵌数组的形式来存储,一次查询就能将订单所有的变更读取出来等等。这些场景中,数据操作都有共同的特点,数据量大读写操作频繁价值较低的数据(对事务性要求不高),对于这样的数据,我们更适合使用MongoDB去实现存储。

如何理解事务性要求不高?

事务性要求不高的意思是指对于一项任务或工作对其完成的准确性、完整性和一致性的要求相对较低。这意味着即使在一些小的错误或不完美的情况下,任务仍然可以被接受或达到预期的结果。

例如,对于一项事务性要求不高的简单办公任务,如复制粘贴文本或整理文件等,只要大致完成了任务,小的错误或细微的差异通常被容忍。而对于事务性要求高的任务,如财务报表的编制或重要文件的审查,任何错误或不完美都可能导致严重后果,因此对其准确性和完整性的要求较高。

然而,尽管事务性要求不高,仍然需要保持对任务的专注和准确性,以确保任务的合理完成,并避免可能出现的问题或错误。

什么时候选择MongoDB?

是否需要选择它,我们可以考虑以下几个问题:应用不需要事务及复杂join支持新应用,需求会变,数据模型无法确定,想快速迭代开发应用需要2000-3000以上的读写QPS应用需要TB甚至PB级别数据存储应用发展迅速,需要能快速水平扩展应用要求存储的数据不丢失应用需要99.999%高可用应用需要大量的地理位置查询,文本查询

如果符合上述中的1个及以上,那么MongoDB是你绝不后悔的选择,一定会有人有这样的疑问,上述的这些问题就不能使用们么之前学习过的关系型数据库解决了吗?当然不是,只是在面对这些问题时,相比于MySQL或者SQL server,MongoDB无论是从开发还是运维都可以以更低的成本解决问题

什么是MongoDB?

MongoDB是一个开源高性能无模式文档型数据库,当初的设计就是用于简化开发和方便扩展是NOSQL数据库产品中的一种最像关系型数据库(MySQL)的非关系型数据库,它所支持的数据结构非常松散,是一种类似于JSON的格式叫BSON,所以它既可以存储比较复杂的数据类型,又相当的灵活,MongoDB中的记录是一个文档,它是一个由字段和值对组成的数据结构,MongoDB文档类似于JSON对象,即一个文档认为就是一个对象,字段的数据类型是字符型,它的值除了使用基本的一些类型外,还可以包括其他文档,普通数组和文档数组。

注:MongoDB的无模式是指在数据存储过程中不需要事先定义表结构也不需要强制要求所有文档具有相同的字段这意味着MongoDB允许在同一个集合中存储不同结构的文档

在传统的关系型数据库中需要定义表结构和字段类型,然后才能存储数据。而在MongoDB中可以直接将文档插入到集合中MongoDB会自动为每个文档创建一个唯一的_id字段,并且不限制其他字段的存在和类型。

这种无模式的特性使得MongoDB非常灵活,能够适应数据结构的变化和快速迭代。开发人员可以根据具体需求来设计文档的结构,而不需要事先定义固定的表结构。这使得MongoDB适用于需要频繁更改和扩展数据模型的场景,如大数据、实时分析和快速迭代的应用程序。

然而,尽管MongoDB允许灵活的无模式设计,但在实际使用中也需要谨慎。过于灵活的结构可能导致数据冗余、查询复杂和数据一致性问题。因此,在设计数据库时,仍然需要考虑数据的结构和关系,以保证数据的一致性和查询性能

关系型数据库与MongoDB对比:

在这里插入图片描述

SQL术语/概念MongoDB术语/概念
database 数据库database 数据库
table 数据库表collection 集合
row 数据记录行document 文档
column 数据字段filed 域
index 索引index 索引
table joins 表连接不支持
嵌入文档 通过嵌入文档来代替表连接
primary key 主键primary key MongoDB自动将_id字段设置为主键

MongoDB中的数据模型:

MongoDB的最小存储单位就是文档对象文档对象对应于关系型数据库的行,数据在MongoDB中以BSON文档的格式存储在磁盘上,BSON是类JSON的一种二进制形式的存储格式,简称Binary JSON,BSON和JSON一样,支持内嵌的文档对象和数组对象,但是BSON有JSON没有的一些数据类型,如Date和BinData类型,BSON采用了类似于C语言结构体的名称,对表示方法,支持内嵌的文档对象和数组对象,具有轻量级可遍历性高效性三个优点,可以有效描述非结构化数据和结构化数据,这种格式的优点是灵活性高,但它的缺点是空间利用率不是很理想,BSON中,除了基本的JSON类型:string,integer,boolean,double,null,array和object,Mongo还使用了特殊的数据类型,这些类型包括date,object,id,binary,data,regular,expression和code,每一个驱动都以特定语言的方式实现了这些类型。

在这里插入图片描述

在Windows下启动和部署MongoDB:

在这里插入图片描述

mongod --dbpath=..\data\db

我们在启动信息中可以看到,mongoDB的默认端口号是27017
在这里插入图片描述

连接mongoDB:

通过shell连接:

在mongoDB的bin目录下cmd回车,输入mongosh,如下所示

在这里插入图片描述

通过图形可视化界面来连接:

在官网下载该软件即可!传送门

MongoDB对数据库进行操作的基本命令:

默认数据库的作用:

在MongDB中有以下四个是MongoDB为我们创建的数据库:

在这里插入图片描述

admin:从权限的角度看,这是"root"数据库,如果我们将一个用户添加到该数据库,那么这个用户就自动被赋予所有数据库的权限一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器

local:这个数据库永远不会被复制可以用来存储本地单台服务器的任意集合

config当Mongo用于分片设置时config数据库在内部使用用于保存分片的相关信息

comment1:在MongoDB中,comment1是一个特殊的数据库名称,它并没有特殊的作用或功能。这个名称仅仅是一个示例用于说明如何在MongoDB中添加注释注释可以在MongoDB命令中使用

查看当前的所有数据库:

show dbs或show databases

选择和创建数据库的语法格式:

use 数据库名;

如果该数据库名不存在,那么会自动创建,如下所示:

在这里插入图片描述

第二次显示所有数据库时,我们会发现articledb数据库并没有被包含其中呀,原因是在MongoDB中它的存储分为两部分一部分是内存存储一部分是磁盘存储,而当我们使用use articledb;进行存放时,实际上是存放在内存中,此时MongoDB并没有将该数据库持久化到磁盘中,因此,我们当前使用show命令是无法查出该数据库的,而只有当该数据库中包含数据,不为空时,它就会被持久化到磁盘中

查看当前使用正在使用的数据库:

db

虽然我们创建的articledb数据库并没有被持久化到磁盘中,但我们已经将其创建到了内存中,因此也是可以直接使用的,如下所示:

在这里插入图片描述

MongoDB中默认的数据库为test,如果我们没有选择数据库,那么所有的数据都会被放在test数据库中

数据库的命名要求和我们之前学过的结构化数据库(MySql,SQL server)是完全一样的,这里我们就不过多赘述了

删除持久化数据库:

db.dropDatabase()

在这里插入图片描述

MongoDB对集合操作的基本命令:

创建集合:

集合类似于关系型数据库中的表,可以显式的创建,也可以隐式地创建

显式创建通过操作命令将其创建

//创建集合
db.createCollection(name)
//查询集合
show collections

举例:

//集合名无论什么类型都要使用双引号引用
db.createCollection("MyMongoDB");

隐式创建

直接插入文档如下所示,如果当前集合不存在,那么会直接创建一个集合

//插入文档后,查询所有的集合就包括My
db.My.insert({id:1,name:"张三",age:10
})

删除集合:

db.要删除的集合名称.drop()

MongoDB对文档操作的基本命令:

单个文档插入:

使用insert()方法

db.要插入的集合名称.insert(document)

批量文档插入:

使用insertMany():

db.要插入的集合名称.insertMany([{document1},{document2}....])

举例:

db.wjr.insertMany([{id:2,name:"易烊千玺",age:19},{id:3,name:"王俊凯",age:24},{id:4,name:"王源",age:23}]);

查询集合中的所有文档:

//查询所有的
db.要查询的集合名称.find()
//条件查询
db.要查询的集合名称.find(限制条件)
//条件查询--返回符合条件的第一条数据
db.要查询的集合名称.findOne(限制条件)
//投影查询--将某个字段名的值设置成1表示查询结果只显示该字段的内容,将_id的值设置成0表示不显示默认字段_id这一列
db.要查询的集合名称.find([字段名:1,_id:0])

文档使用插入try-catch:

插入时指定了_id,则主键就是该值,如果某条数据插入失败将会终止插入,但已经插入成功的数据不会回滚掉,因为批量插入由于数据较多容易出现失败,因此,可以使用try catch进行异常捕捉处理,测试的时候可以不处理

//如果插入数据时发生错误,那么错误信息会被输出
try{db.要插入数据的集合名称.insert([{"_id":1,"姓名":"Lisa"}]);}catch(e){print(e);}

文档的更新:

通过使用修改器$set来实现:

//将_id为1的名字修改为李萍
db.要修改的集合名称.update({_id:1},{$set:{"姓名":"李萍"}})

批量的修改:

//将id为2的所有姓名修改为张明
db.要修改的集合的名称.update({id:"2"},{$set:{"姓名":"张明"}},{multi:true})

注意:{multi:true}不能省略,否则会出现只将满足条件的第一条数据修改

列值增长的修改:

//将_id为9的用户年龄设置为+1,通过$inc运算符来实现
db.要修改的集合名称.update({_id:9},{$inc:{"年龄":NumberInt(1)}})

文档的删除:

删除文档的命令:

//条件删除
db.要删除的集合名称.remove(条件)
//删除所有的数据
db.要删除的集合名称.remove({})

文档的分页查询:

统计所有的记录数:

//统计当前集合中的所有记录条数
db.要统计的集合名称.count()
//统计该集合中姓名为张三的记录条数
db.要统计的集合名称.count({姓名:"张三"})

分页列表查询:

可以使用limit()方法来读取指定数量的数据,使用skip()方法跳过指定数量的数据

//返回当前集合查询结果的Number条数据
db.要查询的集合名称.find().limit(Number)
//将当前集合查询结果的前Number条数据不显示,默认值是0
db.要查询的集合名称.find().skip(Number)

两者也可以同时使用:

//返回当前集合查询结果的Number1条数据,并不显示查询结果的前Number2条数据
db.要查询的集合名称.find().limit(Number1).skip(Number2)

排序查询:

sort()方法可以通过参数指定排序的字段,并使用1和-1来指定排序的方式,其中1为升序排列,而-1是用于降序排列

//将查询结果根据_id进行降序排列,字段也可以指定多个,比如我们可以同时设定根据某个字段进行升序排列,某个字段进行降序排列
db.要查询的集合名称.find().sort({_id:-1})

注:skip(),limit(),sort()三个同时执行时,执行的顺序是先sort(),然后是skip(),最后是显示的limit(),和命令编写的顺序无关

正则的复杂条件查询:

MongoDB的模糊查询是通过正则表达式的方式实现的,格式为:

//查询该集合中姓名以张开头的文档
db.要查询的集合名称.find({"姓名":/^/})
//查询该集合中姓名中包含明的文档
db.要查询的集合名称.find({"姓名"://})

比较查询:

//查询该集合中age大于12的所有文档
db.要查询的集合名称.find({age:{$gt:NumberInt(12)}})//查询该集合中age小于12的所有文档
db.要查询的集合名称.find({age:{$lt:NumberInt(12)}})//查询该集合中age大于等于12的所有文档
db.要查询的集合名称.find({age:{$gte:NumberInt(12)}})//查询该集合中age小于等于12的所有文档
db.要查询的集合名称.find({age:{$lte:NumberInt(12)}})//查询该集合中age不等于12的所有文档
db.要查询的集合名称.find({age:{$ne:NumberInt(12)}})

包含查询:

包含使用$in操作符

//查询该集合中姓名字段包含a或者c
db.要查询的集合名称.find({"姓名":{$in:["a","c"]}})

不包含使用$nin操作符

//查询该集合中姓名字段不包含a或者c
db.要查询的集合名称.find({"姓名":{$in:["a","c"]}})

条件连接查询:

我们如果需要查询同时满足两个以上条件需要使用$and操作符将条件进行关联,相当于我们之前学学过的结构化数据库中的and

格式为:

$and:[{},{},{},....]
//查询该集合中age大于等于12并且小于等于19的文档
db.要查询的集合.find({$and:[{age:{$gte:NumberInt(12)}},{age:{$lt:NumberInt(19)}}]})

如果两个以上条件之间是或者的关系,我们使用$or操作符进行关联,与前面的and格式相同

$or:[{},{},{},....]
//查询该集合中age大于等于12或者小于等于19的文档
db.要查询的集合.find({$or:[{age:{$gte:NumberInt(12)}},{age:{$lt:NumberInt(19)}}]})

索引—Index:

索引支持在MongoDB中高效地执行查询。如果没有索引MongoDB必须执行全集合扫描,即扫描集合中的每个文档以选择与查询语句匹配的文档。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒其至几分钟,这对网站的性能是非常致命的。

如果查询存在适当的索引,MongoDB可以使用该索引限制必须检查的文栏数。

索引是特殊的数据结构,它以易于遍历的形式存储集合数据集的一小部分。索引存储特定字段或一组字段的值,按字段值排序。索引项的排序支持有效的相等匹配和基于范围的查询操作。此外,MongoDB还可以使用索引中的排序返回排序结果。

单字段索引:

MongoDB支持在文档的单个字段上创建用户定义的升序/降序索引,称为单字段索引(Single FieldIndex)。对于单个字段索引和排序操作,索引键的排序顺序(即升序或降序)并不重要,因为MongoDB可以在任何方向上遍历索引

复合索引:

MongoDB还支持多个字段的用户定义索引,即复合索引(CompoundIndex)。复合索引中列出的字段顺序具有重要意义。例如,如果复合索引由[ userid: 1,score:-1组成,则索引首先按userid正序排序,然后在每个userid的值内,再在按score倒序排序。

索引的管理操作:

索引的查看:

说明:返回一个集合中的所有索引的数组。

语法:

db.collection.getIndexes()

注:该语法命令运行要求是MongoDB3.0+

索引的创建:

在集合上创建索引:

语法:

db.collection.createIndex(keys,options)

keys:它的类型为document,包含字段值对的文档,其中字段是索引键值描述该字段的索引类型对于字段上的升序索引,请指定值1;对于降序索引,请指定值-1;比如:{字段:1或-1},其中1为指定按升序创建索引,如果你想按降序来创建索引指定为-1即可,另外,MongoDB支持几种不同的索引类型包括文本,地理空间和哈希索引。

options:它的类型为document,它是可选的,包含一组控制索引创建的选项的文档。

options的常见可选参数如下所示:

unique:它的类型为Boolean,它表示创建的索引是否唯一,指定true创建唯一索引,默认为false

name:它的类型为String,它表示索引的名称,如果未指定,MongoDB通过连接索引的字段名和排序顺序生成一个索引名称。

索引的移除:

说明:可以移除指定的索引,或者移除所有索引

指定索引的移除

db.collection.dropIndex(index)

参数:

index:它的类型为string或者document,它用来指定要删除的索引可以通过索引名称或索引规范文档指定索引若要删除文本索引,请指定索引名称

所有索引的删除

db.collection.dropIndexs()

索引的使用:

执行计划:

分析查询性能通常使用执行计划(解释计划)来查看查询的情况,如查询耗费的时间,是否基于索引查询等。

那么通常,我们想知道建立的索引是否有效,效果如何,都需要通过执行计划查看。

语法:

db.collection.find(query,options).explain(options)

涵盖的查询:

查询条件查询的投影仅包含索引字段时MongoDB直接从索引返回结果,而不扫描任何文档或将文档带入内存,这些覆盖的查询可以非常有效。

存放文章评论的数据放入MongoDB中,数据结构参考如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/189776.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高防CDN:护航网络安全的卓越之选

在当今数字化时代,网络攻击与日俱增,为了确保网站和应用程序的稳定运行,高防CDN(高防御内容分发网络)应运而生。选择高防CDN的理由不仅源于其强大的防护性能,还体现了其与硬件防火墙异曲同工的奥妙。 选择高…

【蓝桥杯软件赛 零基础备赛20周】第3周——填空题

报名明年4月蓝桥杯软件赛的同学们,如果你是大一零基础,目前懵懂中,不知该怎么办,可以看看本博客系列:备赛20周合集 20周的完整安排请点击:20周计划 文章目录 00. 2023年第14届参赛数据0. 上一周答疑1. 填空…

进亦忧,退亦忧,Github Copilot 集成进入 Visual Studio 带来的思考

开篇想到《岳阳楼记》的结尾: 不以物喜,不以己悲;居庙堂之高则忧其民;处江湖之远则忧其君。是进亦忧,退亦忧。然则何时而乐耶?其必曰:“先天下之忧而忧,后天下之乐而乐”乎。未来30…

【信息安全原理】——传输层安全(学习笔记)

📖 前言:为保证网络应用,特别是应用广泛的Web应用数据传输的安全性(机密性、完整性和真实性),可以在多个网络层次上采取安全措施。本篇主要介绍传输层提供应用数据安全传输服务的协议,包括&…

python异常、模块与包

1.异常 异常:当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”,也就是我们常说的BUG。 1.1捕获异常 基本语法: try:可能发生错误代码 except:如果出现…

数据分析实战 | SVM算法——病例自动诊断分析

目录 一、数据分析及对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据准备 七、模型训练 八、模型应用及评价 一、数据分析及对象 CSV文件——“bc_data.csv” 数据集链接:https://download.csdn.net/download/m0_70452407/88…

阿里云国际站:全球加速GA

文章目录 一、前言 二、阿里云全球加速的概念 三、阿里云全球加速的功能优势 四、阿里云全球加速的原理 五、阿里云全球加速的应用场景 六、写在最后 一、前言 随着互联网的快速发展,网站速度已经成为了用户访问体验的一个重要指标。阿里云加速作为一种新的技…

黑马程序员微服务Docker实用篇

Docker实用篇 0.学习目标 1.初识Docker 1.1.什么是Docker 微服务虽然具备各种各样的优势,但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中,依赖的组件非常多,不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署…

CCNA课程实验-13-PPPoE

目录 实验条件网络拓朴需求 配置实现基础配置模拟运营商ISP配置ISP的DNS配置出口路由器OR基础配置PC1基础配置 出口路由器OR配置PPPOE拨号创建NAT(PAT端口复用) PC1测试结果 实验条件 网络拓朴 需求 OR使用PPPoE的方式向ISP发送拨号的用户名和密码,用户名&#xf…

【案例】超声波测距系统设计

1.1 总体设计 1.1.1 概述 学习了明德扬至简设计法和明德扬设计规范,本人用FPGA设计了一个测距系统。该系统采用超声波进行测量距离再在数码管上显示。在本案例的设计过程中包括了超声波的驱动、三线式数码管显示等技术。经过逐步改进、调试等一系列工作后&#xf…

【数据结构】树与二叉树(十三):递归复制二叉树(算法CopyTree)

文章目录 5.2.1 二叉树二叉树性质引理5.1:二叉树中层数为i的结点至多有 2 i 2^i 2i个,其中 i ≥ 0 i \geq 0 i≥0。引理5.2:高度为k的二叉树中至多有 2 k 1 − 1 2^{k1}-1 2k1−1个结点,其中 k ≥ 0 k \geq 0 k≥0。引理5.3&…

vue,react虚拟dom

Virtual DOM 前言 在传统的Web开发中,直接操作真实的DOM通常是一个昂贵且低效的操作。为了解决这个问题,Virtual DOM(虚拟DOM)被引入为一个中间层,允许开发者在内存中进行操作,从而避免频繁且不必要的真实D…

深度学习的集体智慧:最新发展综述

一、说明 我们调查了来自复杂系统的想法,如群体智能、自组织和紧急行为,这些想法在机器学习中越来越受欢迎。人工神经网络正在影响我们的日常生活,从执行预测性任务(如推荐、面部识别和对象分类)到生成任务&#xff08…

git的分支及标签使用及情景演示

目录 一. 环境讲述 二.分支 1.1 命令 1.2情景演练 三、标签 3.1 命令 3.2 情景演示 ​编辑 一. 环境讲述 当软件从开发到正式环境部署的过程中,不同环境的作用如下: 开发环境:用于开发人员进行软件开发、测试和调试。在这个环境中…

【Spring Boot 源码学习】初识 SpringApplication

Spring Boot 源码学习系列 初识 SpringApplication 引言往期内容主要内容1. Spring Boot 应用程序的启动2. SpringApplication 的实例化2.1 构造方法参数2.2 Web 应用类型推断2.3 加载 BootstrapRegistryInitializer2.4 加载 ApplicationContextInitializer2.5 加载 Applicatio…

Codeforces Round 788 (Div. 2) E. Hemose on the Tree(树上构造)

题目 t(t<5e4)组样例&#xff0c;每次给定一个数p&#xff0c; 表示一棵节点数为的树&#xff0c; 以下n-1条边&#xff0c;读入树边 对于n个点和n-1条边&#xff0c;每个点需要赋权&#xff0c;每条边需要赋权&#xff0c; 权值需要恰好构成[1,2n-1]的排列 并且当你赋…

阿里云ACK(Serverless)安装APISIX网关及APISIX Ingress Controller

在k8s上安装apisix全家&#xff0c;通过helm安装很简单&#xff0c;但是会遇到一些问题。 安装 首先登录阿里云控制台&#xff0c;在ACK集群详情页&#xff0c;进入CloudShell&#xff0c;执行下面helm命令安装apisix、apisix-ectd、apisix-dashboard和apisix-ingress-contro…

汽车ECU的虚拟化技术初探(一)

目录 1.为什么要提汽车ECU的虚拟化&#xff1f; 2.虚拟化技术分类 2.1 硬件虚拟化 2.2 操作系统虚拟化 问题引入&#xff1a; Hypervisor是如何来管理和隔离硬件资源&#xff0c;保证各个不同功能的应用程序的资源使用安全和资源调度&#xff1f;没有MMU就做不了虚拟化&am…

扭矩传感器信号模拟地、数据地与电源地

在电子电路中&#xff0c;电源地、信号地、数字地和模拟地都是不同的地&#xff08;ground&#xff09;节点&#xff0c;它们在电路中有不同的作用。 电源地&#xff08;Power Ground&#xff09;是指用于连接电源电源回路的地节点。在大多数电子设备中&#xff0c;电源地通常是…

Git Commit 之道:规范化 Commit Message 写作指南

1 commit message 规范 commit message格式都包括三部分&#xff1a;Header&#xff0c;Body和Footer <type>(<scope>): <subject><body><footer>Header是必需的&#xff0c;Body和Footer则可以省略 1.1 Header Type&#xff08;必需&#xf…