MongoDB

MongDB

MongoDB简介

**MongoDB 是免费开源的跨平台 NoSQL 数据库,**命名源于英文单词 humongous,意思是「巨大无比」,可见开发组对 MongoDB 的 定位。与关系型数据库不同,MongoDB 的数据以类似于 JSON 格 式的二进制文档存储

{
   
   
    name: "McConaughey",
    age: 18,
    hobbies: ["travel", "swimming"]
}

文档型的数据存储方式有几个重要好处

文档的数据类型可以对应 到语言的数据类型,如数组类型(Array)和对象类型(Object);

文档可以嵌套,有时关系型数据库涉及几个表的操作,在 MongoDB 中一次就能完成,可以减少昂贵的连接花销;

文档不对 数据结构加以限制,不同的数据结构可以存储在同一张表。

MongoDB的适用场景

**网站数据:**Mongo 非常适合实时的插入,更新与查询,并具备网站 实时数据存储所需的复制及高度伸缩性。

**缓存:**由于性能很高,Mongo 也适合作为信息基础设施的缓存层。 在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数 据源过载。

**大尺寸、低价值的数据:**使用传统的关系型数据库存储一些大尺寸 低价值数据时会比较浪费,在此之前,很多时候程序员往往会选择 传统的文件进行存储。

**高伸缩性的场景:**Mongo 非常适合由数十或数百台服务器组成的数据库,Mongo 的路线图中已经包含对MapReduce 引擎的内置支持 以及集群高可用的解决方案。

**用于对象及JSON 数据的存储:**Mongo 的BSON 数据格式非常适合 文档化格式的存储及查询。

MongoDB的行业具体应用

游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分 等直接以内嵌文档的形式存储,方便查询、更新。

物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中 会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询就能 将订单所有的变更读取出来。

社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋 友圈信息,通过地理位置索引实现附近的人、地点等功能。

物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及 设备汇报的日志信息,并对这些信息进行多维度的分析。

直播,使用 MongoDB 存储用户信息、礼物信息等。

如何抉择是否使用MongoDB
应用特征 Yes/No
应用不需要复杂事务及复杂join支持 必须yes
新应用,需求会变,数据模型无法确定,想快速迭代开发 ?
应用需要2000-3000以上的读写QPS(更高也可以) ?
应用需要TB甚至 PB 级别数据存储 ?
应用发展迅速,需要能快速水平扩展 ?
应用需要大量的地理位置查询、文本查询 ?
应用需要99.999%高可用 ?

有一个yes就可以选择MongoDB,两个以上yes,选MongoDB绝对 不后悔

与关系型数据库比较

MongoDB与RDMS(关系型数据库)比较,如下图所示

RDMS MongoDB
database(数据库) database(数据库)
table (表) collection( 集合)
row( 行) document( BSON 文档)
column (列) field (字段)
index(唯一索引、主键索引) index (支持地理位置索引、全文索引 、哈希索引)
join (主外键关联) embedded Document (嵌套文档)
primary key(指定1至N个列做主键) primary key (指定_id field做为主键)

什么是BSON

BSON是一种类似于JSON的二进制形式的存储格式,简称Binary JSON,它和JSON一样,支持内嵌的文档对象和数组对象,但是 BSON有JSON没有的一些数据类型,如Date和BinData类型。 BSON有三个特点:轻量性、可遍历性、高效性

下表列出了MongoDB中Document可以出现的数据类型:

数据类型 说明 document举例
String 字符串 {key:“cba”}
Integer 整型数值 {key:2}
Boolean 布尔型 {key:true}
Double 双精度浮点数 {key:0.23}
ObjectId 对象id,用于创建文档的id {_id:new ObjectId()}
Array 数组 {arr:[“jack”,“tom”]}
Timestamp 时间戳 { createTime: new Timestamp() }
object 内嵌文档 {student:{name:“zhangsan”,age:18}}
null 空值 {key:null}
Date或者ISODate 日期时间 {birthday:new Date()}
Code 代码 {setPersonInfo:function(){}}

MongoDB安装(Centos)

独立安装

进入/etc/yum.repos.d目录,创建文件

[root@192 yum.repos.d]# pwd
/etc/yum.repos.d
[root@192 yum.repos.d]# vim mongodb-org-5.0.repo

在文件内输入yum源地址

[mongodb-org-5.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/5.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc

安装之前先更新

yum update

开始安装

yum -y install mongodb-org

安装完成后,查看mongo的安装位置

whereis mongod 

修改配置文件

#vim /etc/mongod.conf
bindIp: 172.0.0.1 改为 bindIp: 0.0.0.0 #(可以远程连接)

启动/停止/重启/查看

systemctl start mongod.service
systemctl stop mongod.service
systemctl restart mongod.service
systemctl status mongod.service

设置开机自启动

systemctl enable mongod.service

mongo shell 的启动

# 进入/usr/bin/目录
./mongo

指定主机和端口的方式启动

./mongo --host=主机IP --port=端口

docker安装

访问hub.docker.com,搜索mongo镜像

在这里插入图片描述

查看可用的镜像

在这里插入图片描述

获取你想要拉取的镜像

docker pull mongo:5.0.9-focal

查看已下载的镜像

docker images

创建挂载目录

mkdir -p /mnt/mongodb/data --创建保存数据目录

创建并运行 mongo 容器

docker run -itd --privileged=true --name mongo5 
-p 27017:27017 -v /mnt/mongodb/data:/data/db 
mongo:5.0.9-focal

使用GUI工具连接MongoDB

使用NosqlBooster For MongoDB客户端工具连接MongoDB数据 库

在这里插入图片描述

MongoDB架构

MongoDB逻辑结构

在这里插入图片描述

MongoDB 与 MySQL 中的架构相差不多,底层都使用了可插拔的 存储引擎以满足用户的不同需要。用户可以根据程序的数据特征选 择不同的存储引擎,在最新版本的 MongoDB 中使用了 WiredTiger 作为默认的存储引擎,WiredTiger 提供了不同粒度的并发控制和压缩机制,能够为不同种类的应用提供了最好的性能和存储率。

在存储引擎上层的就是 MongoDB 的数据模型和查询语言了,由于 MongoDB 对数据的存储与 RDBMS有较大的差异,所以它创建了一 套不同的数据模型和查询语言。

MongoDB数据模型

与SQL数据库不同,在SQL数据库中,在插入数据之前必须确定和 声明表的架构,默认情况下,MongoDB的集合不要求其文档具有相 同的架构。

结构灵活

​ 单个集合中的文档不需要具有相同的字段集合,并且集合中的文档 之间的字段数据类型可能不同; 可灵活更改集合中文档的结构,如添加新字段、删除现有字段或将 字段值更改为新类型,将文档更新为新结构。

文档结构
内嵌

​ 内嵌的方式指的是把相关联的数据保存在同一个文档结构之中。 MongoDB的文档结构允许一个字段或者一个数组内的值作为一个嵌 套的文档。

在这里插入图片描述

引用

​ 引用方式通过存储数据引用信息来实现两个不同文档之间的关联,应 用程序可以通过解析这些数据引用来访问相关数据。

在这里插入图片描述

如何选择数据模型
选择内嵌:

​ 数据对象之间有包含关系 ,一般是数据对象之间有一对多或者一对一 的关系 。

​ 需要经常一起读取的数据。

​ 有 map-reduce/aggregation 需求的数据放在一起,这些操作都只 能操作单个 collection。

选择引用:

​ 当内嵌数据会导致很多数据的重复,并且读性能的优势又不足于覆 盖数据重复的弊端 。

​ 需要表达比较复杂的多对多关系的时候 。

​ 大型层次结果数据集 嵌套不要太深。

MongoDB存储引擎

存储引擎负责管理数据如何在磁盘和内存中存储,MongoDB支持多 种存储引擎,不同的存储引擎都有其在特定工作环境下的特点,选 择适合的存储引擎能够有效提高应用程序的性能。

WiredTiger存储引擎 (默认)

WiredTiger适合大多数工作场景,从MongoDB 3.2开始默认的存储 引擎是WiredTiger,3.2版本之前的默认存储引擎是MMAPv1, MongoDB 4.x版本不再支持MMAPv1存储引擎。

支持document级别并发操作

​ WiredTiger对写入操作使用document级并发控制。因此,多个客 户端可以同时修改集合的不同文档。对于大多数读写操作, WiredTiger使用乐观并发控制。WiredTiger仅在全局、数据库和集 合级别使用意向锁。当存储引擎检测到两个操作之间的冲突时,其 中一个操作将引发写入冲突,MongoDB会对用户透明地重试该操 作。

Snapshots and Checkpoints(快照和检查点)

​ WiredTiger使用多版本并发控制(MVCC)。在操作开始时, WiredTiger会向操作提供数据的point-in-time快照,快照显示了数 据在内存中的一致性视图。

​ 从3.6版开始,MongoDB将WiredTiger配置为每隔60秒创建检查点 (即将快照数据写入磁盘)。在早期版本中,MongoDB将检查点设 置为在WiredTiger中每隔60秒或写入2 GB日志数据时(以先发生的 为准)对用户数据进行检查。

Journal(日志)

​ WiredTiger将日志与检查点结合使用,以确保数据的持久性。 WiredTiger日志将保留检查点之间的所有数据修改。如果 MongoDB在两个检查点之间退出,它将使用日志重播自上一个检查 点以来修改的所有数据

Compression(压缩)

​ 使用WiredTiger存储引擎,MongoDB会对所有集合和索引进行压 缩,压缩以牺牲额外的CPU为代价,最大限度地减少了磁盘的使 用。默认情况下,WiredTiger对所有集合使用block compression,并对索引使用 prefix compression。

内存使用

​ 对于WiredTiger,MongoDB利用WiredTiger内部缓存和文件系统 缓存。从MongoDB 3.4开始,默认WiredTiger内部缓存大小为以下 两者中的较大值:50% of (RAM - 1 GB) 256 MB

In-memory存储引擎

从MongoDB 企业版3.2.6版开始,In-Memory存储引擎是64位版本 中广泛使用(general availability GA)的一部分。除某些元数据和 诊断数据外,In-Memory存储引擎不维护任何磁盘上的数据,包括 配置数据,索引,用户凭据等。

In-Memory存储引擎设置

​ 配置–storageEngine选项值为inMemory;如果使用配置文件,则 配置storage.engine

mongod  --storageEngine inMemory  --dbpath 
<path>

​ 配置–dbpath,如果使用配置文件则配置storage.dbPath。尽管InMemory存储引擎不会将数据写入文件系统,但它会在–dbpath中 维护小型元数据文件和诊断数据以及用于构建大型索引的临时文 件。

storage:
   engine: inMemory
   dbPath: <path>
并发(concurrency)

​ In-Memory存储引擎对于写入操作使用了document级并发控制。 多个客户端可以同时修改集合的不同文档。

内存使用

​ 默认情况下,In-Memory存储引擎使用50%的物理RAM减去1 GB。 如果写操作的数据超过了指定的内存大小,则MongoDB返回错误.

"WT_CACHE_FULL: operation would overflow cache"

要指定新大小,可使用YAML格式配置文件的

storage:
   engine: inMemory
   dbPath: <path>
   inMemory:
     engineConfig:
         inMemorySizeGB: <newSize>
事务

​ 从MongoDB 4.2开始,复制集和分片集群上支持事务,其中:主成 员节点使用WiredTiger存储引擎,同时,辅助成员使用WiredTiger 存储引擎或In-Memory存储引擎。 在MongoDB 4.0中,只有使用WiredTiger存储引擎的复制集才支持 事务。

MongoDB命令

基本操作

查看数据库

show dbs;

切换数据库 如果没有对应的数据库则创建

use 数据库名;

创建集合

db.createCollection("集合名")

查看集合

show tables;
show collections;

删除集合

db.集合名.drop();

删除当前数据库

db.dropDatabase();

CRUD操作

添加文档

添加单个文档,如果集合不存在,会创建一个集合

db.collection.insertOne() 

如果不指定id, MongoDB会使用ObjectId的value作为id

db.inventory.insertOne({
   
    item: "canvas", qty: 100, tags: ["cotton"], size: {
   
    h: 28, w: 35.5, uom: "cm" }})

添加多个文档

db.collection.insertMany()

如果不指定id, MongoDB会使用ObjectId的value作为id

db.inventory.insertMany([
{
   
    item: "journal", qty: 25, tags: ["blank", "red"], size: {
   
    h: 14, w: 21, uom: "cm" } },
{
   
    item: "mat", qty: 85, tags: ["gray"], size: {
   
    h: 27.9, w: 35.5, uom: "cm" } },
{
   
    item: "mousepad", qty: 25, tags: ["gel", "blue"],size: {
   
    h: 19, w: 22.85, uom: "cm" 
}}])
查询文档

首先插入一批文档,再进行查询

db.inventory.insertMany( [
   {
   
    item: "journal", qty: 25, size: {
   
    h: 14, w: 21, uom: "cm" }, status: "A" },
   {
   
    item: "notebook", qty: 50, size: {
   
    h: 8.5, w: 11, uom: "in" }, status: "A" },
   {
   
    item: "paper", qty: 100, size: {
   
    h: 8.5, w: 11, uom: "in" }, status: "D" },
   {
   
    item: "planner", qty: 75, size: {
   
    h: 22.85, w: 30, uom: "cm" }, status: "D" },
   {
   
    item: "postcard", qty: 45, size: {
   
    h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);

查询集合所有文档

db.inventory.find({
   
   })

查询指定内容的文档,匹配1条

db.inventory.find( {
   
    size: {
   
    h: 14, w: 21, uom:"cm" } } )

匹配0条,原因是顺序不匹配

db.inventory.find( {
   
    size: {
   
    w: 21, h: 14, uom: "cm" } } )

匹配size中uom属性为“in”的文档

db.inventory.find( {
   
    "size.uom": "in" } )

匹配size中h属性值小于15的文档

db.inventory.find( {
   
    "size.h": {
   
    $lt: 15 } } )

匹配h属性小于15并且uom属性为“in”,并且“status”属性为"D"的文 档

db.inventory.find( {
   
    "size.h": {
   
    $lt: 15 }, "size.uom": "in", status: "D" } )

s

更新文档

插入下列文档,供更新操作

db.inventory.insertMany([
   {
   
    item: "canvas", qty: 100, size: {
   
    h: 28, w: 35.5, uom: "cm" }, status: "A" },
   {
   
    item: "journal", qty: 25, size: {
   
    h: 14, w: 21, uom: "cm" }, status: "A" },
   {
   
    item: "mat", qty: 85, size: {
   
    h: 27.9, w: 35.5, uom: "cm" }, status: "A" },
   {
   
    item: "mousepad", qty: 25, size: {
   
    h: 19, w: 22.85, uom: "cm" }, status: "P" },
   {
   
    item: "notebook", qty: 50, size: {
   
    h: 8.5, w: 11, uom: "in" }, status: "P" },
   {
   
    item: "paper", qty: 100, size: {
   
    h: 8.5, w: 11, uom: "in" }, status: "D" },
   {
   
    item: "planner", qty: 75, size: {
   
    h: 22.85, w: 30, uom: "cm" }, status: "D" },
   {
   
    item: "postcard", qty: 45, size: {
   
    h: 10, w: 15.25, uom: "cm" }, status: "A" },
   {
   
    item: "sketchbook", qty: 80, size: {
   
    h: 14, w: 21, uom: "cm" }, status: "A" },
   {
   
    item: "sketch pad", qty: 95, size: {
   
    h: 22.85, w: 
30.5, uom: "cm" }, status: "A" }]);

更新item值为“paper”的第一个文档 将它的size.uom设置为“cm”,status值设置为"P" 并且把lastModified字段更新为当前时间,如果该字段不存在,则 生成一个

db.inventory.updateOne(
   {
   
    item: "paper" },
   {
   
   $set: {
   
    "size.uom": "cm", status: "P" },
    $currentDate: {
   
    lastModified: true }}
)
#更新返回
#参数一:更新成功;参数二:匹配多少条;参数三:成功多少条。
#{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

更新qty属性值小于50的文档 将它的size.uom设置为“in”,status值设置为"P" 并且把lastModified字段更新为当前时间,如果该字段不存在,则 生成一个

db.inventory.updateMany(
   {
   
    "qty": {
   
    $lt: 50 } },
   {
   
    $set: {
   
    "size.uom": "in", status: "P" },
     $currentDate: {
   
    lastModified: true }
   }
)

把item属性为“paper”的文档替换成下面的内容

db.inventory.replaceOne(
   {
   
    item: "paper" },{
   
    item: "paper", instock: 
[ {
   
    warehouse: "A", qty: 60 }, {
   
    warehouse: 
"B", qty: 40 } ] })
删除文档

删除集合所有文档

db.inventory.deleteMany({
   
   })

删除指定条件的文档

db.inventory.deleteMany({
   
    status : "A" })

最多删除1个指定条件的文档

db.inventory.deleteOne( {
   
    status: "D" } )
与SQL语法的对应

在这里插入图片描述

在这里插入图片描述

聚合操作

通过聚合操作可以处理多个文档,并返回计算后的结果。

​ 对多个文档进行分组

​ 对分组的文档执行操作并返回单个结果

​ 分析数据变化

聚合管道

分别由多个阶段来处理文档,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值