MongoDB基础知识~

news2024/11/18 23:32:02

引入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.coloradmin.cn/o/1200058.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用visualStudio发布可执行文件

编译成功后会在程序项目的路径下创建一个debug文件夹和一个release文件夹 文件夹中的具体文件入下所示 生成32位的可执行文件 32位的可执行文件可以在64位的计算机中执行,而64位的操作系统程序只能在64位的计算机中执行安装运行库的安装包根据电脑的版本选择合适的…

手机开机入网流程 KPI接通率和掉线率

今天我们来学习手机开机入网流程是怎么样的。以及RRC连接和重建流程(和博主之前讲TCP三次握手,四次挥手原理很相似)是什么样的,还有天线的KPI指标都包括什么,是不是很期待啊~ 目录 手机开机入网流程 ATTACH/RRC连接建立过程 KPI接通率和掉…

【YOLOv5】【模型压缩与加速】【量化】FP32、FP16、INT8

量化是将模型参数的存储类型从高精度存储降到低精度存储,从而达到减小模型体积大小、加快模型推理速度的效果。 目录 FP32量化 FP16量化 INT8量化 FP32量化 这个直接使用yolov5的export导出32位存储的 engine格式模型即可 python export.py --weights runs/train/…

前端---认识HTML

文章目录 什么是HTML?HTML的读取、运行HTML的标签注释标签标题标签段落标签换行标签格式化标签图片标签a标签表格标签列表标签表单标签form标签input标签文本框单选框复选框普通按钮提交按钮文件选择框 select标签textarea标签特殊标签div标签span标签 什么是HTML&a…

No188.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

C语言基础篇4:变量与存储

1 局部变量和全局变量 在介绍局部变量和全局变量前,先,了解一些关于作用域方面的内容。作用域的作用就是决定程序中的哪些语句是可用的,换句话说,就是程序中的可见性。作用域有局部作用域和全局作用域,那么局部变量就具…

深入研究SVN代码检查的关键工具:svnchecker vs. SonarQube,选择最适合你的代码检查工具

目录 一、SVN代码检查(整合svnchecker)1、创建SVN代码库2、下载安装包3、修改SVN配置4、新建代码检查配置文件(名称自定义)5、hooks目录添加配置文件6、设置只对Java文件进行检查7、测试 二、SonarQube代码检测1、什么是SonarQube2、MySQL数据库的安装3、SonarQube服务端软件安…

Python之函数进阶-函数执行原理

Python之函数进阶-函数执行原理 函数执行流程 C语言中,函数的活动和栈有关。栈是后进先出的数据结构。栈是由底端向顶端生长,栈顶加入数据成为压栈、入栈、栈顶弹出数据称为出栈。 def add(x, y):r x yprint(r)return rdef main():a 1r add(a, 2)r…

Pytorch损失函数、反向传播和优化器、Sequential使用

Pytorch_Sequential使用、损失函数、反向传播和优化器 文章目录 nn.Sequential搭建小实战损失函数与反向传播优化器 nn.Sequential nn.Sequential是一个有序的容器,用于搭建神经网络的模块被按照被传入构造器的顺序添加到nn.Sequential()容器中。 import torch.nn …

【操作系统】1.1 操作系统的基础概念、功能和目标以及特性

📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…

Mac电脑配置Flutter开发环境

1.进入官网下载页: Flutter SDK releases | Flutter 可以看到有 Windows、macOS、Linux三种系统的下载包 选择macOS,然后点击下载 Stable channel(稳定版)中的最新版本,下载完成后可以移动到资源库Library中。 2.下载…

使用easyui前端框架构建一个crud应用(看完这篇就够了)

easyui是博主最喜欢的前端框架,因为它提供了多种主题样式和各种好看的ui组件。 这篇文章将会详细地介绍easyui前端框架的使用,通过创建一个crud应用来帮助大家快速掌握easyui的使用。 一、快速开始 这个章节主要介绍easyui前端框架的下载,ea…

Leetcode—680.验证回文串II【简单】

2023每日刷题&#xff08;二十七&#xff09; Leetcode—680.验证回文串II 实现代码 class Solution { public:bool judgeFunc(string s, int left, int right) {while(left < right) {if(s[left] ! s[right]) {return false;}left;right--;}return true;}bool validPalin…

按键精灵中的字符串常用的场景

在使用按键精灵编写脚本时&#xff0c;与字符串有关的场景有以下几种&#xff1a; 1. 用时间字符串记录脚本使用截止使用时间 Dim localTime "2023-11-12 00:15:14" Dim networkTime GetNetworkTime() TracePrint networkTime If networkTime > localTime The…

LeetCode200.岛屿数量

看完题目我还感觉这道题目有点难&#xff0c;没想到20分钟不到就完全靠自己给写出来了。我就是按照自己的想法来&#xff0c;我用一个等大的visit数组来表示grid数组中的这个元素是否被访问过&#xff08;是否已经被判断了是不是岛屿&#xff09;。 先用一个大的循环对grid数组…

threejs(12)-着色器打造烟雾水云效果

一、自己封装水波纹效果 src/main/main01.js import * as THREE from "three";import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; import gsap from "gsap"; import * as dat from "dat.gui"; import ver…

解决springboot接受buffer文件为null(从picgo上传buffer看springmvc处理过程)

1. 前言&#xff1a; picgo插件的简单开发 上篇文章我们简单写了picgo上传插件&#xff0c;但是当我们测试的时候&#xff0c;发现问题了&#xff0c;后端MultipartFile file接受到的文件为null。 2. 排查问题&#xff1a; 参考的文档 picgo api列表关于multipart form-data中…

U-Mail邮件系统三大安全措施,防止信息泄露!

在当信息化高速发展的今天&#xff0c;国内很多企业业务流程对OA系统、CRM系统、ERP系统、邮件系统等办公应用依赖度越来越高。这些办公应用给企业带来便利的同时也伴随着越来越多的信息安全问题&#xff0c;而在日常的办公场景中&#xff0c;由于内部员工非法泄漏或黑客入侵导…

Qt实现TCP调试助手 - 简述如何在Qt中实现TCP多并发

简介 软件开发中&#xff0c;可能经常会用到TCP调试工具。本人使用QT开发了一款TCP调试工具&#xff0c;方便大家使用。本文章主要介绍下&#xff0c;该工具的功能&#xff0c;以及如何在Qt中实现TCP服务器的并发。 界面展示 安装界面 桌面图标。安装后会生成桌面图标&#…

(三)正点原子I.MX6ULL kernel6.1挂根文件系统

一、概述 移植NXP官方最新的linux kernel&#xff08;linux-imx-lf-6.1.y&#xff09; 移植方法基本参照正点原子教程 移植开发板&#xff1a;正点原子阿尔法2.1 二、添加开发板到内核 进入内核目录下&#xff0c;先修改Makefile 打开终端&#xff1a; cp arch/arm/configs/im…