和众多其他数据库产品一样,MongoDB 数据库的命名和设计也有一套规范。只不过,由于用的人不多,目前在业界还没有形成权威的共识,今天根据我个人平时的一些经验,总结了一些规范,不喜忽喷!

第一部分,我们先说命名规范。

文档

设计约束

  • UTF-8 字符

  • 不能包含 \0 字符(空字符),这个字符标识建的结尾

  • . 和 $ 有特殊含义,需要避免

  • 区分大小写

  • 键不能重复

  • 键/值对有序

实践约束

  • 【强制】文档中的key禁止使用_以外的特殊字符

  • 【强制】key全部小写,多个单词可以下划线分割

  • 【强制】禁止使用数字打头的key

  • 【强制】禁止自定义_id(_id一般自增,使用无序id极有可能降低写入性能)

  • 【建议】相似类型文档放在一个集合中,能大幅提高索引利用率

  • 【建议】若业务上对于存放数据大小写不敏感,则使用全部大写/小写存放(或者增加一个统一了大小写写的辅助字段)。

    使用忽略大小写的查询极其耗费性能

  • 【建议】不要存放太长的字符串

注意:MongoDB 索引仅支持 1KB 以内的字段

集合

设计约束

  • UTF-8 字符

  • 不能是空字符串("")

  • 不能包含 \0 字符(空字符),这个字符标识集合名的结束

  • 不能以 “system.” 开头,这是为系统保留的前缀

  • 不在集合中包含字符 “$”

  • 使用 “.” 来分隔不同命名空间的子集合,如一个博客可能包含两个子集合,blog.posts和blog.authors,而blog本身可以不存在

实践约束

  • 【强制】禁止使用_以外的特殊字符

  • 【强制】集合名称不超过64字符

  • 【强制】集合名称全部小写

  • 【强制】禁止使用数字打头的集合名,禁止使用system打头的集合名(system为系统集合前缀)

  • 【建议】为了避免库级锁带来的问题,应尽量对写入较大的集合使用“单库单集合”的结构,所以对于新增业务应尽量创建新库,而不是在现有库中创建新集合

数据库

设计约束

  • UTF-8 字符

  • 不能是空字符串("")

  • 基本上只能使用 ASCII 中的字母和数字。

    不能含有 /、\、.、"、*、、:、|、?、$、(空格)、\0(空字符)

  • 全部使用小写。

    (支持大写,不建议使用)

  • 不超过64字节

  • 存在保留数据库如:

    admin、local、config

注意:数据库名称限制主要是由于数据库最终会变成文件系统里的文件,而数据库名就是相应的文件名,因此才有很多约束

实践约束

  • 【强制】数据库名称全部小写

  • 【强制】数据库名称不超过64字符

  • 【强制】禁止使用_以外的特殊字符

  • 【强制】禁止使用数字打头的数据库名

  • 【强制】禁止与保留的数据库重名,如:

    admin,local,config等

索引

  • 【强制】索引名称长度不超过128字节

  • 【强制】禁止在数组字段上创建索引

  • 【强制】创建组合索引时,尽量将数据基数大(唯一值多的数据)的字段放在组合索引前面

查询

  • 【建议】先做等值查询,再做排序,再做范围查询

  • 【建议】查询中的某些 $ 操作符可能会导致性能低下,尽量避免

注意:ne,ne,     ne,ne,not,exists,exists,     exists,exists,nin,$or,尽量在业务中不要使用$exist:因为松散的文档结构导致查询必须遍历每一个文档$ne:如果当取反的值为大多数,则会扫描整个索引$not:可能会导致查询优化器不知道应当使用哪个索引,所以会经常退化为全表扫描$nin:全表扫描$or:有多少个条件就会查询多少次,最后合并结果集,所以尽可能的使用 $in

命名空间

  • 将数据库名添加到集合前,得到集合的完全限定名,称为命名空间(namespace),如cms数据库的blog.posts集合,命名空间即为:

    cms.blog.posts。

    实际使用中命名空间长度不得超过100字节

第二部分,设计规范。

数据库设计规范

(1)数据库名约定为小写。

(2)数据库名称不能包含除’_’以外的特殊字符,例如:/ \ . “ $。

(3)数据库名称最多为64个字符。

(4)数据库上线需经过DBA评审。

集合设计规范

(1)集合名称约定为小写。

(2)集合名称不能包含除’_’以外的特殊字符字符;集合名称禁止以system.开头。

(3)集合名称的最大长度为64个字符,包括前缀的【database.】内容。

(4)集合名称的命名规则和MySQL数据库表的命名规则相同。

a)   同一模块的集合尽可能使用相同的前缀名,集合名称尽可能表达用途。

b)   数据表 _ 例如:order_header , order_detail

c)   编码表 base__

d)   日志表 log__

(5)固定集合可以用于记录日志,其插入数据更快,可以实现在插入数据时,淘汰最早的数据。固定集合需要显式创建,指定Size的大小,还能够指定文档的数量。集合不管先达到哪一个限制,之后插入的新文档都会把最老的文档移出。

(6)索引命名:idx_。如果字段名字过长,可采用字段缩写。

文档设计规范

(1)Key的命名规范:不能以$开头;不能包含.(点号)。

(2)文档中的_id键推荐使用默认值,禁止向_id中保存自定义的值。

MongoDB文档中都会有一个“_id”键,默认是个ObjectID对象(标识符中包含时间戳、机器ID、进程ID和计数器)。MongoDB在指定_id与不指定_id插入时速度相差很大,指定_id会减慢插入的速率。

(3)推荐使用短字段名。

与关系型数据库不同,MongoDB集合中的每一个文档都需要存储字段名,长字段名会需要更多的存储空间。

(4)禁止在同一个集合字段中存储多个数据类型的数据。

(5)如若将日期类型选择为string,不同的日期格式的文档,不支持等值查询,不支持范围查询。

创建一个测试集合product,分别向集合插入Date:"20180425"和Date:"2018-04-25"两笔数据。等值查询、范围查询($gte, $lte)只能查到日期格式相同的数据,都为一笔数据。

(6)MongoDB大小写敏感,如果字段无需大小写敏感,为了提高查询效率,应尽量在统一了大小写之后再插入到数据库中。

(7)MongoDB是文档型数据库,数据以BSON形式存储在文档中。MongoDB能够支持最大16 MB的文档大小。建议尽量不要存储大型对象,将文档控制在16 MB以内。

(8)通过$size查询数组大小,但是$size运算符不使用索引和限制准确匹配(不能指定$Sized 范围)。因此,如果需要基于数组的大小执行查询,可以在文档设计中增加size属性。

例如在商品评价中,其他人可以对评价进行投票。为了阻止用户多次投票和对有帮助的评论进行排序,所以,评价文档设计是:在一个数组字段(voter_ids)保存了所有评论用户的ID,而数组大小缓存在helpful_votes字段里。

(9)分片键必须有索引,分片键大小限制为512byte,一旦集合已经分片,不可以直接修改分片键。不接受向已进行分片的collection上插入无分片键的文档,也不支持空值插入。

(10)片键的设计原则:

a)   所有的插入、更新、删除将会均匀发送到集群的所有分片中。

b)   所有的查询将会在集群中的所有分片中均匀地分发。

c)   所有的更新或者删除操作将会只面向相关的分片,不会发送到一个没有存储被修改数据的分片上。

d)   一个查询将不会被发送到没有存储被查询数据的分片上。

连接规范

(1)正确连接副本集,副本集提供了数据的保护、高可用和灾难恢复的机制。如果主节点宕机,其中一个从节点会自动提升为从节点。

(2)合理控制连接池的大小,限制连接数资源,可通过Connection String URL中的maxPoolSize 参数来配置连接池大小。

Mongod 的服务模型是每个网络连接由一个单独的线程来处理,每个线程配置了1MB 的栈空间,当网络连接数太多时,过多的线程会导致上下文切换开销变大,同时内存开销也会上涨。

(3)复制集读选项

默认情况下,复制集的所有读请求都发到Primary,Driver可通过设置的Read Preference 来将读请求路由到其他的节点。

a)   Primary:默认规则,所有读请求发到Primary。

b)   PrimaryPreferred: Primary优先,如果Primary不可达,请求Secondary。

c)   Secondary:所有的读请求都发到Secondary。

d)   SecondaryPreferred:Secondary优先,当所有的Secondary不可达时,请求Primary。

e)   Nearest:读请求发送到最近的可达节点上(通过ping探测得出最近的节点)。

操作规范

(1)MongoDB数据库更新文档有两种实现方式—文档替换和目标字段更新。既可以完整替换现有的文档,也可以使用更新操作符来修改某个字段。

使用操作符,例如$set操作符和$push操作符,无论原始的大小,可以更新文档里的指定字段。频繁文档更新的场景下,使用目标更新可以在序列化和传输数据上花费更少的时间,获得更好的性能。

(2)多文档更新,在默认情况下,只会更新匹配查询器的第一个文档。要更新所有的匹配文档,需要显式指定多文档更新模式--添加参数multi:true。

(3)在文档级别更新是原子性的,这意味着一条更新10个文档的语句可能在更新3个文档后由于某些原因失败。应用程序必须根据自己的策略来处理这些失败。

(4)update结合upsert可以用来处理,当文档存在时更新,文档不存在时插入。如果查询选择器匹配,更新就正常执行;如果没有匹配的文档,就会插入新的文档。新文档的字段是查询选择器和目标更新文档的逻辑合并。

(5)复制集的数据安全及写策略,Write Concern 用于控制写入安全的级别。

Write Concern 是一个性能和数据一致性的权衡,应根据业务场景进行设定。对于强一致性场景,建议w>1或者等于majority。

(6)聚合框架是MongoDB的高级查询语言,它允许通过转换和合并由多个文档中的数据来生成新的单个文档里不存在的文档信息。可以把MongoDB的聚合框架等价于SQL的Group By 语句。

(7)在聚合框架中,$project操作符允许过滤传递给管道下一个阶段的字段。限制每个文档传递的大小,可以改善性能,尤其是在处理大文档且只需要每个文档一部分数据的场景下。

c++两个文档匹配数据_MongoDB 数据库的命名、设计规范相关推荐

  1. c++两个文档匹配数据_《搜索和推荐中的深度匹配》——1.2 搜索和推荐中匹配统一性...

    Garcia-Molina等[1]指出,搜索和推荐中的根本问题是识别满足用户信息需求的信息对象.还表明搜索(信息检索)和推荐(信息过滤)是同一枚硬币的两个方面,具有很强的联系和相似性[2].图1.1 ...

  2. 如何计算两个文档的相似度(一)

    下面的内容转自我爱自然语言处理博客,感谢博主,学到很多东西. 原文链接:http://www.52nlp.cn/%E5%A6%82%E4%BD%95%E8%AE%A1%E7%AE%97%E4%B8%A ...

  3. 复旦大学张奇组:对话摘要数据不足?对话数据、文档摘要数据,我全都要!...

    ©PaperWeekly 原创 · 作者 | 刘兴贤 学校 | 北京邮电大学硕士生 研究方向 | 自然语言处理 这篇文章发表在 EMNLP 2021,是复旦大学张奇老师组的工作.本文尝试解决的问题是对 ...

  4. python 合并word内容_python如何合并两个文档内容

    1.两个文档合并之前 2.合并两个文件的代码:file1 = open("name,tel.txt", "rb") file2 = open("nam ...

  5. Git提交到多个远程仓库(多看两个文档)

    Git提交到多个远程仓库(多看两个文档) 一.总结 一句话总结: 二. Git提交到多个远程仓库(多看两个文档) 有两种做法,先看第一种 一.通过命令行进行操作 例如我有下面两个仓库: Mybatis ...

  6. 比较两个文档的相似程度_您的文档对读者的友好程度如何?

    比较两个文档的相似程度 有成就的技术作家所要做的首要任务是为观众写作. 这个任务听起来很简单,但是当我想到世界各地的人们时,我想知道:他们能阅读我们的文档吗? 可读性已经研究了多年,接下来是对研究成果 ...

  7. 团队合作开发的两种文档工具

    前言 团队中,需要从需求分析开始确定,一直到项目的开发完成,中间要经历各种事情,需要各种任务来维持,一直到合作开发完成,所以需要一个团队协作查看的任务工具.那么这里推荐的有两种,trello,和tea ...

  8. mongoDb内嵌文档的数据查询

    导读 本文档主要讲述在内嵌文档中数据的筛选,内容如下 - 获取内嵌文档某特定数据 - 获取多个内嵌文档的某特定数据 - 获取多层级内嵌文档中的某特定数据 - 获取内嵌文件特定数据,并利用排序和分页筛选 ...

  9. Computer:成功解决在WPS中合并论文中两个文档(比如将另一个封皮的文档合并在当前文档当中)

    Computer:成功解决在WPS中合并两个文档(比如将另一个封皮的文档合并在当前文档当中) 目录 解决问题 解决方法 解决问题 经常在写论文的时候,需要这样的一个场景,在WPS中合并两个文档,比如将 ...

  10. 使用python代码区分两个文档的差异,并将差异内容输出

    使用 python 代码来区分两个文档的差异,并将差异内容输出,可以使用 difflib 库. 首先,需要安装 difflib 库,可以使用以下命令安装: pipinstall difflib 然后, ...

最新文章

  1. 【译】OpenDaylight控制器:YANG Schema和Model
  2. python不断刷新网页_python使用多线程不断刷新网页的方法
  3. 【错误记录】Flutter 使用 MediaQuery 适配全面屏报错 ( No MediaQuery widget ancestor found. )
  4. Java 中 StringBuilder 在高性能用法总结
  5. eDrawings Pro 2020中文版
  6. Linux信号量之内核信号量
  7. POJ3485 区间问题
  8. JAVA单例模式 关于延迟加载问题
  9. 简单的网站项目开发流程 .
  10. mysql 拼接字符串查询
  11. 友盟分享——微信、腾讯微博、新浪微博分享失败原因分析
  12. 2021年茶艺师(中级)考试及茶艺师(中级)复审模拟考试
  13. js月份的计算公式_JavaScript getMonth() 方法
  14. sql server导入备份文件
  15. 情感分析textblob--英文分析
  16. 有关H5第二章排列页面内容介绍
  17. 函数模板案例—选择排序
  18. 基于JavaWeb的学生考勤系统
  19. P4 程序设计语法学习
  20. 华为荣耀3x G750-T01 Root操作

热门文章

  1. Linux内存管理:Linux 可加载内核模块剖析:2.6 内核透视图
  2. SEO内容为王之如何创造伪原创
  3. css引用与html语义化
  4. HtmlUnitDriver 网页内容动态抓取
  5. centos启动提示unexpected inconsistency RUN fsck MANUALLY
  6. iOS之正则表达式的使用
  7. MFC之添加PNG,JPG图片
  8. Xamarin开发Android时Visual Studio 2012没有智能提示解决办法
  9. 爬虫_抓取京东手机图片
  10. k-近邻算法进行回归拟合