MongoDB入门概念

1. 简介

MongoDB 是一款流行的开源文档型数据库,从它的命名来看,确实是有一定野心的。
MongoDB 的原名一开始来自于 英文单词"Humongous", 中文含义是指"庞大",即命名者的意图是可以处理大规模的数据。

但笔者更喜欢称呼它为 "芒果"数据库,除了译音更加相近之外,原因还来自于这几年使用 MongoDB 的两层感觉:

  • 第一层感受是"爽",使用这个文档数据库的特点是几乎不受什么限制,一方面Json文档式的结构更容易理解,而无Schema约束也让DDL管理更加简单,一切都可以很快速的进行。
  • 第二层感受是"酸爽",这点相信干运维或是支撑性工作的兄弟感受会比较深刻,MongoDB 由于入门体验"太过于友好",导致一些团队认为用好这个数据库是个很简单的事情,所以开发兄弟在存量系统上埋一些坑也是正常的事情。所谓交付一时爽,维护火葬场.. 当然了,这句话可能有些过。 但这里的潜台词是:与传统的RDBMS数据库一样,MongoDB 在使用上也需要认真的考量和看护,不然的化,会遇到更多的坑。

MongoDB 数据库的一些特性:

  • 面向文档存储,基于JSON/BSON 可表示灵活的数据结构
  • 动态 DDL能力,没有强Schema约束,支持快速迭代
  • 高性能计算,提供基于内存的快速数据查询
  • 容易扩展,利用数据分片可以支持海量数据存储
  • 丰富的功能集,支持二级索引、强大的聚合管道功能,为开发者量身定做的功能,如数据自动老化、固定集合等等。
  • 跨平台版本、支持多语言SDK

假定你是初次了解 MongoDB,下面的内容将能帮助你对该数据库技术的全貌产生一定的了解。

2. 基本模型

数据结构对于一个软件来说是至关重要的,MongoDB 在概念模型上参考了 SQL数据库,但并非完全相同。

如下表所示:

SQL概念MongoDB概念
databasedatabase
tablecollection
rowdocument
columnfield
  • database 数据库,与SQL的数据库(database)概念相同,一个数据库包含多个集合(表)
  • collection 集合,相当于SQL中的表(table),一个集合可以存放多个文档(行)。 不同之处就在于集合的结构(schema)是动态的,不需要预先声明一个严格的表结构。更重要的是,默认情况下 MongoDB 并不会对写入的数据做任何schema的校验。
  • document 文档,相当于SQL中的行(row),一个文档由多个字段(列)组成,并采用bson(json)格式表示。
  • field 字段,相当于SQL中的列(column),相比普通column的差别在于field的类型可以更加灵活,比如支持嵌套的文档、数组。此外,MongoDB中字段的类型是固定的、区分大小写、并且文档中的字段也是有序的。

另外,SQL 还有一些其他的概念,对应关系如下:

SQL概念    MongoDB概念
primary key _id
foreign keyreference
view    view    
index    index    
join    $lookup
transaction    transaction    
group by aggregation

 

 

 

 

 

 

 

 

  • _id 主键,MongoDB 默认使用一个_id 字段来保证文档的唯一性。
  • reference 引用,勉强可以对应于 外键(foreign key) 的概念,之所以是勉强是因为 reference 并没有实现任何外键的约束,而只是由客户端(driver)自动进行关联查询、转换的一个特殊类型。
  • view 视图,MongoDB 3.4 开始支持视图,和 SQL 的视图没有什么差异,视图是基于表/集合之上进行动态查询的一层对象,可以是虚拟的,也可以是物理的(物化视图)。
  • index 索引,与SQL 的索引相同。
  • $lookup,这是一个聚合操作符,可以用于实现类似 SQL-join 连接的功能
  • transaction 事务,从 MongoDB 4.0 版本开始,提供了对于事务的支持
  • aggregation 聚合,MongoDB 提供了强大的聚合计算框架,group by 是其中的一类聚合操作。

2.1 BSON数据类型

MongoDB 文档可以使用 Javascript 对象表示,从格式上讲,是基于 JSON 的。一个典型的文档如下:

{
  "_id": 1,
  "name" : { "first" : "John", "last" : "Backus" },
  "contribs" : [ "Fortran", "ALGOL", "Backus-Naur Form", "FP" ],
  "awards" : [
    {
      "award" : "W.W. McDowell Award",
      "year" : 1967,
      "by" : "IEEE Computer Society"
    }, {
      "award" : "Draper Prize",
      "year" : 1993,
      "by" : "National Academy of Engineering"
    }
  ]
}

曾经,JSON 的出现及流行让 Web 2.0 的数据传输变得非常简单,所以使用 JSON 语法是非常容易让开发者接受的。
但是 JSON 也有自己的短板,比如无法支持像日期这样的特定数据类型,因此 MongoDB 实际上使用的是一种扩展式的JSON,叫 BSON(Binary JSON)。

BSON 所支持的数据类型包括:

2.2 分布式ID

在单机时代,大多数应用可以使用数据库自增式ID 来作为主键。 传统的 RDBMS 也都支持这种方式,比如 mysql 可以通过声明 auto_increment来实现自增的主键。 但一旦数据实现了分布式存储,这种方式就不再适用了,原因就在于无法保证多个节点上的主键不出现重复。

为了实现分布式数据ID的唯一性保证,应用开发者提出了自己的方案,而大多数方案中都会将ID分段生成,如著名的 snowflake 算法中就同时使用了时间戳、机器号、进程号以及随机数来保证唯一性。

MongoDB 采用 ObjectId 来表示主键的类型,数据库中每个文档都拥有一个_id 字段表示主键。_id 的生成规则如下:

其中包括:

  • 4-byte Unix 时间戳
  • 3-byte 机器 ID
  • 2-byte 进程 ID
  • 3-byte 计数器(初始化随机)

值得一提的是 _id 的生成实质上是由客户端(Driver)生成的,这样可以获得更好的随机性,同时降低服务端的负载。当然服务端也会检测写入的文档是否包含_id 字段,如果没有就生成一个。

3. 操作语法

除了文档模型本身,对于数据的操作命令也是基于JSON/BSON 格式的语法。

比如插入文档的操作:

db.book.insert(
{
  title: "My first blog post",
  published: new Date(),
  tags: [ "NoSQL", "MongoDB" ],
  type: "Work",
  author : "James",
  viewCount: 25,
  commentCount: 2
}
)

执行文档查找:

db.book.find({author : "James"})

更新文档的命令:

db.book.update(
   {"_id" : ObjectId("5c61301c15338f68639e6802")},
   {"$inc": {"viewCount": 3} }
)

删除文档的命令:

db.book.remove({"_id":
     ObjectId("5c612b2f15338f68639e67d5")})

在传统的SQL语法中,可以限定返回的字段,MongoDB可以使用Projection来表示:

db.book.find({"author": "James"}, 
    {"_id": 1, "title": 1, "author": 1})

实现简单的分页查询:

db.book.find({})
    .sort({"viewCount" : -1})
    .skip(10).limit(5)

这种基于BSON/JSON 的语法格式并不复杂,它的表达能力或许要比SQL更加强大。与 MongoDB 做法类似的还有 ElasticSearch,后者是搜索数据库的佼佼者。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值