MongoDB开发规范

一.命名规则

1.mongodb版本选择:
默认新装数据库使用MongoDB 3.X 社区版。建议3.2.10+

2.数据库设计规范
数据库名可以是满足以下条件的任意UTF-8字符串:
(1)不能出现除“_”字符以外的特殊字符;
(2)不能含有”(空格)、.、$、/、、和(空字符);
(3)应全部小写;
(4)最多30字符。
(5)禁止使用数字打头的库名

3.集合命名规则
必须满足下列条件的任意UTF-8字符串
(1)集合名不能是空字符串“”; 不能出现除“_”字符以外的特殊字符,禁止使用数字开头的名称;
(2)集合名不能以“system.”开头,这是为系统集合保留的前缀。例如system.users这个集合保存着数据库的用户信息,system.namespaces集合保存着所有数据库集合的信息;
(3)用户创建的集合名字不能含有保留字符$。除非你要访问系统创建的集合,否则不可在名字里出现$;
(4)集合名应简洁明了,尽量都使用小写;

4.字段命名规范
(1)字段不能含有(空字符)。
(2)禁止使用数字开头的字段名;
(3)不可以“”开头命名字段名称,不能出现除“”字符以外的特殊字符;
(4)字段引用必须采用集合名+被引用字段名称。例如集合user的键id在集合user_info中被引用,用user_id作为键名;
(5)只有在遇到引用情况下,字段中包含的集合名首字母需要大写,其他一律小写格式。
(6)如果字段较大,应尽量压缩存放
(7)如果字段较大且会成为查询条件,例如一长串的url,可以转成md5后存放
(8)禁止自定义_id的值。

二:数据库设计规范

1.
(1) 合理容量规划和库级拆分
创建新的数据库时,提前进行容量规划库的集合数,存储容量,QPS等, 是放在已有集群,还是新创 建集群部署。
(2) 避免把所有集合都放在同一个数据库,造成一个库中集合过多;
(3) 业务禁止使用id字段;
业务避免向id字段写入自定义的业务数据:因MongoDB的
Jd字段默认是主键, 类似于MySQL InnoDB表的主键,如果业务写入无序数据(如uuid/md5),集合本身是B+ Tree,为保证树的平衡,会大副度调整内部存储数据结构;写入数据的代价很大,容易导致写入性能低;
(4) MongoDB数据是大小写敏感的,如业务不区分大小,建议冗余一个全部大写或小写字段,用于不区分大小写的数据检索效率*
mongo中数据查询是大小写敏感的,例如{f,"aA"}的查询条件, 不能匹配字段为“aa”,“AA", “Aa” 值的文档。有的业务需忽略大小,需通过正则方式进行处理{f:aa/},虽实现忽略大小功能,但查询效率很低,同时很耗CPU资源。 解决这类需求,希望冗余一个全大写(或小写)的字段,用于业务忽略大小的检索需求。例如对f字段冗余tupper字 段,存储字段内容全大写{f_upper."AA‘}
(5) 对高频大字段进行压缩存储:
很多高频的查询,如果存在返回较大字段数据(如10 KB以上),当QPS增加后很容易把MongoDB服务器网络带宽占满。
或写入频次较高,会导数oplog实体很大。建议这类高频和较大的数据, 在业务层进行 压缩后,再存入MongoDB中。
(6)ObjectId存储时,作为ObjectId存储,不可存成字符串类型;
原因:第一,方便查询(字符串和ObjectId不能相互匹配)第二,ObjectId 含有有用的信息,如从插入的时间戳可以得知创建日期;第三,字符串表示的ObjectId要多占用两倍的磁盘空间;

2.索引设计规范
(1)MongoDB的索引仅支持1K以内的字段,如果你存入的数据长度超过1K,那么它将无法被索引
(2)索引名称长度不要过长;命名方式:idx_字段名 ;组合索引建议包含所有字段名,过长的字段名可以采用缩写形式。
(3)唯一索引命名规范:uniq_字段名称
(3)应尽量综合评估查询场景,通过评估尽可能的将单列索引并入组合索引以降低所以数量;
(4)索引越多,插入或修改记录就会导致 mongodb 越慢。
(5)创建索引要在后台创建,避免阻塞业务正常DML和查询。db.works.createIndex({a:1,b:1},{"name":‘idx_字段名‘},{background:true})
(6)禁止在数组字段上创建索引;
(7)在创建组合索引的时候,应评估索引中包含的字段,尽量将选择性高(唯一值多的数据)的字段放在组合索引的前面;
(8)在开发业务的时候尽量检查自己的程序性能,多使用explain()查看执行计划;
(9)禁止冗余索引。 例如索引idx_account_sName_createTime {"account" : 1,"sName" : 1,"createTime" : -1}和索引idx_account {"account" : 1} 索引冗余,可删除idx_account索引。

3.查询规范
(1)查询语句是否使用到索引,在查询条件的键上,或者排序条件的键上必须有索引(数据量较小的集合除外);
(2)使用limit()限定返回结果集的大小,减少数据库服务器的资源消耗,以及网络传输的数据量。
(3)只查询使用到的字段,而不查询所有字段;尽量不要让数组字段成为查询条件
(4)执行remove()删除操作,未带查询条件,警告或报错;
(5)查询中的某些$操作符可能会导致性能低下,如 $ne,$not,$exists,$nin,$or,$where尽量在业务中不要使用
(6)MongoDB 的组合索引使用策略 遵循"最左原则",优先使用覆盖索引,查询语句遵守复合索引字段顺序
(7)必要时使用hint()强制使用某个索引查询
(8)更新操作时,先查询后更新,通过主键key更新,可以提高更新效率;

###应用程序连接配置
合理设置读写分离,减少主节点压力,提高可集群可扩展性
(1)mongo客户端通过只读偏好(read -preference)属性设置,决定客户端只读查询的路由规则。
(2)mongo客户端默认所有查询都路由到主节点查询,而很多应用程序只读业务一-致性不高 (接受秒级别的同步延时), 可把只读查询路由到从节点。MongoDB正常 复制同步延时在1秒内。
(3)如果业务只读查询,对数据- -致性要求不高(比如最坏情况按受60秒延时).建议程序drver的[只读偏好]属性设置为 secondaryPreferred.

mongo客户端[只读偏好]支持5种模式:

Read Preference Mode Description
primary 默认模式,客户端所有只读命令都发向主节点
primaryPreferred 只读查询默认发给主节点,当主节点不可用时,转发给从节点
secondary 所有的只读查询发向从节点
secondaryPreferred 所有只读查询发向从节点,如果所有从节点不可用时,转发给主节点
nearest 只读查询发给最近可用数据节点,不考虑节点的角色

MongoDB 分片片键如何选择:

分片键规范:

1.分片键的几个原则:
分片键是不可变。
分片键必须是索引。
分片键大小限制512bytes。
分片键用于路由查询。
MongoDB不接受已进行collection级分片的collection上插入无分片键的文档。

好片键的要素

好的 shard key 应该拥有如下特性:
1.key 分布足够离散 (sufficient cardinality)
2.写请求均匀分布 (evenly distributed write)
3.尽量避免 scatter-gather 查询 (targeted read)
MongoDB的内部机制保证了每个副本集(RS)包含了同样数量的块。
片键的选择决定了三个重要的方面:
#####1. 读和写的分布
其中最重要的一点是读和写的分布。如果你总是朝一台机器写,那么这台机器将会成为写瓶颈,则你的集群的写性能将会降低。这无关乎你的集群有多少个节点,因为所有的写操作都只在一个地方进行。因此,你不应该使用单调递增的_id或时间戳作为片键,这样将会导致你一直往最后一个副本集中添加数据。

相类似的是如果你的读操作一直都在同一个副本集上,那么你最好祈求你的任务能在机器内存所能承受的范围之内。通过副本集将读请求划分开能够使你的工作数据集大小随着分片数线性扩展。这样的话你能够将负载压力均分到各台机器的内存和磁盘之上。

2. 数据块的大小

其次是数据块的大小。MongoDB能够将大的数据块划分成更小的,但这种情况仅仅在片键不同的情况下发生。如果你有巨量的数据文档都使用了同样的片键,那么你相应的会得到巨大的数据块。出现巨大块是非常不好的,不仅仅因为它会导致数据的不平均分布,还因为一旦这个数据块的大小超过某个值,那么你就不能够在分片之间移动它了。

3. 每个查询命中的分片数目

最后一点,如果能够保证大部分的查询请求都能够命中尽可能少的分片那就最好了。对于一个查询请求来说,其延迟直接取决于最慢的那个命中服务器的延迟;所以你命中的分片越少,那么理论上来说查询将会越快。这一点并不是硬性的规定,不过如果能够做到充分考虑那么应该是很有利的。因为数据块在分片上的分布仅仅是近似的遵循片键的顺序,而并不是严格的强制指定。

几种分片键的策略

1、Hashed id 可以使用数据文档_id的哈希作为片键

读和写都能够平均分布,并且它能够保证每个文档都有不同的片键所以数据块能够很精细。
对多个文档的查询必将命中所有的分片。

2、递增的sharding key

数据文件挪动小(优势)
因为数据文件递增,所以会把insert的写IO永久放在最后一片上,造成最后一片的写热点。同时,随着最后一片的数据量增大,将不断的发生迁移至之前的片上。

3、随机的sharding key

数据分布均匀,insert的写IO均匀分布在多个片上。(优势)
对多个文档的查询必将命中所有的分片;大量的随机IO,磁盘不堪重荷。

4、混合型key

为防止巨大块的产生,建议使用组合键,引入_id来细化。{keyname: 1, _id: 1}
原则就是:keyname可以是一个经常被查询的字段,尽可能基数较大;_id字段是有非常多不同的值可以供mongodb进行分割,这种策略适合大多业务情况;如果实在找不到keyname这样字段,那么就对_id进行Hashed吧。

原文地址:https://blog.51cto.com/woniu123/2464060

时间: 2024-11-08 23:00:13

MongoDB开发规范的相关文章

web前端开发规范

本文原创,这里首先声明,转载注明本文出处,翻版必究! web前端开发规范的现实意义 1.提高团队的协作能力 2.提高代码的重复利用率 3.可以写出质量更高,效率更好的代码 4.为后期维护提供更好的支持 5.可读性高 一.命名规则 1.html命名规则: a.文件名称命名规则:统一使用小写英文字母.数字.下划线的组合,不得包含汉字空格和特殊字符 2.命名原则:方便理解.方便查找 b.索引文件命名原则:index.html.index.htm.index.asp.index.aspx.index.j

Sqoop 脚本开发规范(实例手把手带你写sqoop export和sqoop import)

首先,先明确,为什么Sqoop需要规范的脚本开发呢? 答:是因为,Sqoop import HDFS/Hive/HBase这些都是手动.但是在实际生产里,有时候,需要用脚本来完成. 比如,通过shell脚本来操作对Sqoop.Hive.HBase.MapReduce.HDFS.Spark.Storm等各种. Sqoop 脚本开发规范 目录规范 1.目录结构体系 /home/hadoop(开发用户)/app/djt(数据来源.业务)/sh/sqoop 示例:/home/hadoop/app/djt

C#语言开发规范-ching版

学习C#之初,始终不知道怎么命名比较好,很多时候无从命名,终于有一天我整理了一份命名规范文档,自此我就是按照这个命名规范书写代码,整洁度无可言表,拙劣之处请大家斧正,愚某虚心接受,如有雷同,不胜荣幸 C#语言开发规范 作者ching 1.  命名规范 a) 类 [规则1-1]使用Pascal规则命名类名,即首字母要大写. eg: Class Test { ... } [规则1-2]使用能够反映类功能的名词或名词短语命名类. [规则1-3]不要使用“I”.“C”.“_”等特定含义前缀. [规则1-

Web前端开发规范文档(google规范)

(Xee:其实没什么规范约束,但是养成一种好习惯,何乐而不为?) 我推荐去看看google的开发规范,然后从他的当中去总结自己的开发规范. Google HTML/CSS代码风格指南 Google JavaScript 编码规范指南 ------------------------------------------------------------------------------------------------------------------------------- 绝大多数项

麦子新课上线之web前端开发规范

同学们,Web前端开发又有课程上线啦!对Web前端感兴趣的同学们,速来围观哦~~下面简单介绍一下课程. [学霸学新,课快人一步] 课程简介: Web前端开发规范,可以帮助同学们,了解web前端开发规范的意义,掌握前端开发中的开发规范,掌握web前端开发中的实用技巧.面对企业团队开发,可以很快融入团队合作中,高效率的完成团队给予的任务. 课程地址→http://www.maiziedu.com/course/web/621-8960/ 老师简介: 何虎:8年软件开发经验,擅长互联网应用程序开发,曾

shell开发规范

版本1.0版,参考网上的一些文章规整而来.后期打算继续修改.完成一篇适合自己的shell开发规范. 最新编辑时间:2017.6.25 一. 命名规范 1. 版本和运行参数 1) 脚本开始之前以注释形式说明版本号:(推荐)2) 如果调用其他工具,还需说明工具的版本号:(推荐)3) 为脚本添加必须的运行参数,类似于C程序的运行参数,可使用getopt的方式取得运行参数值,如基本的参数有:-v - 版本号:-h – 帮助信息:(推荐) 2. 变量命名 1) 变量命名要前后统一,建议使用全部大写字母,如

软甲开发规范

软件开发规范:获得本目录的绝对路径sys.payh.abspath(__file__)获得本级目录的父目录sys.payh.dirname(sys.payh.abspath(__file__)) 软件名 bin #可执行文件  start.py#调用core下面的main代码启动软件 core#主代码  main.py#调用数据库的配置文件存放处 conf#配置文件中可以导入数据库文件  setting.py db#数据库文件  db.json docs#软件文档  一些文档 lib#库文件,就

我的开发规范

转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6413978.html 每个开发人员在长久的开发生涯中,都会养成自己的一套开发风格,或者说,规范.之后在开发项目时都会下意识地遵循着心中的规范去设计.开发项目.这种开发风格随着经验和能力的增加会不断修改.演变,由幼稚走向成熟.我只是个刚开启开发之旅的小菜鸟,在此记录下我的开发规范,以便日后不断修正.进步. 1:项目架构与设计 分6层:View层编写前端页面,Control层处理view层请求(包括各servl

Android技术积累:开发规范

原创文章,转载请注明:转载自Keegan小钢 并标明原文链接:http://keeganlee.me/post/android/20150709 微信订阅号:keeganlee_me 写于2015-07-09 上个月发布了Android项目重构的三篇系列文章,其中,界面篇中提到了在项目中保持规范性的重要性,也有简单举了几个例子.这篇文章则将其延伸,提供更完整的开发规范说明. 书写规范 1. 编码方式统一用UTF-8. Android Studio默认已是UTF-8,只要不去改动它就可以了. 2.