分布式专题(4)之MongoDB快速实战与根本原理
一、MongoDB介绍1.1 什么是MongoDB
MongoDB是一个文档数据库(以JSON为数据模型),由C++语言编写,旨在为WEB应用提供可扩展的高性能存储解决方案。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的,它支持的数据结构非常松散,数据格式是BSON,一种类似JSON的二进制形式的存储格式,简称Binary JSON,和JSON一样支持内嵌的文档对象和数组对象,因此可以存储比力复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库表单查询的绝大部门功能,而且还支持对数据创建索引。原则上Oracle和Mysql能做的事变,MongoDB都能做(包括ACID事件)。
MongoDB在数据库总排名第5,仅次于Oracle、MySQL等RDBMS,在NoSQL数据库排名首位。从诞生以来,其项目应用广度、社区生动指数持续上升。
https://i-blog.csdnimg.cn/direct/7ee74e3b87f44ae980c8d99b8a16a59b.png
1.2 MongoDB vs 关系型数据库
MongoDB概念与关系型数据库(RDBMS)非常类似:
https://i-blog.csdnimg.cn/direct/0143757a8d414d778853fd6311954eca.png
[*]数据库(database):最外层的概念,可以明白为逻辑上的名称空间,一个数据库包含多个不同名称的聚集。
[*]聚集(collection):相当于SQL中的表,一个聚集可以存放多个不同的文档。
[*]文档(document):一个文档相当于数据表中的一行,由多个不同的字段构成。
[*]字段(field):文档中的一个属性,等同于列(column)。
[*]索引(index):独立的检索式数据结构,与SQL概念一致。
[*]_id:每个文档中都拥有一个唯一的_id字段,相当于SQL中的主键(primary key)。
[*]视图(view):可以看作一种虚拟的(非真实存在的)聚集,与SQL中的视图类似。从MongoDB 3.4版本开始提供了视图功能,其通过聚合管道技术实现。
[*]聚合操作($lookup):MongoDB用于实现“类似”表连接(tablejoin)的聚合操作符。
https://i-blog.csdnimg.cn/direct/079226333362475bbfd78c9c3a21159c.png
尽管这些概念大多与SQL标准定义类似,但MongoDB与传统RDBMS仍然存在不少差异,包括:
[*]半结构化,在一个聚集中,文档所拥有的字段并不需要是类似的,而且也不需要对所用的字段进行声明。因此,MongoDB具有很显着的半结构化特点。除了松散的表结构,文档还可以支持多级的嵌套、数组等灵活的数据类型,非常契合面向对象的编程模型。
[*]弱关系,MongoDB没有外键的约束,也没有非常强大的表连接本领。类似的功能需要使用聚合管道技术来弥补。
1.3 MongoDB技术上风
MongoDB基于灵活的JSON文档模型,非常适合敏捷式的快速开发。与此同时,其与生俱来的高可用、高水平扩展本领使得它在处置惩罚海量、高并发的数据应用时颇具上风。
[*]JSON 结构和对象模型接近,开发代码量低
[*]JSON的动态模型意味着更容易响应新的业务需求
[*]复制集提供99.999%高可用
[*]分片架构支持海量数据和无缝扩容
https://i-blog.csdnimg.cn/direct/bd1ba2a68cfd4d749913e043277c8fb8.png
简朴直观:从错综复杂的关系模型到一目了然的对象模型:
https://i-blog.csdnimg.cn/direct/fa6589ca3ee1439fbe9c9f8f62d62a83.png
快速:最简朴快速的开发方式
https://i-blog.csdnimg.cn/direct/32ecc038fbc642d681ba7511e5f149c2.png
灵活:快速响应业务变化
https://i-blog.csdnimg.cn/direct/15ccc3ac91734331babd3da095ceabe4.png
原生的高可用:
https://i-blog.csdnimg.cn/direct/d37a224b1296470eabf632114745f850.png
横向扩展本领
https://i-blog.csdnimg.cn/direct/84d2bbee509643c8bc0d0af663239540.png
1.4 MongoDB应用场景
从现在阿里云 MongoDB 云数据库上的用户看,MongoDB 的应用已经渗出到各个范畴:
[*]游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新;
[*]物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不绝更新,以MongoDB 内嵌数组的形式来存储,一次查询就能将订单全部的变更读取出来;
[*]社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能;
[*]物联网场景,使用 MongoDB 存储全部接入的智能设备信息,以及设备汇报的日记信息,并对这些信息进行多维度的分析;
[*]视频直播,使用 MongoDB 存储用户信息、礼品信息等;
[*]大数据应用,使用云数据库MongoDB作为大数据的云存储体系,随时进行数据提取分析,把握行业动态。|
国内外着名互联网公司都在使用MongoDB:
https://i-blog.csdnimg.cn/direct/bfa0107ddf01466e9a93013b41b558f6.png
1.4.1 如何判定当前业务是否适合使用MongoDB
没有某个业务场景必须要使用MongoDB才能解决,但使用MongoDB通常能让你以更低的成本解决问题。假如你不清楚当前业务是否适合使用MongoDB,可以通过做几道选择题来辅助决议。
https://i-blog.csdnimg.cn/direct/19d4706f108d45ce991eac262e7cc93a.png
只要有一项需求满意就可以考虑使用MongoDB,匹配越多,选择MongoDB越符合。
二、MongoDB环境搭建
2.1 linux安装MongoDB
环境预备:
[*]linux体系: centos7
[*]安装MongoDB社区版
#如何查看linux版本
# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
#下载MongoDB
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-6.0.5.tgz
tar -zxvf mongodb-linux-x86_64-rhel70-6.0.5.tgz
#创建dbpath和logpath
mkdir -p /mongodb/data /mongodb/log
#进入mongodb目录,启动mongodb服务
bin/mongod --port=27017 --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log \
--bind_ip=0.0.0.0 --fork --dbpath :指定数据文件存放目录
--logpath :指定日记文件,注意是指定文件不是目录
--logappend :使用追加的方式记载日记
--port:指定端口,默以为27017
--bind_ip:默认只监听localhost网卡
--fork: 后台启动
--auth: 开启认证模式
https://i-blog.csdnimg.cn/direct/de0c96a10786432a9f2f02bddb752327.png
添加环境变量:修改/etc/profile,添加环境变量,方便执行MongoDB下令,然后执行source /etc/profile 重新加载环境变量
export MONGODB_HOME=/usr/local/soft/mongodb
PATH=$PATH:$MONGODB_HOME/bin 使用配置文件启动服务:编辑/mongodb/conf/mongo.conf文件,内容如下:
systemLog:
destination: file
path: /mongodb/log/mongod.log # log path
logAppend: true
storage:
dbPath: /mongodb/data # data directory
engine: wiredTiger#存储引擎
journal: #是否启用journal日志
enabled: true
net:
bindIp: 0.0.0.0
port: 27017 # port
processManagement:
fork: true 注意:肯定要yaml格式:
mongod -f /mongodb/conf/mongo.conf 2.2 关闭MongoDB 服务
mongod --port=27017 --dbpath=/mongodb/data --shutdown 关闭:方式一
https://i-blog.csdnimg.cn/direct/e7ddab7419db4321b00fecb8eeaf0ad4.png
关闭方式二: 进入mongosh
use admin
# 关闭MongoDB server 服务
db.shutdownServer() 2.3 mongosh使用
mongosh是MongoDB的交互式JavaScript Shell界面,它为体系管理员提供了强大的界面,并为开发职员提供了直接测试数据库查询和操作的方法。
注意:MongoDB 6.0 移除了mongo,使用mongosh
mongosh下载地点:MongoDB Shell Download | MongoDB
#centos7 安装mongosh
wget https://downloads.mongodb.com/compass/mongodb-mongosh-1.8.0.x86_64.rpm
yum install -y mongodb-mongosh-1.8.0.x86_64.rpm
# 连接mongodb server端
mongosh --host=192.168.65.206 --port=27017
mongosh 192.168.65.206:27017
# 指定uri方式连接
mongosh mongodb://192.168.65.206:27017/test --port:指定端口,默以为27017
--host:连接的主机地点,默认127.0.0.1
https://i-blog.csdnimg.cn/direct/29e3c7ce0e454dd7ba06bf06d785545c.png
2.4 mongosh常用下令
下令
说明
show dbs | show databases
表现数据库列表
use 数据库名
切换数据库,假如不存在创建数据库
db.dropDatabase()
删除数据库
show collections | show tables
表现当前数据库的聚集列表
db.聚集名.stats()
检察聚集详情
db.聚集名.drop()
删除聚集
show users
表现当前数据库的用户列表
show roles
表现当前数据库的角色列表
show profile
表现最近发生的操作
load("xxx.js")
执行一个JavaScript脚本文件
exit | quit
退出当前shell
help
检察mongodb支持哪些下令
db.help()
查询当前数据库支持的方法
db.聚集名.help()
表现聚集的帮助信息
db.version()
检察数据库版本
数据库操作;
#查看所有库
show dbs
# 切换到指定数据库,不存在则创建
use test
# 删除当前数据库
db.dropDatabase() 聚集操作:
#查看集合
show collections
#创建集合
db.createCollection("emp")
#删除集合
db.emp.drop() 创建聚集语法:
db.createCollection(name, options) options参数:
字段
类型
描述
capped
布尔
(可选)假如为true,则创建固定聚集。固定聚集是指有着固定巨细的聚集,当到达最大值时,它会主动覆盖最早的文档。
size
数值
(可选)为固定聚集指定一个最大值(以字节计)。
假如 capped 为 true,也需要指定该字段。
max
数值
(可选)指定固定聚集中包含文档的最大数量。
三、MongoDB文档操作
SQL to MongoDB Mapping Chart :SQL to MongoDB Mapping Chart - MongoDB Manual v8.0
3.1 插入文档
MongoDB提供了以下方法将文档插入到聚集中:
[*]db.collection.insertOne ():将单个文档插入到聚集中。
[*]db.collection.insertMany ():将多个文档插入到聚集中。
3.1.1 新增单个文档
[*]insertOne: 用于向聚集中插入一条文档数据,支持writeConcern。语法如下:
db.collection.insertOne(
<document>,
{
writeConcern: <document>
}
)
db.emps.insertOne(
{ name: "fox", age: 35},
{
writeConcern: { w: "majority", j: true, wtimeout: 5000 }
}
) https://i-blog.csdnimg.cn/direct/c10ba907042d43fc92d7d9d07d2fddb3.png
writeConcern 是 MongoDB 中用来控制写入确认的选项。以下是 writeConcern 参数的一些常见选项:
[*]w:指定写入确认级别。假如指定为数字,则表示要等候写入操作完成的节点数。假如指定为 majority,则表示等候大多数节点完成写入操作。默以为 1,表示等候写入操作完成的节点数为 1。
[*]j:表示写入操作是否要求长期化到磁盘。假如设置为 true,则表示写入操作必须长期化到磁盘后才返回乐成。假如设置为 false,则表示写入操作可能在数据被长期化到磁盘之前返回乐成。默以为 false。
[*]wtimeout:表示等候写入操作完成的超时时间,单位为毫秒。假如凌驾指定的时间仍然没有返回确认信息,则返回错误。默以为 0,表示不设置超时时间。
3.1.2 批量新增文档
[*]insertMany:向指定聚集中插入多条文档数据
db.collection.insertMany(
[ <document 1> , <document 2>, ... ],
{
writeConcern: <document>,
ordered: <boolean>
}
)
[*]writeConcern:写入确认选项,可选。
[*]ordered:指定是否按顺序写入,默认 true,按顺序写入。
3.2 查询文档
查询聚集中的多少文档,语法格式如下:
db.collection.find(query, projection)
[*]query :可选,使用查询操作符指定查询条件
[*]projection :可选,使用投影操作符指定返回的键。查询时返回文档中全部键值, 只需省略该参数即可(默认省略)。投影时,_id为1的时间,其他字段必须是1;_id是0的时间,其他字段可以是0;假如没有_id字段约束,多个其他字段必须同为0或同为1。 https://i-blog.csdnimg.cn/direct/096929132c874f04b620cc69ab8e84e2.png
假如查询返回的条目数量较多,mongosh则会主动实现分批表现。默认情况下每次只表现20条,可以输入it下令读取下一批。
3.2.1 查询聚集中的第一个文档
语法格式如下:
db.collection.findOne(query, projection) https://i-blog.csdnimg.cn/direct/4c5d5ea502594c33a06d0f5709157ea1.png
假如你需要以易读的方式来读取数据,可以使用pretty)方法,语法格式如下:
db.collection.find().pretty() 3.2.2 条件查询
查询条件对照表:
SQL
MQL
a = 1
{a: 1}
a <> 1
{a: {$ne: 1}}
a > 1
{a: {$gt: 1}}
a >= 1
{a: {$gte: 1}}
a < 1
{a: {$lt: 1}}
a
{a: {$lte: 1}}
查询逻辑对照表:
SQL
MQL
a = 1 AND b = 1
{a: 1, b: 1}或{$and: [{a: 1}, {b: 1}]}
a = 1 OR b = 1
{$or: [{a: 1}, {b: 1}]}
a IS NULL
{a: {$exists: false}}
a IN (1, 2, 3)
{a: {$in: }}
查询逻辑运算符:
[*]$lt: 存在并小于
[*]$lte: 存在并小于即是
[*]$gt: 存在并大于
[*]$gte: 存在并大于即是
[*]$ne: 不存在或存在但不即是
[*]$in: 存在并在指定数组中
[*]$nin: 不存在或不在指定数组中
[*]$or: 匹配两个或多个条件中的一个
[*]$and: 匹配全部条件
#查询带有nosql标签的book文档:
db.books.find({tag:"nosql"})
#按照id查询单个book文档:
db.books.find({_id:ObjectId("61caa09ee0782536660494d9")})
#查询分类为“travel”、收藏数超过60个的book文档:
db.books.find({type:"travel",favCount:{$gt:60}})3.3 更新文档
MongoDB提供了以下方法来更新聚集中的文档:
[*]db.collection.updateOne ():纵然多个文档可能与指定的筛选器匹配,也只会更新第一个匹配的文档。
[*]db.collection.updateMany ():更新与指定筛选器匹配的全部文档。
更新操作符:
操作符
格式
描述
$set
{$set:{field:value}}
指定一个键并更新值,若键不存在则创建
$unset
{$unset : {field : 1 }}
删除一个键
$inc
{$inc : {field : value } }
对数值类型进行增减
$rename
{$rename : {old_field_name : new_field_name } }
修改字段名称
$push
{ $push : {field : value } }
将数值追加到数组中,若数组不存在则会进行初始化
$pushAll
{$pushAll : {field : value_array }}
追加多个值到一个数组字段内
$pull
{$pull : {field : _value } }
从数组中删除指定的元素
$addToSet
{$addToSet : {field : value } }
添加元素到数组中,具有排重功能
$pop
{$pop : {field : 1 }}
删除数组的第一个或最后一个元素
3.4 删除文档
官方保举使用 deleteOne() 和 deleteMany() 方法删除文档,语法格式如下:
db.books.deleteOne ({ type:"novel" })//删除 type等于novel 的一个文档
db.books.deleteMany ({})//删除集合下全部文档
db.books.deleteMany ({ type:"novel" })//删除 type等于 novel 的全部文档
注意:remove、deleteMany下令需要对查询范围内的文档逐个删除,假如渴望删除整个聚集,则使用drop下令会更加高效
四、MongoDB数据类型详解
4.1 BSON协议与数据类型
JSON是当今非常通用的一种跨语言Web数据交互格式,属于ECMAScript标准规范的一个子集。JSON(JavaScript Object Notation, JS对象简谱)即JavaScript对象表示法,它是JavaScript对象的一种文本表现形式。
JSON是当今非常通用的一种跨语言Web数据交互格式,属于ECMAScript标准规范的一个子集。JSON(JavaScript Object Notation, JS对象简谱)即JavaScript对象表示法,它是JavaScript对象的一种文本表现形式。
JSON只定义了6种数据类型:
[*]string: 字符串
[*]number : 数值
[*]object: JS的对象形式,用{key:value}表示,可嵌套
[*]array: 数组,JS的表示方式,可嵌套
[*]true/false: 布尔类型
[*]null: 空值
大多数情况下,使用JSON作为数据交互格式已经是理想的选择,但是JSON基于文本的解析服从并不是最好的,在某些场景下往往会考虑选择更符合的编/解码格式,一些做法如:
[*]在微服务架构中,使用gRPC(基于Google的Protobuf)可以获得更好的网络使用率。
[*]分布式中心件、数据库,使用私有定制的TCP数据包格式来提供高性能、低延时的计算本领。
BSON由10gen团队计划并开源,现在主要用于MongoDB数据库。BSON(Binary JSON)是二进制版本的JSON,其在性能方面有更优的表现。BSON在很多方面和JSON保持一致,其同样也支持内嵌的文档对象和数组结构。二者最大的区别在于JSON是基于文本的,而BSON则是二进制(字节省)编/解码的形式。在空间的使用上,BSON相比JSON并没有显着的上风。
MongoDB在文档存储、下令协议上都采用了BSON作为编/解码格式,主要具有如下上风:
[*]类JSON的轻量级语义,支持简朴清晰的嵌套、数组层次结构,可以实现模式灵活的文档结构。
[*]更高效的遍历,BSON在编码时会记载每个元素的长度,可以直接通过seek操作进行元素的内容读取,相对JSON解析来说,遍历速度更快。
[*]更丰富的数据类型,除了JSON的根本数据类型,BSON还提供了MongoDB所需的一些扩展类型,比如日期、二进制数据等,这更加方便数据的表示和操作。
4.2 BSON的数据类型
MongoDB中,一个BSON文档最大巨细为16M,文档嵌套的级别不凌驾100:BSON Types - MongoDB Manual v6.0
Type
Number
Alias
Notes
Double
1
"double"
String
2
"string"
Object
3
"object"
Array
4
"array"
Binary data
5
"binData"
二进制数据
Undefined
6
"undefined"
Deprecated.
ObjectId
7
"objectId"
对象ID,用于创建文档ID
Boolean
8
"bool"
Date
9
"date"
Null
10
"null"
Regular Expression
11
"regex"
正则表达式
DBPointer
12
"dbPointer"
Deprecated.
JavaScript
13
"javascript"
Symbol
14
"symbol"
Deprecated.
JavaScript code with scope
15
"javascriptWithScope"
Deprecated in MongoDB 4.4.
32-bit integer
16
"int"
Timestamp
17
"timestamp"
64-bit integer
18
"long"
Decimal128
19
"decimal"
New in version 3.4.
Min key
-1
"minKey"
表示一个最小值
Max key
127
"maxKey"
表示一个最大值
4.3 ObjectId天生器
MongoDB聚集中全部的文档都有一个唯一的_id字段,作为聚集的主键。在默认情况下,_id字段使用ObjectId类型,采用16进制编码形式,共12个字节。
为了避免文档的_id字段出现重复,ObjectId被定义为3个部门:
[*]4字节表示Unix时间戳(秒)。
[*]5字节表示随机数(机器号+进程号唯一)。
[*]3字节表示计数器(初始化时随机)。
大多数客户端驱动都会自行天生这个字段,比如MongoDB Java Driver会根据插入的文档是否包含_id字段来主动补充ObjectId对象。这样做不光提高了离散性,还可以低落MongoDB服务器端的计算压力。在ObjectId的构成中,5字节的随机数并没有明确定义,客户端可以采用机器号、进程号来实现:
https://i-blog.csdnimg.cn/direct/8da0367802ca4619b5fb0ef73a5287a1.png
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]