MongoDB学习笔记:MongoDB 数据库的命名、设计规范

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

文档

设计约束

  • UTF-8 字符
  • 不能包含 \0 字符(空字符),这个字符标识建的结尾
  • . 和 $ 有特殊含义,需要避免
  • 区分大小写
  • 键不能重复
  • 键/值对有序

实践约束

  • 【强制】文档中的key禁止使用_以外的特殊字符
  • 【强制】key全部小写,多个单词可以下划线分割
  • 【强制】禁止使用数字打头的key
  • 【强制】禁止自定义_id(_id一般自增,使用无序id极有可能降低写入性能)
  • 【建议】相似类型文档放在一个集合中,能大幅提高索引利用率
  • 【建议】若业务上对于存放数据大小写不敏感,则使用全部大写/小写存放(或者增加一个统一了大小写写的辅助字段)。 使用忽略大小写的查询极其耗费性能
  • 【建议】不要存放太长的字符串

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

  • 【强制】禁止使用数字打头的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操作符允许过滤传递给管道下一个阶段的字段。限制每个文档传递的大小,可以改善性能,尤其是在处理大文档且只需要每个文档一部分数据的场景下。
 
 

MongoDB学习笔记:MongoDB 数据库的命名、设计规范的更多相关文章

  1. MongoDB学习笔记——MongoDB 连接配置

    MongoDB连接标准格式: mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[dat ...

  2. MongoDB学习笔记~MongoDB实体中的值对象

    回到目录 注意,这里说的值对象是指在MongoDB实体类中的,并不是DDD中的值对象,不过,两者也是联系,就是它是对类的补充,自己本身没有存在的价值,而在值对象中,也是不需要有主键Id的,这与DDD也 ...

  3. MongoDB 学习笔记(原创)

    MongoDB 学习笔记 mongodb 数据库 nosql 一.数据库的基本概念及操作 SQL术语/概念 MongoDB术语/概念 解释/说明 database database 数据库 table ...

  4. MongoDB学习笔记系列

    回到占占推荐博客索引 该来的总会来的,Ef,Redis,MVC甚至Sqlserver都有了自己的系列,MongoDB没有理由不去整理一下,这个系列都是平时在项目开发时总结出来的,希望可以为各位一些帮助 ...

  5. MongoDB学习笔记系列~目录

    MongoDB学习笔记~环境搭建 (2015-03-30 10:34) MongoDB学习笔记~MongoDBRepository仓储的实现 (2015-04-08 12:00) MongoDB学习笔 ...

  6. MongoDB学习笔记(2):数据库操作及CURD初步

    MongoDB学习笔记(2):数据库操作及CURD 数据库操作 创建数据库 首先MongoDB中数据库的创建和数据库的切换都是使用命令,USE DATABASE,如果要切换的数据库不存在则会进行创建, ...

  7. mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)

    最后更新时间:2017-07-13 11:10:49 原始文章链接:http://www.lovebxm.com/2017/07/13/mongodb_primer/ MongoDB - 简介 官网: ...

  8. MongoDB学习笔记(二)--Capped集合 && GridFS存储文件

    Capped集合                                                            Capped集合的大小是固定的,如果空间都被用完了,新添加的对象 ...

  9. PHP操作MongoDB学习笔记

    <?php/*** PHP操作MongoDB学习笔记*///*************************//**   连接MongoDB数据库  **////*************** ...

随机推荐

  1. 读取ini配置文件 及 UI对象库

    读取ini配置文件 配置项 读取API 写入API 实战:UI 对象库 读取ini配置文件 配置项 在每个 ini 配置文件中,配置数据会被分组(比如下述配置文件中的"config" ...

  2. 2021S软件工程——案例分析作业

    2021S软件工程--案例分析作业 18231169 黄思为 项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任建) 这个作业的要求在哪里 案例分析作业 我在这个课程的目标是 了解并熟悉 ...

  3. 1067 Sort with Swap(0, i)

    Given any permutation of the numbers {0, 1, 2,..., N−1}, it is easy to sort them in increasing order ...

  4. hdu 2841 Visible Trees(容斥)

    原文链接 There are many trees forming a m * n grid, the grid starts from (1,1). Farmer Sherlock is stand ...

  5. Django中的表单

    目录 表单 Django中的表单 用表单验证数据 自定义验证 表单 HTML中的表单是用来提交数据给服务器的,不管后台服务器用的是 Django  还是 PHP还是JSP还是其他语言.只要把 inpu ...

  6. URL分发器(视图层)

    目录 视图 URL映射 path函数 URL中传入参数 普通传入参数 变量形式传入参数 ​URL中包含另一个urls模块 URL命名.URL反转.应用命名空间 视图 视图一般都写在 app  的 vi ...

  7. Windows核心编程 第23章 结束处理程序

    第2 3章 结束处理程序 SEH(结构化异常处理) 使用 S E H的好处就是当你编写程序时,只需要关注程序要完成的任务. 如果在运行时发生什么错误,系统会发现并将发生的问题通知你.利用S E H,你 ...

  8. Windows中的用户和组以及用户密码处理

    目录 用户帐户 Windows 默认账户 Windows 内置用户账户 查看.创建和删除账户 组账户 内置组账户 组的查看.创建和删除 Windows中对用户密码的处理 LM-hash NTLM-ha ...

  9. 启动QQ时出现无法访问个人文件夹怎么决解

    找了一圈的百度,真正有用的. 在设置中进行修改. https://zhidao.baidu.com/question/2073820786837168348.html 打开设置的其中页面 你的IT管理 ...

  10. Eclipse的安装及相关配置

    一.Eclipse的下载 二.Eclipse的安装 三.Eclipse中相关配置 一.Eclipse的下载 Eclipse各版本下载地址 1.选择要下载的版本(我这里选择的4.14版) 2.选择与自己 ...