1. mongoDB安装
官方手册:
https://docs.mongodb.com/manual/tutorial/
安装指南:
https://docs.mongodb.com/manual/tutorial/install-mongodb-enterprise-on-red-hat/
mongoDB可视化工具:
https://studio3t.com/
远程链接需要注意:
mongodb的配置文件中的bind_ip 默认为127.0.0.1,默认只有本机可以连接。 此时,需要将bind_ip配置为0.0.0.0,表示接受任何IP的连接。修改mongod配置文件: /etc/mongod.conf
参考文档:
MongoDB 进阶模式设计:
https://mp.weixin.qq.com/s/IL3L1OI9SUYN1gNaaVDVHA
2.关系模型和文档模型的区别在哪里?
关系模型的功能:单值,多文档事物性,关联。
文档模型的功能:富文档、数组、内嵌,单文档事务性,基本不支持关联
两者的相同功能:动态查询,二级索引,聚合。
2.1 文档模型的优点
读写效率高 -由于文档模型把相关数据集中在一块,在普通机械盘上读数据的时候不用花太多时间去定位磁头,因此在IO性能上有先天独厚的优势;
可扩展能力强 -关系型数据库很难做分布式的原因就是多节点海量数据关联有巨大的性能问题。如果不考虑关联,数据分区分库,水平扩展就比较简单;
动态模式 -文档模型支持可变的数据模式,不要求每个文档都具有完全相同的结构。对很多异构数据场景支持非常好;
模型自然 -文档模型最接近于我们熟悉的对象模型。从内存到存储,无需经过ORM的双向转换,性能上和理解上都很自然易懂。
3.MongoDB文档模式设计的基本策略
文档模式设计有2中基本策略:1.内嵌。2.引用
3.1 内嵌策略
如果你的对象模型数量不多,关系不是很复杂,可以使用内嵌策略。内嵌是文档模型的特色,可以充分利用MongoDB的富文档功能来享受我们刚才谈到的一些文档模型的性能和扩展性等特性。一般的一对一、一对多关系,比如说一个人多个地址多个电话等等都可以放在一个文档里用内嵌来完成。
单个文档(BSON格式)大小限制为16M。这是一个坑。
这个’坑’ 可能会让你花时间都难以发现, 因为这又要牵扯到mongodb的另一个存储机制 —- 无返回码. 在 < mongodb 权威指南> 一书中, 作者称之为离弦之箭. 什么意思呢?就是mongodb的插入,删除等操作, 客户端向数据库发出请求之后, 是不需要等待数据库返回操作是否成功的返回结果. 这也是mongodb插入,更新等操作速度快的原因. 这就导致, 当单个文件超过16M之后, 程序并不会报错。
GridFS是用于存储和检索超过 BSON文档大小限制为16 MB的文件的规范。GridFS不是将文件存储在单个文档中,而是将文件分成多个部分或块,并将每个块存储为单独的文档。
如果需要以原子方式更新整个文件的内容,请不要使用GridFS。作为替代方案,您可以存储每个文件的多个版本,并在元数据中指定文件的当前版本。您可以在上载新版本的文件后更新在原子更新中指示“最新”状态的元数据字段,并在以后删除以前版本。
3.2 引用策略
在主表里存储一个id值,指向另一个表中的 id 值。使用引用要注意的就是:从性能上讲,一般我们可能需要两次以上才能把需要的数据取回来。更加重要的是:需要把数据存放到两个集合里,但是目前为止MongoDB并不支持跨表的事务性,所以对于强事务的应用场景要谨慎使用。
3.3 何时选择不同的策略
先考虑内嵌,内嵌适合一对一,一对多。局限性在于文档最大16M限制,大数组性能欠佳。
后考虑引用,引用适合多对多,两个对象都为主要对象。局限性在于多次查询、写入,无跨表事务性。
4.MongoDB模式设计的终极原则
MongoDB的模式设计和关系型大不相同,我们说MongoDB是为应用程序设计的,而不是为了存储优化的。如果可以达到最高性能的话,我们甚至可以做一些反范式的东西。
4.1 数据冗余&扇出写
社交app最关键的一些场景就是维护朋友关系以及朋友圈或微博墙等。使用文档模型的内嵌数组特性,我们可以很容易地把我关注的用户(following)和关注我的用户表示出来。
但是有一个潜在问题就是如果我是一个明星,他们关注我的人可能有千万。一个千万级的数组会有两个问题:
1) 有可能超出一个文档最大16M的硬性限制;
2) MongoDB数组太大会严重影响性能。
扇出读是一种比较常规的做法,就是当你需要去获得所有你关注用户的最新更新的时候,你就去到每一个你关注用户的数据区,把最新的一些数据取回来。因为需要去到不同的分片服务器去取,所以叫做扇出读。大家可以想象,这种扇出读的效率不会太高,基本上是最慢的那个服务器的响应时间决定了总体的响应时间。 当然,这种方式是比较简单的,不需要特殊处理。
扇出写的具体做法,当发布的时候,一条数据会写多次,直接写到每一个关注你的粉丝的墙上。这样做的好处是当你的粉丝读他自己的微博墙的时候,他只需要去一个地方就可以把所有最新的更新连续取回来。由于一个用户的数据可一般可以存储在同一台服务器上的同一个区域,通过这种方式可以实现快速的读取微博墙数据。 代价当然也是很明显: 你的写入需求会被放大几十几百倍,存储也是相应的扩大几十几百倍。这个绝对不是关系型数据库的玩法,但是在MongoD 模式设计,这个很正常。只要保证性能,什么事情都做得出来。
4.2 分桶
在IOT这个场景里,我们可以使用一个叫做分桶的设计方式来进行几十倍的性能增长。具体来说就是把采集的数据按小时为一个桶,把每小时的数据聚合到一个文档里。这样做的好处就是大量减少文档的数量,相应的索引数量也会减少,总体写入IO将会大幅度降低并得到性能提升。
存储引擎:
mongodb 3.0默认存储引擎为MMAPV1,mongodb 3.2+之后,默认的存储引擎为“wiredTiger”,大量优化了存储性能,建议升级到3.2+版本。