为啥MongoDB适合大数据的存储

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥MongoDB适合大数据的存储相关的知识,希望对你有一定的参考价值。

Mongo是一个高性能,开源,无模式的文档型数据库,它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。Mongo使用C++开发,提供了以下功能:
◆面向集合的存储:适合存储对象及JSON形式的数据。
◆动态查询:Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
◆完整的索引支持:包括文档内嵌对象及数组。Mongo的查询优化器会分析查询表达式,并生成一个高效的查询计划。
◆查询监视:Mongo包含一个监视工具用于分析数据库操作的性能。
◆复制及自动故障转移:Mongo数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。
◆高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)。
◆自动分片以支持云级别的伸缩性(处于早期alpha阶段):自动分片功能支持水平的数据库集群,可动态添加额外的机器。
MongoDB的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统(丰富的功能)架起一座桥梁,集两者的优势于一身。根据官方网站的描述,Mongo适合用于以下场景:
◆网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
◆缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源过载。
◆大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
◆高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路线图中已经包含对MapReduce引擎的内置支持。
◆用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储及查询。
自然,MongoDB的使用也会有一些限制,例如它不适合:
◆高度事务性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
◆传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
◆需要SQL的问题
MongoDB支持OS X、Linux及Windows等操作系统,并提供了Python,php,Ruby,Java及C++语言的驱动程序,社区中也提供了对Erlang及.NET等平台的驱动程序。
参考技术A Mongo是一个高性能,开源,无模式的文档型数据库,它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。Mongo使用C++开发,提供了以下功能:
◆面向集合的存储:适合存储对象及JSON形式的数据。
◆动态查询:Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
◆完整的索引支持:包括文档内嵌对象及数组。Mongo的查询优化器会分析查询表达式,并生成一个高效的查询计划。
◆查询监视:Mongo包含一个监视工具用于分析数据库操作的性能。
◆复制及自动故障转移:Mongo数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。
◆高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)。
◆自动分片以支持云级别的伸缩性(处于早期alpha阶段):自动分片功能支持水平的数据库集群,可动态添加额外的机器。
MongoDB的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统(丰富的功能)架起一座桥梁,集两者的优势于一身。根据官方网站的描述,Mongo适合用于以下场景:
◆网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
◆缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源过载。
◆大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
◆高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路线图中已经包含对MapReduce引擎的内置支持。
◆用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储及查询。
自然,MongoDB的使用也会有一些限制,例如它不适合:
◆高度事务性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
◆传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
◆需要SQL的问题
MongoDB支持OS X、Linux及Windows等操作系统,并提供了Python,PHP,Ruby,Java及C++语言的驱动程序,社区中也提供了对Erlang及.NET等平台的驱动程序。
参考技术B Mongo是一个高性能,开源,无模式的文档型数据库,它在许多场景下可用于替代传统的关系型数据库或键/值存储方式。Mongo使用C++开发,提供了以下功能:
◆面向集合的存储:适合存储对象及JSON形式的数据。
◆动态查询:Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。
◆完整的索引支持:包括文档内嵌对象及数组。Mongo的查询优化器会分析查询表达式,并生成一个高效的查询计划。
◆查询监视:Mongo包含一个监视工具用于分析数据库操作的性能。
◆复制及自动故障转移:Mongo数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目标是提供冗余及自动故障转移。
◆高效的传统存储方式:支持二进制数据及大型对象(如照片或图片)。
◆自动分片以支持云级别的伸缩性(处于早期alpha阶段):自动分片功能支持水平的数据库集群,可动态添加额外的机器。
MongoDB的主要目标是在键/值存储方式(提供了高性能和高度伸缩性)以及传统的RDBMS系统(丰富的功能)架起一座桥梁,集两者的优势于一身。根据官方网站的描述,Mongo适合用于以下场景:
◆网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
◆缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源过载。
◆大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
◆高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。Mongo的路线图中已经包含对MapReduce引擎的内置支持。
◆用于对象及JSON数据的存储:Mongo的BSON数据格式非常适合文档化格式的存储及查询。
自然,MongoDB的使用也会有一些限制,例如它不适合:
◆高度事务性的系统:例如银行或会计系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
◆传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。
◆需要SQL的问题
MongoDB支持OS X、Linux及Windows等操作系统,并提供了Python,PHP,Ruby,Java及C++语言的驱动程序,社区中也提供了对Erlang及.NET等平台的驱动程序。

MongoDB 数据模型

MongoDB数据库介绍

  • 特点

    • 面向集合存储
    • 丰富的查询语句
    • 复制集机制
    • 支持文件存储
    • 模式自由
    • 多级索引
    • 易水平扩展
    • 跨平台、支持语言众多
    • 可插入式存储引擎(3.0)
  • 适用场景

    • 数据缓存
    • JSON格式的数据
    • 局伸如性场景
    • 弱事务类型业务

    MongoDB更多适合于大数据量、高并发、弱事务的互联网应用,其内置的水平扩展 机制提供了从几百万到十亿级别的数据处理能力,可以很好的满足Web2.0和移动互联网应 用的数据存储要求。

MongoDB的相关网站

官方文档:https://docs.mongodb.com/tutorials/

中文网站:http://www.mongoing.com/

谷歌Group:https://groups.google.com/forum/

MongoDB概念解析

SQL术语/概念 MongoDB术语/概念 解释/说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins embedded documents/reference 表连接/(内嵌/引用)
primary key primary key 主键,MongoDB自动将_id字段设置为主键

通过下图实例,可以更直观的的了解Mongo中的一些概念:

技术分享图片


数据库

多个文档组成集合,而多个集合组成了数据库。一个MongoDB实例可以 承载多个数据库,每个数据库都有独立的权限,在磁盘上,不同的数据库也 可放置在不同的文件夹中(启动时加directoryperdb选项)。

为了更好的组织数据,一般情况下,会把属于同一个应用程序(或同一种 业务类型)的所有数据放到一个数据库中。

show dbs 命令可以显示所有数据的列表。

? at [09/10/17][0:21:00] 
? ?  mongo
MongoDB shell version: 3.2.11
connecting to: test
> exit
bye
? at [09/10/17][0:21:04] 
? ?  mongo
MongoDB shell version: 3.2.11
connecting to: test
> show dbs
local  0.000GB

执行 "db" 命令可以显示当前数据库对象或集合。

> db
test

运行use db_name命令,切换数据库,没有数据库时自动创建

> use local
switched to db local
> db
local
> 

以上实例命令中,local 是你要链接的数据库。

在下一个章节我们将详细讲解MongoDB中命令的使用。

数据库也通过名字来标识。数据库名可以是满足以下条件的任意UTF-8字符串。

  • 不能是空字符串("")。
  • 不得含有‘ ‘(空格)、.、$、/、\\和\\0 (空字符)。
  • 数据库名字区分大小写(建议数据库名全部使用小写)
  • 最多64字节。
  • 不要与系统保留的数据库名字相同,这些数据库包括:admin、local、 config等

有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。

  • admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
  • local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
  • config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。

相关操作

命令 操作
db 查看当前数据库
show dbs 查看当前端口有多少数据库
use db_name 切换数据库,没有数据库时自动创建
db.dropDatabase() 删除数据库

文档

文档是MongoDB最核心的概念,本质上是一种类JSON的BSON格式的数据。
BSON是一种类JSON的二进制格式数据,它可以理解为在JSON基础上添加了 _些新的数据类型,包括曰期、int32、int64等。
BSON是由一组组键值对组成,它具有轻量性、可遍 历性和高效性三个特征。可遍历性是MongoDB将BSON 作为数据存储的主要原因。
BSON官网地址:http://bsonspec.org/

{
    fieldl:valuel,
    field2:value2,
    field3:value3,
    ...
    fieldN:valuen
}

下表列出了 RDBMSMongoDB 对应的术语:

RDBMS MongoDB
数据库 数据库
表格 集合
文档
字段
表联合 嵌入文档
主键 主键 (MongoDB 提供了 key 为 _id )
数据库服务 客户端
Mysqld/Oracle mysql/sqlplus
mongod mongo

需要注意的是:

  1. 文档中的键/值对是有序的。MongoDB会尽量保持文档被插入时键值对的顺序
  2. 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
  3. MongoDB区分类型和大小写。
  4. MongoDB的文档不能有重复的键。
  5. 文档的键是字符串。除了少数例外情况,键可以使用任意UTF-8字符。
  6. MongoDB中写操作的原子性限制在文档级别,对文档的保存、修改、删除 等都是原子操作
  7. 单个文档占用的存储空间不能超过16MB

关于文档键的命名需要注意以下几点:

  • _id是系统保留的关键字,它是默认的主键,该值在集合中必须唯一,且不可更改
  • .(命名空间)和$(操作符)有特别的意义,只有在特定环境下才能使用。
  • 以下划线"_"开头的键是保留的(不是严格要求的)。
  • 键不能包含\\0或空字符,这个字符用于表示键的结尾
  • 键是区分大小写的且不能重复例如:{foo:l,Foo:l}

内嵌文档

文档可以作为键的值,这样的文档称为内嵌文档。内嵌文档可以使数据不用保存成扁平结构的键值对,从而使数据组织方式更加自然。

例如:下面是一个与博客管理有关的文档

{
    _id: <Objectldl>, 
    title: MongoDBDateModeln, 
    author: foo, 
    comments:[
    {who:"John",comment:"Good"} 
    {who:"Joe",comment:"ExceUent"}
    ]
}

上面的文档可以进行如下的拆分:

技术分享图片

即拆分成引用文档.

内嵌文档特点

  • 子文档比较少时,可以保证原子性,同时具备高速查询;
  • 子文档比较多时,会影响查询和更新速度,同时也带来数据冗余

集合

把一组相关的文档放到一起组成了集合,如果将MongoDB的一个文档比喻 为关系型数据库中的一行,那么一个集合就相当于一张表。

MongoDB的集合是模式自由的,一个集合里面的文档可以是各式各样。

例如:下面的两个文档可以出现了同一个集合中。

{"x":1}
{"x":1,"y":2}
{"x":1,"y":2,"z":5}

当第一个文档插入时,集合就会被创建。

MongoDB提供了一些特殊功能的集合,例如:cappedcollection、 system.indexes、system.namespaces 等。

合法的集合名

  • 集合名不能是空字符串""。
  • 集合名不能含有\\0字符(空字符),这个字符表示集合名的结尾。
  • 集合名不能以system.开头,这是为系统集合保留的前缀。
  • 用户创建的集合名字不能含有保留字符。有些驱动程序的确支持在集合名里面包含,这是因为某些系统生成的集合中包含该字符。除非你要访问这种系统创建的集合,否则千万不要在名字里出现$(注:可包含.) 

如下实例:

db.col.findOne()

capped collections

Capped collections 就是固定大小的collection。

它有很高的性能以及队列过期的特性(过期按照插入的顺序). 有点和 "RRD" 概念类似。

Capped collections是高性能自动的维护对象的插入顺序。它非常适合类似记录日志的功能 和标准的collection不同,你必须要显式的创建一个capped collection, 指定一个collection的大小,单位是字节。collection的数据存储空间值提前分配的。

要注意的是指定的存储大小包含了数据库的头信息。

db.createCollection("mycoll", {capped:true, size:100000})
  • 在capped collection中,你能添加新的对象。
  • 能进行更新,然而,对象不会增加存储空间。如果增加,更新就会失败 。
  • 数据库不允许进行删除。使用drop()方法删除collection所有的行。
  • 注意: 删除之后,你必须显式的重新创建这个collection。
  • 在32bit机器中,capped collection最大存储为1e9( 1X109)个字节。

命名空间

把数据库名添加到集合名字前面,中间用点号连接,得到集合的完全限定 名,就是命名空间,例如:命名空间parent.sub。

需要说明的是,点号还可以出现在集合名字中,例如:parent.subling0,parent.subling2可以将subling0和subling2集合看作是parent集合的子集合。
使用子集合可以使我们更好的组织数据,使数据的结构更加清晰明了。

元数据

数据库的信息是存储在集合中。它们使用了系统的命名空间:

dbname.system.*

在MongoDB数据库中名字空间<dbname>.system.*是包含多种系统信息的特殊集合(Collection),如下:

集合命名空间 描述
db.system.namespaces 列出所有名字空间。
db.system.indexes 列出所有索引。
db.system.profile 包含数据库概要(profile)信息。
db.system.users 列出所有可访问数据库的用户。
db.local.sources 包含复制对端(slave)的服务器信息和状态。

对于修改系统集合中的对象有如下限制。

{{system.indexes}}插入数据,可以创建索引。但除此之外该表信息是不可变的(特殊的drop index命令将自动更新相关信息)。

{{system.users}}是可修改的。 {{system.profile}}是可删除的。


MongoDB 数据类型

BSON可以理解为在JSON基础上添加了一些新的数据类型,包括Date,正贝IJ 表达式,对数值类型的更进一步划分等。

数据类型 类型编号 数据类型 类型编号
Double 1 Regular Expression 11
String 2 JavaScript 13
Object 3 Symbol 14
Array 4 JavaScript(Scope) 15
Binarydata 5 32-bit integer 16
Object id 7 Timestamp 17
Boolean 8 64-bit integer 18
Date 9 Min Key 255
Null 10 Max Key 127

可以使用类型编号进行条件查询如下:

db.collection.find({name:{$type:2}})

基本数据类型

  • null 表示空值或不存在的字段例如:db.collection.find({nyn:null})

    • 布尔有两个值true或false 例如:{"y":true}
  • 数值类型支持32-int、64-int以及64-double

    注:JavaScript只支持64位浮点数

    例如:

    • {"y":10} - double
    • {"y":Numberlnt(10)} - 32
    • {"y":NumberLong(10)} - 64
    7 Documents:0 > db.demo.insert({y:10})
    WriteResult({ "nInserted" : 1 })
    8 Documents:1 > db.demo.find({y:{$type:1}})
    { "_id" : ObjectId("5a7863305640374fb2cd5620"), "y" : 10 }
    9 Documents:1 > db.demo.insert({y:NumberInt(10)})
    WriteResult({ "nInserted" : 1 })
    10 Documents:2 > db.demo.find({y:{$type:16}})
    { "_id" : ObjectId("5a78636d5640374fb2cd5621"), "y" : 10 }
    11 Documents:2 > db.demo.insert({y:NumberLong(10)})
    WriteResult({ "nInserted" : 1 })
    12 Documents:3 > db.demo.find({y:{$type:18}})
    { "_id" : ObjectId("5a7863915640374fb2cd5622"), "y" : NumberLong(10) }
    • 字符串使用UTF-8对字符串进行编码例如:{"y":"HelloMongoDB"}
  • 二进制数据可以保存由任意字节组成的字符串,例如:图片、视频等

  • 正则表达式:主要用于查询,使用正则表达式作为限定条件

    例如:

    • {name:/foo/} name字段含有foo的文档
    • {name:/foo/i} name字段含有foo的文档,且不区分大小写
    • {name:/^foo/i} name字段以foo幵头,且不区分大小写
  • JavaScript代码:文档中可以包含任意的JavaScript代码

    例如:{"func":function(){}}

Date日期

  • MongoDB中,日期类型是一个64位的整数,它代表的是距Unixepoch的毫秒数
  • MongoDB在存储时间时,先转化为UTC时间
  • 北京时间(CST) = UTC + 8个小时
  • MongoDBShell中可以使用newDate或ISODate来创建时间对象,在进行显示时,Shell会根据本地时间去设置显示日期对象
14 Documents:3 > var mydate0 = new Date()
15 Documents:3 > var mydate9 = ISODate()
16 Documents:3 > mydate0
ISODate("2018-02-05T14:04:43.243Z")
17 Documents:3 > mydate9
ISODate("2018-02-05T14:04:57.715Z")
18 Documents:3 > mydate9.toString()
Mon Feb 05 2018 22:04:57 GMT+0800 (CST)

Timestamp

  • 时间戳类型有两部分组成:

技术分享图片

  • Timestmp只供MongoDB数据库服务内部使用,用于记录操作的详细时间
  • Timestamp类型和Date类型是没有关系的,对于我们来说使用更多的Date类型
  • 相关函数:Timestamp()

Objectld

Objectld由24个十六进制字符构成,每个字节存储两位十六进制数字,总共需 12字节存储空间

每个字节代表的含义如下:

技术分享图片

这种方式生成的Objectld在分布式仍然是唯一的.

相关函数

  • Objectld()

    用于取得Objectld

  • getTimestamp()

    用于取得Objectld的时间戳

  • valueOf()

    用于取得Objectld的字符串表示

19 Documents:3 > x = ObjectId()
ObjectId("5a7866e75640374fb2cd5623")
20 Documents:3 > x.getTimestamp()
ISODate("2018-02-05T14:15:03Z")
21 Documents:3 > x.valueOf()
5a7866e75640374fb2cd5623

数组

  • 数组是使用方括号来表示的一组值,它既可以作为有序对象(列表、栈、队 歹|J),也能作为无序对象(如集合)来操作

  • 数组中可以包含不同数据类型的元素(字符串、浮点数、文档等)

    例如:[3.14,"hello",[l2,3],{"key":"MongoDB"}]

    针对数组MongoDB提供了许多特定的操作符,例如:$push$pop$pull$slice$addToSet

  • MongoDB可自动的为数组元素建立Multikey索引

以上是关于为啥MongoDB适合大数据的存储的主要内容,如果未能解决你的问题,请参考以下文章

为啥有关MongoDB采用B树索引,以及Mysql B+树做索引

MongoDB

MongoDB 数据模型

mongodb

mongoDB适用啥场合呢?

Mongodb大数据语法大全