民工哥MongoDB教程:MD数据库设计开发规范
MongoDB是非关系型数据库的典型代表。 DB-Engines Ranking 数据显示,MongoDB 在过去几年一直是 NoSQL 领域的领导者。 MongoDB是一个专为快速开发互联网应用而设计的数据库系统。其数据模型和持久化策略专为高读/写性能而设计,并且可以灵活扩展。
公司目前使用MongoDB的主要场景包括仓库(原材料进出、货物进出、货架与货架上货物的变化、与其他系统平台交互消息等)、物流配送。 (订单物流信息、配送信息、地理位置信息等)、日志中心(系统应用及APP日志信息、调用依赖信息等)、产品中心(产品数据、推送信息等)、运维管理平台(保存变更信息采集等)等由于 MongoDB 的普及和使用迅速增长,编写本文档的目标是标准化其使用、易于管理和提高性能。
命名规则
mongoDB版本选择:新安装的数据库默认使用MonGoDB 3.X社区版。建议3.2.10+
数据库设计规范 数据库名称可以是任意满足以下条件的UTF-8字符串:
- (1) 不得使用“_”以外的特殊字符;
- (2) 不得包含“(空格)、.、$、/ 和(零个字符);
- (3) 必须小写;
- (4) 最多 30 个字符。
- ( 5 ) 禁止使用以字母开头的数字 库名
整个命名规则必须是满足以下条件的 UTF-8 字符串
- (1) 整个名称不能为空字符串 "" ;不得使用且禁止使用“_”以外的特殊字符 以数字开头的名称;
- (2) 整个名称不得以“system.”开头,“system.”是为系统集合保留的前缀。例如,整个system.users存储数据库中的用户信息,整个system.users存储数据库中的用户信息,数据库中所有信息的命名空间;
- (3) 用户创建的集合名称不能包含保留字符。如果不想访问系统创建的集合,它们一定不能出现在名称中
- (4)集合名称应尽可能简短、清晰 全部使用小写字母
字段命名规范
- (1) 字段不得包含(空字符)
- (2) 禁止以数字开头的字段名称;
- (3) 名称不能以字母“”开头 字段名称中不能出现除“”以外的特殊字符;
- (4) 字段引用必须使用全名+引用字段的名称。比如user_info集合中,引用了整个用户的key ID,以user_id作为key名;
- (5) 仅在查找参考文献时,字段中包含的整个名称的第一个字母必须大写,其余小写。
- (6) 如果字段较大,应尽可能压缩存储。
- (7) 如果字段较大,成为查询条件,例如很长的URL列表,则转换为md5并存储
- (8) _id值自定义不可用。
数据库设计规范
合理的容量规划和数据库级切片在创建新数据库时,需要提前进行容量规划。 DB池的数量、存储容量、QPS等应该放在现有的集群中或者在新创建的集群中实现。 。
避免将所有馆藏放在同一个数据库中,导致一个库中馆藏过多;
禁止公司使用id字段;企业避免在 id 字段中写入自定义业务数据:因为 MongoDB 的默认字段 Jd 这是一个类似于 Mysql InnoDB 表的主键的主键。如果一家公司写入无序数据(例如uuid/md5),那么整个本身就是一棵B+树。内存数据结构大幅调整,保证树平衡;写入数据成本高,容易导致写入性能低;
MongoDB 数据区分大小写。如果公司不区分大小写,建议省略大小写,以保证数据检索效率。 数据查询*mongo 区分大小写。例如,查询条件{f, "aA"}无法匹配字段"aa", "AA", "Aa"
。有些公司需要忽略尺寸,定期进行处理{f:aa/}
。虽然实现了忽略大小功能,但是查询效率很低,而且很消耗CPU资源。为了满足这种类型的需求,我们希望使大写(或小写)变得多余,以满足与规模无关的企业的搜索需求。例如,对于f场冗余tupper字段,存储字段内容为大写{f_upper."AA'}
压缩存储高频大字段:很多高频请求,当有较大的字段数据,返回(比如超过10KB),当QPS增大时,很容易占满MongoDB服务器的网络带宽或者写入频率较高,导致导出的oplog较大,频率如此之高而大数据建议在业务层进行压缩然后存储在MongoDB中。
存储ObjectId时,存储为ObjectId,不能存储为字符串类型;原因:
- 首先,方便查询(字符串和ObjectId不能重叠)
- 其次,ObjectId包含有用的信息,例如可以通过输入的时间戳查出创建日期;
- 第三,字符串表示的ObjectId占用两倍的磁盘空间;
索引设计规范
- (1) MongoDB索引仅支持1000个以内的字段。如果你保存的数据长度超过1000,则不会被索引
- (2)索引名称的长度不能太长;命名方式:idx_字段名;建议组合索引包含任何太长的字段名称。字段名称可以缩写。
- (3)唯一索引命名规范:uniq_field name,应尽量综合评估查询场景,尽可能将单列索引合并为复合索引,以减少数量;
- (4)索引越多,添加或更改记录会让mongodb变慢。
- (5)索引创建必须在后台创建,避免阻塞正常的DML和业务查询。 db.works.createIndex({a:1,b:1},{"name":'idx_field name'},{background:true}) (6) 禁止在数组字段上创建索引;
- ( 7)创建复合索引时,应评估索引中包含的字段,并尝试将选择性高的字段(具有许多唯一值的数据)放在聚合索引的前面;
- (8) 业务发展尽量做到最好 检查你的程序的性能,并通过解释查看执行计划();
- (9) 禁用冗余索引。例如,索引
idx_account_sName_createTime {"account" : 1,"sName" : 1"createTime" : -1}
和索引idx_konto:idx_account:idx_account {"1} 是多余的并且索引可以删除
idx_account
索引。
查询规范
- (1)无论查询语句是否使用索引,查询条件的key或者排序条件的key都必须有索引(数据量小的集合除外);
- (2)使用limit()限制返回结果集的大小,以减少数据库服务器的资源消耗和网络传输的数据量;
- (3) 只询问使用过的字段,而不询问所有字段;尽量不要让数组字段成为查询条件;
- (4) 在没有任何查询条件、警告或错误的情况下执行remove()操作;
- (5)查询中的一些运算符可能会导致性能不佳,如ne,,exists,or,$where在业务中不宜使用;
- (6)MongoDB的复合索引使用策略遵循“最左原则”,倾向于使用覆盖索引,查询语句对应复合索引字段的顺序;
- (7) 如果需要,使用hint()强制进行索引查询;
- (8) 更新操作时,请先查询后更新。通过更新主键可以提高更新的有效性;
应用程序的连接配置已正确设置为分离读取和写入。减轻主节点的压力,提高集群的可扩展性:
- (1)Mongo客户端决定客户端读取路由规则。通过属性的只读首选项设置进行查询。
- (2) Mongo客户端默认将所有请求转发到主节点。然而,许多应用程序的只读业务连续性较低(接受秒级同步延迟)。只读请求可以路由到子节点。结。 MongoDB正常复制同步延迟在1秒以内。
- (3)如果公司有只读查询,对数据一致性要求不高(比如最坏情况延迟60秒),建议程序的只读优先属性驱动程序设置为 SecondPreferred。
Mongo 客户端只读首选项支持 5 种模式。
一把好扳手的要素
一把好的扳手必须具备以下特点:
- 1.密钥分布足够离散(足够基数)
- 2。写入请求均匀分布(均匀分布写入)
- 3. 尽量避免分散-聚集请求(定向读取)。 MongoDB 的内部机制确保每个副本集(RS)包含相同数量的块。
分片键的选择决定了三个重要的方面:
读写的分布。最重要的一点是读写的分布
如果你总是写到一台机器上,那台机器就会成为写瓶颈,你的集群的写性能会下降。集群中有多少个节点并不重要,因为所有写入都发生在一个地方。因此,您不应该使用单调递增的 _id 作为分片键或迫使您不断向最后一个副本集添加数据的时间戳。
同样,如果你的读操作总是在同一个副本集中,你最好祈祷你的任务在机器的内存中。在副本集之间拆分读取请求可以使工作数据集的大小随分片数量线性缩放。这样,就可以在每台机器的内存和磁盘之间均匀分配负载压力。
数据块大小
第二个是数据块大小。 MongoDB 可以将大数据块分割成更小的数据块,但这只有在分片键不同的情况下才会发生。如果您有大量的数据文档都使用相同的分片键,那么您将获得相应的巨大数据块。大块是不好的,不仅因为它们会导致数据分布不均匀,而且还因为如果块大小超过某个值,则无法在分片之间移动它。
每个查询命中的分片数量
最后一点,如果能够保证大多数查询请求命中尽可能少的分片,那就最好了。对于一个查询请求,其延迟直接由命中最慢的服务器的延迟决定;因此,命中的分片越少,理论上查询速度就越快。这不是一个硬性规定,但如果能充分考虑到它应该会很有帮助。由于分片上数据块的分布仅大致遵循分片键的顺序,因此这并不严格执行。
多种密钥共享策略
Hash ID 可以使用数据文档的_id哈希作为分片键
读写都可以均匀分布,保证每个硬文档有不同的键值,所以数据块可以非常详细。多文档查询命中所有分片。
共享密钥增加
数据文件移动小(优点)随着数据文件大小的增加,写插入的IO总是放在最后一个分片上,导致最后一个分片写入热点。同时,随着最后一段数据量的增加,继续向前面几段过渡。
随机共享密钥
数据均匀分布,输入写入IO均匀分布在多个分片上。 (优点)查询多个文档肯定会命中所有碎片;大量的随机IO会压垮磁盘。
混合键
为避免出现大块,建议使用组合键并添加_id
以进行澄清。 {keyname: 1, _id: 1}
基本思想是:键名可以是经常被问到的、基数尽可能大的字段;字段 _id
可以有许多不同的值。对于Mongodb共享来说,这种策略适合大多数业务场景;如果你确实找不到像键名这样的东西,那么 hash _s。 来源:https://www.lsjlt.com/news/47351.html
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。