MongoDB学习笔记:MongoDB 数据库的命名、设计规范
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字节。
第二部分,设计规范。
数据库设计规范
- 数据库名约定为小写。
- 数据库名称不能包含除’_’以外的特殊字符,例如:/ \ . “ $。
- 数据库名称最多为64个字符。
- 数据库上线需经过DBA评审。
集合设计规范
- 集合名称约定为小写。
- 集合名称不能包含除‘’以外的特殊字符字符;集合名称禁止以system.开头。
- 集合名称的最大长度为64个字符,包括前缀的【database.】内容。
- 集合名称的命名规则和MySQL数据库表的命名规则相同。 a) 同一模块的集合尽可能使用相同的前缀名,集合名称尽可能表达用途。 b) 数据表 <模块标识><表标识> 例如:order_header , order_detail
c) 编码表 base_<模块标识><表标识> d) 日志表 log<模块标识><表标识> - 固定集合可以用于记录日志,其插入数据更快,可以实现在插入数据时,淘汰最早的数据。固定集合需要显式创建,指定Size的大小,还能够指定文档的数量。集合不管先达到哪一个限制,之后插入的新文档都会把最老的文档移出。
- 索引命名:idx<构成索引的字段名>。如果字段名字过长,可采用字段缩写。
文档设计规范
- Key的命名规范:不能以$开头;不能包含.(点号)。
- 文档中的_id键推荐使用默认值,禁止向_id中保存自定义的值。MongoDB文档中都会有一个“_id”键,默认是个ObjectID对象(标识符中包含时间戳、机器ID、进程ID和计数器)。MongoDB在指定_id与不指定_id插入时速度相差很大,指定_id会减慢插入的速率。
- 推荐使用短字段名。与关系型数据库不同,MongoDB集合中的每一个文档都需要存储字段名,长字段名会需要更多的存储空间。
- 禁止在同一个集合字段中存储多个数据类型的数据。
- 如若将日期类型选择为string,不同的日期格式的文档,不支持等值查询,不支持范围查询。创建一个测试集合product,分别向集合插入Date:”20180425″和Date:”2018-04-25″两笔数据。等值查询、范围查询($gte, $lte)只能查到日期格式相同的数据,都为一笔数据。
- MongoDB大小写敏感,如果字段无需大小写敏感,为了提高查询效率,应尽量在统一了大小写之后再插入到数据库中。
- MongoDB是文档型数据库,数据以BSON形式存储在文档中。MongoDB能够支持最大16 MB的文档大小。建议尽量不要存储大型对象,将文档控制在16 MB以内。
- 通过$size查询数组大小,但是$size运算符不使用索引和限制准确匹配(不能指定$Sized 范围)。因此,如果需要基于数组的大小执行查询,可以在文档设计中增加size属性。例如在商品评价中,其他人可以对评价进行投票。为了阻止用户多次投票和对有帮助的评论进行排序,所以,评价文档设计是:在一个数组字段(voter_ids)保存了所有评论用户的ID,而数组大小缓存在helpful_votes字段里。
- 分片键必须有索引,分片键大小限制为512byte,一旦集合已经分片,不可以直接修改分片键。不接受向已进行分片的collection上插入无分片键的文档,也不支持空值插入。
- 片键的设计原则:
a) 所有的插入、更新、删除将会均匀发送到集群的所有分片中。
b) 所有的查询将会在集群中的所有分片中均匀地分发。
c) 所有的更新或者删除操作将会只面向相关的分片,不会发送到一个没有存储被修改数据的分片上。
d) 一个查询将不会被发送到没有存储被查询数据的分片上。
连接规范
- 正确连接副本集,副本集提供了数据的保护、高可用和灾难恢复的机制。如果主节点宕机,其中一个从节点会自动提升为从节点。
- 合理控制连接池的大小,限制连接数资源,可通过Connection String URL中的maxPoolSize 参数来配置连接池大小。Mongod 的服务模型是每个网络连接由一个单独的线程来处理,每个线程配置了1MB 的栈空间,当网络连接数太多时,过多的线程会导致上下文切换开销变大,同时内存开销也会上涨。
- 复制集读选项。默认情况下,复制集的所有读请求都发到Primary,Driver可通过设置的Read Preference 来将读请求路由到其他的节点。
a) Primary:默认规则,所有读请求发到Primary。
b) PrimaryPreferred: Primary优先,如果Primary不可达,请求Secondary。
c) Secondary:所有的读请求都发到Secondary。
d) SecondaryPreferred:Secondary优先,当所有的Secondary不可达时,请求Primary。
e) Nearest:读请求发送到最近的可达节点上(通过ping探测得出最近的节点)。
操作规范
- MongoDB数据库更新文档有两种实现方式—文档替换和目标字段更新。既可以完整替换现有的文档,也可以使用更新操作符来修改某个字段。使用操作符,例如$set操作符和$push操作符,无论原始的大小,可以更新文档里的指定字段。频繁文档更新的场景下,使用目标更新可以在序列化和传输数据上花费更少的时间,获得更好的性能。
- 多文档更新,在默认情况下,只会更新匹配查询器的第一个文档。要更新所有的匹配文档,需要显式指定多文档更新模式–添加参数multi:true。
- 在文档级别更新是原子性的,这意味着一条更新10个文档的语句可能在更新3个文档后由于某些原因失败。应用程序必须根据自己的策略来处理这些失败。
- update结合upsert可以用来处理,当文档存在时更新,文档不存在时插入。如果查询选择器匹配,更新就正常执行;如果没有匹配的文档,就会插入新的文档。新文档的字段是查询选择器和目标更新文档的逻辑合并。
- 复制集的数据安全及写策略,Write Concern 用于控制写入安全的级别。Write Concern 是一个性能和数据一致性的权衡,应根据业务场景进行设定。对于强一致性场景,建议w>1或者等于majority。
- 聚合框架是MongoDB的高级查询语言,它允许通过转换和合并由多个文档中的数据来生成新的单个文档里不存在的文档信息。可以把MongoDB的聚合框架等价于SQL的Group By 语句。
- 在聚合框架中,$project操作符允许过滤传递给管道下一个阶段的字段。限制每个文档传递的大小,可以改善性能,尤其是在处理大文档且只需要每个文档一部分数据的场景下。
MongoDB学习笔记:MongoDB 数据库的命名、设计规范的更多相关文章
- MongoDB学习笔记——MongoDB 连接配置
MongoDB连接标准格式: mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[dat ...
- MongoDB学习笔记~MongoDB实体中的值对象
回到目录 注意,这里说的值对象是指在MongoDB实体类中的,并不是DDD中的值对象,不过,两者也是联系,就是它是对类的补充,自己本身没有存在的价值,而在值对象中,也是不需要有主键Id的,这与DDD也 ...
- MongoDB 学习笔记(原创)
MongoDB 学习笔记 mongodb 数据库 nosql 一.数据库的基本概念及操作 SQL术语/概念 MongoDB术语/概念 解释/说明 database database 数据库 table ...
- MongoDB学习笔记系列
回到占占推荐博客索引 该来的总会来的,Ef,Redis,MVC甚至Sqlserver都有了自己的系列,MongoDB没有理由不去整理一下,这个系列都是平时在项目开发时总结出来的,希望可以为各位一些帮助 ...
- MongoDB学习笔记系列~目录
MongoDB学习笔记~环境搭建 (2015-03-30 10:34) MongoDB学习笔记~MongoDBRepository仓储的实现 (2015-04-08 12:00) MongoDB学习笔 ...
- MongoDB学习笔记(2):数据库操作及CURD初步
MongoDB学习笔记(2):数据库操作及CURD 数据库操作 创建数据库 首先MongoDB中数据库的创建和数据库的切换都是使用命令,USE DATABASE,如果要切换的数据库不存在则会进行创建, ...
- mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)
最后更新时间:2017-07-13 11:10:49 原始文章链接:http://www.lovebxm.com/2017/07/13/mongodb_primer/ MongoDB - 简介 官网: ...
- MongoDB学习笔记(二)--Capped集合 && GridFS存储文件
Capped集合 Capped集合的大小是固定的,如果空间都被用完了,新添加的对象 ...
- PHP操作MongoDB学习笔记
<?php/*** PHP操作MongoDB学习笔记*///*************************//** 连接MongoDB数据库 **////*************** ...
随机推荐
- 整合Atomikos、Quartz、Postgresql的踩坑日记
前言 由于业务需要,在单体Spring Boot项目中需要引入分布式事务,来保证单体应用连接的多个数据源的事务统一. 而说到分布式事务,小伙伴们肯定会想到阿里的Seata,阿里Seata强大的AT模式 ...
- API文档大集合
[API文档大集合] sklearn API:http://sklearn.apachecn.org/cn/0.19.0/tutorial/index.html pandas API:http://p ...
- 记weblogic上传shell路径
0x01 前言 自从上次在渗透过程中发现了波weblogic CVE-2020-2551漏洞后面又对其进行了复现,后边看到exp里有个上传webshell的功能,但是由于不清楚weblogic这个路径 ...
- 多指灵巧手MoveIt!与Gazebo联合仿真框架搭建
至于为什么叫框架,一是因为灵巧手的3维模型没有按照基本的设计要求画,正常来说,设计机器人机构之前应该设计好机构需要多少个自由度/DOF,每个自由度是旋转/revolute类型还是滑移/prismati ...
- PowerShell-4.API调用以及DLL调用
PowerShell可以直接调用API,So...这东西完全和cmd不是一回事了... 调用API的时候几乎和C#一样(注意堆栈平衡): 调用MessageBox: $iii = Add-Type - ...
- Python爬虫之 正则表达式和re模块
什么是正则表达式: 通俗理解:按照一定的规则,从某个字符串中匹配出想要的数据.这个规则就是正则表达式.标准答案:https://baike.baidu.com/item/正则表达式/1700215?f ...
- Ubuntu Linux DNS服务器 BIND9配置文件命令介绍
BIND9配置方法 转载▼ 配置语法 named.conf acl 定义访问控制列表 controls 定义rndc命令使用的控制通道,若省略,则只允许经过rndc.key认证的127.0.0 ...
- Python技术栈性能测试工具Locust入门
Locust是一款Python技术栈的开源的性能测试工具.Locust直译为蝗虫,寓意着它能产生蝗虫般成千上万的并发用户: Locust并不小众,从它Github的Star数量就可见一斑: 截止文章写 ...
- 深入浅出带你玩转sqlilabs(四)-updatexml(),floor(),extractvalue()报错注入
SQL各种参数类型下的注入测试 数字型-sqlilabs less2 前面文章已演示过 字符型-sqlilabs less1 前面文章已演示过 搜索型-自写测试 如: www.test.com/ind ...
- 【JavaScript】Leetcode每日一题-移除元素
[JavaScript]Leetcode每日一题-移除元素 [题目描述] 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度. 不要使用 ...