分布式专题(4)之MongoDB快速实战与根本原理

打印 上一主题 下一主题

主题 1002|帖子 1002|积分 3006

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
一、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数据库排名首位。从诞生以来,其项目应用广度、社区生动指数持续上升。

1.2 MongoDB vs 关系型数据库 

         MongoDB概念与关系型数据库(RDBMS)非常类似:

   

  • 数据库(database):最外层的概念,可以明白为逻辑上的名称空间,一个数据库包含多个不同名称的聚集。
  • 聚集(collection):相当于SQL中的表,一个聚集可以存放多个不同的文档。
  • 文档(document):一个文档相当于数据表中的一行,由多个不同的字段构成。
  • 字段(field):文档中的一个属性,等同于列(column)。
  • 索引(index):独立的检索式数据结构,与SQL概念一致。
  • _id:每个文档中都拥有一个唯一的_id字段,相当于SQL中的主键(primary key)。
  • 视图(view):可以看作一种虚拟的(非真实存在的)聚集,与SQL中的视图类似。从MongoDB 3.4版本开始提供了视图功能,其通过聚合管道技术实现。
  • 聚合操作($lookup):MongoDB用于实现“类似”表连接(tablejoin)的聚合操作符。
  

        尽管这些概念大多与SQL标准定义类似,但MongoDB与传统RDBMS仍然存在不少差异,包括:
   

  • 半结构化,在一个聚集中,文档所拥有的字段并不需要是类似的,而且也不需要对所用的字段进行声明。因此,MongoDB具有很显着的半结构化特点。除了松散的表结构,文档还可以支持多级的嵌套、数组等灵活的数据类型,非常契合面向对象的编程模型。
  • 弱关系,MongoDB没有外键的约束,也没有非常强大的表连接本领。类似的功能需要使用聚合管道技术来弥补。
   1.3 MongoDB技术上风

        MongoDB基于灵活的JSON文档模型,非常适合敏捷式的快速开发。与此同时,其与生俱来的高可用、高水平扩展本领使得它在处置惩罚海量、高并发的数据应用时颇具上风。
   

  • JSON 结构和对象模型接近,开发代码量低
  • JSON的动态模型意味着更容易响应新的业务需求
  • 复制集提供99.999%高可用
  • 分片架构支持海量数据和无缝扩容
  

         简朴直观:从错综复杂的关系模型到一目了然的对象模型:

         快速:最简朴快速的开发方式

         灵活:快速响应业务变化

         原生的高可用:

         横向扩展本领

1.4 MongoDB应用场景

         从现在阿里云 MongoDB 云数据库上的用户看,MongoDB 的应用已经渗出到各个范畴:
   

  • 游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新;
  • 物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不绝更新,以MongoDB 内嵌数组的形式来存储,一次查询就能将订单全部的变更读取出来;
  • 社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能;
  • 物联网场景,使用 MongoDB 存储全部接入的智能设备信息,以及设备汇报的日记信息,并对这些信息进行多维度的分析;
  • 视频直播,使用 MongoDB 存储用户信息、礼品信息等;
  • 大数据应用,使用云数据库MongoDB作为大数据的云存储体系,随时进行数据提取分析,把握行业动态。|
          国内外着名互联网公司都在使用MongoDB:
  

  1.4.1  如何判定当前业务是否适合使用MongoDB

         没有某个业务场景必须要使用MongoDB才能解决,但使用MongoDB通常能让你以更低的成本解决问题。假如你不清楚当前业务是否适合使用MongoDB,可以通过做几道选择题来辅助决议。

        只要有一项需求满意就可以考虑使用MongoDB,匹配越多,选择MongoDB越符合。
二、MongoDB环境搭建 

2.1 linux安装MongoDB

        环境预备:
      

  • linux体系: centos7
  • 安装MongoDB社区版
   
  1. #如何查看linux版本
  2. [root@hadoop01 soft]# cat /etc/redhat-release
  3. CentOS Linux release 7.9.2009 (Core)
  4. #下载MongoDB
  5. wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-6.0.5.tgz
  6. tar -zxvf mongodb-linux-x86_64-rhel70-6.0.5.tgz
  7. #创建dbpath和logpath
  8. mkdir -p /mongodb/data /mongodb/log  
  9. #进入mongodb目录,启动mongodb服务
  10. bin/mongod --port=27017 --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log \
  11. --bind_ip=0.0.0.0 --fork
复制代码
  --dbpath :指定数据文件存放目录
  --logpath :指定日记文件,注意是指定文件不是目录
  --logappend :使用追加的方式记载日记
  --port:指定端口,默以为27017
  --bind_ip:默认只监听localhost网卡
  --fork: 后台启动
  --auth: 开启认证模式
  

         添加环境变量:修改/etc/profile,添加环境变量,方便执行MongoDB下令,然后执行source /etc/profile 重新加载环境变量
  1. export MONGODB_HOME=/usr/local/soft/mongodb
  2. PATH=$PATH:$MONGODB_HOME/bin  
复制代码
         使用配置文件启动服务:编辑/mongodb/conf/mongo.conf文件,内容如下:
  1. systemLog:
  2.   destination: file
  3.   path: /mongodb/log/mongod.log # log path
  4.   logAppend: true
  5. storage:
  6.   dbPath: /mongodb/data # data directory
  7.   engine: wiredTiger  #存储引擎
  8.   journal:            #是否启用journal日志
  9.     enabled: true
  10. net:
  11.   bindIp: 0.0.0.0
  12.   port: 27017 # port
  13. processManagement:
  14.   fork: true
复制代码
         注意:肯定要yaml格式:
  1. mongod -f /mongodb/conf/mongo.conf
复制代码
2.2 关闭MongoDB 服务 

  1. mongod --port=27017 --dbpath=/mongodb/data --shutdown
复制代码
        关闭:方式一 

        关闭方式二: 进入mongosh
  1. use admin
  2. # 关闭MongoDB server 服务
  3. db.shutdownServer()
复制代码
 2.3 mongosh使用

        mongosh是MongoDB的交互式JavaScript Shell界面,它为体系管理员提供了强大的界面,并为开发职员提供了直接测试数据库查询和操作的方法。
   注意:MongoDB 6.0 移除了mongo,使用mongosh
  mongosh下载地点:MongoDB Shell Download | MongoDB
  1. #centos7 安装mongosh
  2. wget https://downloads.mongodb.com/compass/mongodb-mongosh-1.8.0.x86_64.rpm
  3. yum install -y mongodb-mongosh-1.8.0.x86_64.rpm
  4. # 连接mongodb server端
  5. mongosh --host=192.168.65.206 --port=27017
  6. mongosh 192.168.65.206:27017
  7. # 指定uri方式连接
  8. mongosh mongodb://192.168.65.206:27017/test
复制代码
  --port:指定端口,默以为27017
  --host:连接的主机地点,默认127.0.0.1
  

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()
检察数据库版本
        数据库操作;
  1. #查看所有库
  2. show dbs
  3. # 切换到指定数据库,不存在则创建
  4. use test
  5. # 删除当前数据库  
  6. db.dropDatabase()
复制代码
        聚集操作:
  1. #查看集合
  2. show collections
  3. #创建集合
  4. db.createCollection("emp")
  5. #删除集合
  6. db.emp.drop()
复制代码
         创建聚集语法:
  1. 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。语法如下:
  1. db.collection.insertOne(
  2.    <document>,
  3.    {
  4.       writeConcern: <document>
  5.    }
  6. )
  7. db.emps.insertOne(
  8.    { name: "fox", age: 35},
  9.    {
  10.       writeConcern: { w: "majority", j: true, wtimeout: 5000 }
  11.    }
  12. )
复制代码
 

        writeConcern 是 MongoDB 中用来控制写入确认的选项。以下是 writeConcern 参数的一些常见选项:
   

  • w:指定写入确认级别。假如指定为数字,则表示要等候写入操作完成的节点数。假如指定为 majority,则表示等候大多数节点完成写入操作。默以为 1,表示等候写入操作完成的节点数为 1。
  • j:表示写入操作是否要求长期化到磁盘。假如设置为 true,则表示写入操作必须长期化到磁盘后才返回乐成。假如设置为 false,则表示写入操作可能在数据被长期化到磁盘之前返回乐成。默以为 false。
  • wtimeout:表示等候写入操作完成的超时时间,单位为毫秒。假如凌驾指定的时间仍然没有返回确认信息,则返回错误。默以为 0,表示不设置超时时间。
  3.1.2 批量新增文档 

   

  • insertMany:向指定聚集中插入多条文档数据
  1. db.collection.insertMany(
  2.    [ <document 1> , <document 2>, ... ],
  3.    {
  4.       writeConcern: <document>,
  5.       ordered: <boolean>      
  6.    }
  7. )
复制代码
  

  • writeConcern:写入确认选项,可选。
  • ordered:指定是否按顺序写入,默认 true,按顺序写入。
  3.2 查询文档

          查询聚集中的多少文档,语法格式如下:
  1. db.collection.find(query, projection)
复制代码
   

  • query :可选,使用查询操作符指定查询条件
  • projection :可选,使用投影操作符指定返回的键。查询时返回文档中全部键值, 只需省略该参数即可(默认省略)。投影时,_id为1的时间,其他字段必须是1;_id是0的时间,其他字段可以是0;假如没有_id字段约束,多个其他字段必须同为0或同为1。 

             假如查询返回的条目数量较多,mongosh则会主动实现分批表现。默认情况下每次只表现20条,可以输入it下令读取下一批。
3.2.1 查询聚集中的第一个文档

         语法格式如下:
  1. db.collection.findOne(query, projection)
复制代码

        假如你需要以易读的方式来读取数据,可以使用pretty)方法,语法格式如下: 
  1. 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: [1, 2, 3]}}
         查询逻辑运算符:
   

  • $lt: 存在并小于
  • $lte: 存在并小于即是
  • $gt: 存在并大于
  • $gte: 存在并大于即是
  • $ne: 不存在或存在但不即是
  • $in: 存在并在指定数组中
  • $nin: 不存在或不在指定数组中
  • $or: 匹配两个或多个条件中的一个
  • $and: 匹配全部条件
  1. #查询带有nosql标签的book文档:
  2. db.books.find({tag:"nosql"})
  3. #按照id查询单个book文档:
  4. db.books.find({_id:ObjectId("61caa09ee0782536660494d9")})
  5. #查询分类为“travel”、收藏数超过60个的book文档:
  6. 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() 方法删除文档,语法格式如下:
  1. db.books.deleteOne ({ type:"novel" })  //删除 type等于novel 的一个文档
  2. db.books.deleteMany ({})  //删除集合下全部文档
  3. 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的表示方式[value],可嵌套
  • 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字节的随机数并没有明确定义,客户端可以采用机器号、进程号来实现:

  


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊落一身雪

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表