`
jorwen_fang
  • 浏览: 51630 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

MongoDB学习笔记(十四):设计和其它补充

阅读更多

1.反范式设计

先看看关系数据库做个关联查询怎么做的 
比如2个表如下,一个订单有多个产品 
products:{ 
'id', 
'name', 
'price', 
'desc' 
} 

orders:{ 
'id', 
'user', 
'items':[product_id1,product_id2,product_id3] 
} 
这种做法关系数据库肯定没问题,一个表关联查询就行了。但mongodb则不得不查询多次,否则只能拿到产品id而已。大大降低查询性能 

那要一次的话如下设计: 
orders:{ 
'id', 
'user', 
'items':[ 
{ 'id':product_id1, 'name':..., 'price':..., 'desc':... }, 
{ 'id':product_id2, 'name':..., 'price':..., 'desc':... }, 
{ 'id':product_id3, 'name':..., 'price':..., 'desc':... }] 
} 

这样只需要一次查询便可,而且还能用elemMatch方法对items进一步过滤,就和关联查询差不多了。虽然DBRef也能做到,但DBRef不能进一步过滤。但这种方式缺点就是你在更新products时放弃了一致性。比如产品名字和价格变化,那老的数据还在order里,但这个需求是正确的,因为产品变了,但当时的订单的确不该变,不是吗。 

何时需要反范式设计: 
1.你认为引用的数据是否需要保持最新的?不是的话用反范式设计。(比如产品和订单的例子) 
2.要保持最新,那更新频率多久一次?如果极少变化,那适合用反范式设计。 
3.必须做到查询快速。那你得用反范式。 

但你可以在修改时,实时或延时同步过去,看数据量是否庞大,太庞大就算了。
 

2.不要把不断增加的数据嵌入

首先说说什么叫嵌入,数据库一对多,有2种做法,比如帖子和评论2个表,评论有个字段是帖子ID,那帖子和评论就是1对多,这个做法是引用。如果帖子有个字段叫评论(是个放ID的数组)这个就是内嵌。 

不断增加的数据,mongodb对数组追加效率是很低的。不管10个1000个10万个都不算啥,但之后要保持不变,否则会慢得你受不了。比如一个帖子的评论,那就应该使用引用做法,而不是内嵌
 
 

3.嵌入做法预留空间

mongodb如果要增加内嵌的数组,是很慢的,要分配空间。但是只是修改内容是很快的。 
所以如果你在插入数据时,明确知道总共多少条或最多多少条,可以先预留空间。放几个0或空字符串填充。
 

4.尽量避免让mongoDB做计算

由于mongodb是种无脑的大型数据库,几乎不会做任何高效的处理。虽然group,mapreduce,和聚合功能都有,但效率不佳。所以尽量避免这样去做。 
比如你有个表 
{id, appleCount, orangeCount}分别有苹果和橘子总数,你当然可以用上面方式得到他们总数,但你最好增加一个totalCount字段来达到这个效果
 
 

5.要有几个定时任务协助mongodb

1. 一致性修复器 
使用反范式模式,但你有希望数据一致性 

2.预分配器 
创建今后文档需要用到的空间,否则到了应用会很慢 

3.聚合器 
通过增加表或增加字段的方式聚合数据 

4.结构校验器 
确保当前文档都有必填字段,否则矫正或通知。 

当然以上都不能做到实时
 
 

6.ObjectId

无意义的主键用ObjectId存储,千万别转换成字符串。 

1.方便查询 
2.含有有用信息 
3.字符串要多占两倍磁盘
 
 

7.如果有自己主键,请不要用默认主键

默认主键_id,如果你有自己的主键就不要用它,节省空间资源。 
要知道1亿数据下,主键要占几百M内存。
 
 

8.DBRef尽量避免使用

1.浪费一个字段$ref的空间2.完全可以自己用id做引用的范式设计代替这个功能
 

9.小文件数据不要用GridFS

GridFS查询性能较差。如果确定都是小文件(小于16M)请存储在表里
 

10.不要到处使用索引

比如你要返回集合中50%记录,就不该使用索引,比不用索引还慢。 
所以,索引一般用在返回结果只是总体数据的一小部分时,超过一般就不要用了。 

如果已经简历索引,但又在大规模查询不用索引,就用{"$natural":1} 强制禁用索引 

写入操作大大多于查询操作,不要使用索引,否则写入会变慢。
 

11.建立分级文档加速扫描

假如你有一个表有10个字段,其中一个是zip,你查询如下
1.db.users.find({'zip':‘10003’})
那mongodb会遍历每个字段来查找zip字段 

使用内嵌文档我们能这样设计 

把10个字段分成3~4个组,每个字段里面放字段 

那么查询语句就变成
1.db.users.find({'address.zip':‘10003’})
 
 

12.and 和 or查询

对于and,越是结果少的要放在条件的前面 
对于or则相反,越是结果多的放在条件的前面 

原理自己想想吧
 

13. 日志和备份节点

日志(-journal)和备份节点都会影响性能,而且都能做为数据恢复用,每台服务器2个都开启实在没啥必要。 
建议是主纯备份节点可以用日志, 主节点和热备节点可以不用。如果没有纯备份节点,就用某个从节点开启日志
 
 

14.开发时使用notablescan参数

开启这个选项,只要做全表扫描都会报错。开发时开启很有用,但生产环境不要开启
分享到:
评论

相关推荐

    学习笔记:我的学习笔记

    【学习笔记:我的学习笔记】 这是一份个人的学习笔记,主要涵盖了广泛的IT知识领域,...不断更新和补充学习笔记是提升技能和保持行业敏锐度的有效方式。记得结合实际项目和练习来巩固理论知识,以达到最佳的学习效果。

    linux运维学习笔记:数据库介绍与安装管理.pdf

    除了MySQL和NoSQL之外,其他重要的数据库产品如PostgreSQL、MongoDB和Redis等在大型互联网公司中得到广泛应用。这些产品的特点和版本更新,以及它们在市场中的定位,也是数据库管理员需要关注的重点。 在数据库安装...

    数据库与搜索技术-附录.rar

    此外,非关系型数据库,如NoSQL,适用于大数据、实时分析和分布式系统,如MongoDB和Cassandra。 在数据库设计中,概念设计、逻辑设计和物理设计是三个关键步骤。概念设计将业务需求转化为数据模型,如实体-关系(E-...

    FCC:ZQW的FCC前端开发笔记

    【FCC:ZQW的FCC前端开发笔记】是一份深入浅出的前端开发学习资源,主要基于Free Code Camp(FCC)的学习路径和挑战进行整理。FCC是一个全球知名的在线学习平台,专注于教授Web开发技能,包括HTML、CSS、JavaScript...

    study-notes:学习进展中总结的笔记

    首先,"Java知识点补充"这部分是关于Java编程语言的学习笔记。Java是一种广泛使用的面向对象的编程语言,它的特点是跨平台、安全性高以及性能优异。这里可能包括了类、对象、接口、继承、多态性、异常处理、集合框架...

    javayouxi.rar_-baijiahao_java 网络游戏

    7. **数据库集成**:游戏往往需要保存用户数据,学习如何使用SQL和NoSQL数据库如MySQL、MongoDB等存储和检索游戏数据。 8. **调试与测试**:学习如何使用Java的调试工具进行问题定位,以及编写单元测试确保代码质量...

    2_复习资料.zip

    3. **数据库管理**:SQL语言、关系型数据库(如MySQL、Oracle)、NoSQL数据库(如MongoDB)的基本操作和设计原则。 4. **操作系统**:Windows、Linux、macOS的基本操作、命令行使用、系统管理与优化。 5. **软件...

    dss8654-The-Web-Developer-Bootcamp-2020:dss8654The-Web-Developer-Bootcamp-2020。 这是我要保存上述关于Udemy的课程的进度的地方

    9. **补充资料**:可能包括参考书籍、文章、工具和其他资源,帮助扩展学习。 10. **测试和作业**:用于检验学习效果,可能包含代码挑战和小测验。 总之,"The Web Developer Bootcamp 2020" 是一个全面的学习路径,...

    freeCodeCamp研究:Códigorelacionado aos tutoriais做freeCodeCamp

    研究 Códigorelacionado aos tutoriais do FreeCodeCamp" 暗示,这个压缩包可能包括了与freeCodeCamp教程配套的源代码,学员可能通过这些代码来实践所学的知识,或者可能是其他用户对教程内容的补充和扩展,以便...

    notes

    4. **数据库管理**:可能会讲解SQL语法、数据库设计(ER模型)、事务处理、索引优化、关系型数据库(如MySQL、PostgreSQL)和非关系型数据库(如MongoDB、Redis)的区别及使用场景。 5. **软件工程**:包括敏捷开发...

Global site tag (gtag.js) - Google Analytics