MongoDB

匿名 (未验证) 提交于 2019-12-03 00:18:01

MongoDB

MongoDB. 1

一、MongoDB概念... 2

二、数据模型设计介绍... 2

a)文档结构... 2

b)写操作的原子性... 4

c)文档的增长... 4

三、文档关系模型:... 5

a)内嵌文档模型... 5

b)一对多关系建模:内嵌文档模型... 5

c)一对多关系建模:文档引用模式... 5

四、Mongodb索引... 6

五、操作... 6

六、Mongodb组成... 7

七、与传统关系型数据库对比... 16

八、性能测试... 16


MongoDB概念

Mongodb本身只是一个新生数据库,具有比较高性能的读写,分布式扩展强,属于nosql方向,但是没有事务的特性,稳定性和维护性较传统关系数据库差;而传统的关系型数据库,开发周期长相对完善稳定成熟,更能进行简单的操作。所以Mongodb可以将一些海量的日志信息或者统计信息放到mongodb上面,为了能够更好更方便的查询,而且也不怕数据的丢失(现在这方面mongodb也改进了很多),而传统的关系型数据库则存放一些业务数据之类的,业务逻辑复杂的事务处理。

MongoDB存储所有的文档(关系型数据库里的行)在集合(关系型数据库里的表)里。集合是一组相关的文档,他们拥有一套共享的通用索引。

MongoDB 的数据模式是一种灵活模式。关系型数据库要求你在插入数据之前必须先定义好一个表的模式结构,而MongoDB的集合则并不限制文档结构。这种灵活性让对象和数据库文档之间的映射变得很容易。即使数据记录之间有很大的变化,每个文档也可以很好的映射到各条不同的记录。当然在实际使用中,同一个集合中的文档往往都有一个比较类似的结构。

数据模型设计中最具挑战性的是在应用程序需求,数据库引擎性能要求和数据读写模式之间做权衡考量。当设计数据模型的时候,一定要考虑应用程序对数据的使用模式(如查询,更新和处理)以及数据本身的天然结构。

设计基于MongoDB的应用程序的数据模型时的关键就是选择合适的文档结构以及确定应用程序如何描述数据之间的关系。有两种方式可以用来描述这些关系:引用及内嵌。

引用方式通过存储链接或者引用信息来实现两个不同文档之间的关联。应用程序可以通过解析这些数据库引用来访问相关数据。简单来讲,这就是规范化的数据模型。

内嵌方式指的是把相关联的数据保存在同一个文档结构之内。MongoDB的文档结构允许一个字段或者一个数组内的值为一个嵌套的文档。这种冗余的数据模型可以让应用程序在一个数据库操作内完成对相关数据的读取或修改。

写操作在MongoDB里在文档级具有原子性 - 意即单个写操作不能针对两个以上的文档或者集合同时操作。由于一个有内嵌文档的非规范化,冗余数据模型包含了所有相关的数据,这样一个写操作就可以完成对一个对象所有相关数据的一次性插入或者更新。如果使用规范化,无冗余数据模型,那么一个对象的数据要分到多个集合里面的多个文档里去。这样一来就需要多个写操作来完成。这多个写操作作为一个整体是不具由原子性的。

但是要指出的是,这种对原子性写操作利好的内嵌数据模型会限制应用程序对数据的使用场景。这篇文档关于原子性讨论了一些在模式设计时候 权衡数据模式的灵活性和原子性的要做的考量。

有一些文档的更新操作,例如在数组里增加元素或者增加一个新字段,导致文档的大小变大。如果文档的大小超出分配给文档的原空间大小,么MongoDB就需要把文档从磁盘上的现有位置移动到一个新的位置以存放更多的数据。这种数据增长的情况也会影响到是否要使用规范化或是非规范模式-内嵌。文章关于文档增长讲述了一些比较具体的管理文档增长问题的讨论。

{
_id: "joe",
name: "Joe Bookreader",
address:{
street: "123 Fake Street",
city: "Faketon",
state: "MA",
zip: "12345"
}
}

{
_id: "joe",
name: "Joe Bookreader",
addresses: [
{
street: "123 Fake Street",
city: "Faketon",
state: "MA",
zip: "12345"
},
{
street: "1 Some Other Street",
city: "Boston",
state: "MA",
zip: "12345"
}
]
 }

Mongodb索引

索引类型

索引属性

CreateIndex(new Document { {"UserId", 1 } }, true),这时候最后一个参数为“true”

增:

db.inventory.insert(
{
item: "ABC1",
details: {
model: "14Q3",
manufacturer: "XYZ Company"
},
stock: [{size: "S",qty: 25},{size: "M",qty: 50}],
category: "clothing"
}
)
删:
db.inventory.remove({})
:
db.inventory.update(
{ item: "MNO2" },
{
$set: {
category: "apparel",
details: { model: "14Q3", manufacturer: "XYZ Company" }
},
$currentDate: { lastModified: true }
}
)
db.inventory.find( { type: { $in: [ 'food', 'snacks' ] } } )

组成

启动服务器命令Mongdo

启动成功

连接命令Mongo

客户端连接成功

服务未启动,连接失败

安装windows作为服务

A、在D:\data\下创建mongod.cfg文件,内容如下

systemLog:

storage:

dbPath:d:\data\db

B、cmd安装服务

注意:cmd要管理员权限,所以必须以管理员启动

查看日志d:\data\log\mongod.log:

表示安装成功

如果不是管理员启动d:\data\log\mongod.log内容为:

C、start服务

cmd:net start MongoDB

D、stop服务

cmd:net stop MongoDB

E、删除服务

F、操作数据库

Cmd: mongo

2、切换/创建数据库

3、查询所有数据库

4、show collections:显示当前数据库中的集合(类似关系数据库中的表)

4、删除当前使用数据库

5、查看当前使用的数据库

6、显示当前db状态

7、当前db版本

8、查看当前db的链接机器地址

9、创建集合

在MongoDB中,不需要创建集合。当插入一些文件 MongoDB 自动创建的集合,当然也可以手动创建集合

db.createCollection(name, options)

Name

String

要创建的集合名称

Options

Document

(可选)指定有关内存大小和索引选项

Options类型为如下:

字段

类型

描述

capped

Boolean

(可选)如果为true,则启用封顶集合。封顶集合是固定大小的集合,会自动覆盖最早的条目,当它达到其最大大小。如果指定true,则需要也指定尺寸参数。

autoIndexID

Boolean

(可选)如果为true,自动创建索引_id字段的默认值是false

size

number

(可选)指定最大大小字节封顶集合。如果封顶如果是 true,那么你还需要指定这个字段。

max

number

(可选)指定封顶集合允许在文件的最大数量。

db.createCollection("order")

10、删除集合

12、添加数据db.collection.insertOne()

db.order.insertOne({"order_id":1679011615,"agent_order_no":"1287892801201606019147062223","vender_order_no":"","face_price":100000,"agent_id":880030,"created":"2016-06-0114:42:03"})

db.order.insert({"order_id":1679011612,"agent_order_no":"1287892801201606019147062221","vender_order_no":"112345","face_price":50000,"agent_id":880031,"created":"2016-06-0114:42:02"})

13、查询数据db.collection.find();

14、删除数据db.collection.remove({})

15、删除集合db. collection.drop()

db.order.drop()

配置服务器、(其实还有客户端aplication)

分片是存储了集群一部分数据mongod或者replica set.所有分片存储了集群的全部数据.通常来讲,每个分片都是一个复制集.复制集为每个分片的数据提供了冗余和高可靠性.MongoDB以每个集合(关系型数据库中表的意思)为单位使用分片,你必须通过mongos访问开启了分片的集合,如果直接连接到某个分片,你只能看到集合的部分数据.每个分片上的数据并没有特定的顺序.MongoDB并不保证两个连续的数据块会分布在同一个分片上。

配置服务器

集群配置服务器保存元数据的分片。元数据映射块碎片。MongoDB还使用配置服务器来管理分布式锁。配置服务器在config数据库中存储了集群的元信息,mongos缓存了这个数据库用来做读写的路由分发。对存在的数据块进行分裂。

mongosmongos开启分片集合的均衡获取更多分片间数据块均衡的细节。

数据块大小:MongoDB中默认的chunk大小是64M,你可以调整数据块的大小,但要注意到这有可能会集群造成性能影响。数据块大小较小时可以使得分片间的数据更均衡,但是是以频繁的迁移为代价的,会对mongos造成压力。数据块大小较大时会使得均衡较少,这从网络传输与mongos

集群的查询路由分发

mongos实例的读写应用程序路由到碎片,应用程序不能直接访问碎片,Router可多个。

集群的查询路由分发

mongos分片mongos配置服务器mongosmongosmongos持续mongosmongos

片键:

数据块

对于基于哈希的分片,MongoDB计算一个字段的哈希值,并用这个哈希值来创建数据块.

很可能不会

基于范围的分片方式提供了更高效的范围查询,给定一个片键的范围,分发路由可以很简单地确定哪个数据块存储了请求需要的数据,并将请求转发到相应的分片中。

不过,基于范围的分片会导致数据在不同分片上的不均衡,有时候,带来的消极作用会大于查询性能的积极作用。比如,如果片键所在的字段是线性增长的,一定时间内的所有请求都会落到某个固定的数据块中,最终导致分布在同一个分片中.在这种情况下,一小部分分片承载了集群大部分的数据,系统并不能很好地进行扩展。

与此相比,基于哈希的分片方式以范围查询性能的损失为代价,保证了集群中数据的均衡.哈希值的随机性使数据随机分布在每个数据块中,因此也随机分布在不同分片中。但是也正由于随机性,一个范围查询很难确定应该请求哪些分片,通常为了返回需要的结果,需要请求所有分片。


类型

MongoDB

传统关系性数据库(Mysql)

结构模型

无模式结构

要先定义好表结构

数据库模型

非关系型

关系型

存储方式

内存+持久化

InnoDB等各种引擎

构架模式

副本集+分布式分片高可用

主从、分区、分表等

处理数据方式

热数据(shard key,索引)存以Cache中从而达到高速读写

Cache、log、等相对复杂,各不同

成熟度

用户人群

骤增型

稳增型

优点

读写性能高、高扩展、主副集无差热备、无模式结构JSON集

缺点

维护工具,资源公享相对不全、无自带事务机制处理复杂业务逻辑较为复杂

MongoDB与传统关系性数据库对比表格

测试环境:

window10_64bit、mongodb3.2.6、cpu IntelG2030@3.00GHZ、RAM4GB(3.83GB可用)、JUnit、mongodb驱动2.12.3

Pom.xml加入mongodb驱动包2.12.3版

<dependency>

MongoDBTest.java如下

packagecom.mongodb;

importjava.net.UnknownHostException;

importjava.util.ArrayList;

importjava.util.Date;

importjava.util.List;

importjunit.framework.TestCase;

public classMongoDBTest extends TestCase {

}

Mongodb之order集合未建立任何索引条件下,得出如下(集合原数据为0条,直到测试完,中间未删减):

insert:1,cost:20ms

insert:500,cost:148ms

insert:5000,cost:367ms

insert:10000,cost:1095ms

insert:50000,cost:2009ms

insert:100000,cost:3529ms

insert:200000,cost:7464ms

insert:250000,cost:15412ms

测试更多数据JVM就内存溢出了

ԭ:1950000,insert:250000,cost:14073ms

ԭ:2200000,insert:250000,cost:14882ms

ԭ:2450000,insert:250000,cost:11160ms

ԭ:2700000,insert:250000,cost:11500ms

ԭ:2950000,insert:250000,cost:12952ms

ԭ:3200000,insert:250000,cost:15291ms

ԭ:3450000,insert:250000,cost:11960ms

ԭ:3700000,insert:250000,cost:15291ms

ԭ:3950000,insert:250000,cost:11762ms

ԭ:4200000,insert:250000,cost:13453ms

ԭ:4450000,insert:250000,cost:13939ms

ԭ:4700000,insert:250000,cost:13565ms

ԭ:4950000,insert:250000,cost:13866ms

ԭ:5200000,insert:250000,cost:13912ms

ԭ:5450000,insert:250000,cost:12296ms

ԭ:5700000,insert:250000,cost:15472ms

ԭ:5950000,insert:250000,cost:13396ms

ԭ:6200000,insert:250000,cost:9297ms

ԭ:6450000,insert:250000,cost:10591ms

ԭ:6700000,insert:250000,cost:12350ms

ԭ:6950000,insert:250000,cost:11533ms

ԭ:7200000,insert:250000,cost:11657ms

ԭ:7450000,insert:250000,cost:11309ms

ԭ:7700000,insert:250000,cost:13422ms

ԭ:7950000,insert:250000,cost:12750ms

ԭ:8200000,insert:250000,cost:11493ms

ԭ:8450000,insert:250000,cost:12556ms

ԭ:8700000,insert:250000,cost:12235ms

ԭ:8950000,insert:250000,cost:13918ms

原:9200000,insert:250000,cost:12586ms

同比mysql如下:

mongodb之order集合对orderId建立任何索引条件下,得出如下:

同比mysql如下:

源码

文章来源: MongoDB
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!