前面介绍了、、、、、、、等相关的知识点。今天我将详细的为大家介绍 MongoDB 数据库开发设计规范相关知识,希望大家能够从中收获多多!如有帮助,请点在看、转发支持一波!!!
MongoDB 是非关系型数据库的典型代表,DB-Engines Ranking 数据显示,近年来,MongoDB 在 NoSQL 领域一直独占鳌头。MongoDB 是为快速开发互联网应用而设计的数据库系统,其数据模型和持久化策略就是为了构建高读/写的性能,并且可以方面的弹性拓展。
目前公司使用到的 MongoDB 的主要场景有 库存中心(原料出入库、商品出入库、商品上下架变动、与其它系统平台的交互报文等)、物流配送(订单的物流信息、配送信息、地理位置信息等)、日志中心(系统应用和APP的log信息、调用依赖信息等)、商品中心(商品数据、推送信息等)、运维管理平台(收集记录的变更信息等)等。随着MongoDB的普及和使用量的快速增长,为了规范使用,便于管理和获取更高的性能,整理此文档。更多关于 MongoDB 数据库的学习文章,请参阅:,本系列持续更新中。
命名规则
mongoDB 版本选择:默认新装数据库使用MonGoDB 3.X 社区版。建议3.2.10+
数据库设计规范数据库名可以是满足以下条件的任意UTF-8字符串:
集合命名规则必须满足下列条件的任意UTF-8字符串
字段命名规范数据库设计规范
合理容量规划和库级拆分创建新的数据库时,提前进行容量规划库的集合数,存储容量,QPS等, 是放在已有集群,还是新创 建集群部署。
避免把所有集合都放在同一个数据库,造成一个库中集合过多;
业务禁止使用id字段;业务避免向id字段写入自定义的业务数据:因MongoDB的 Jd字段默认是主键, 类似于Mysql InnoDB表的主键,如果业务写入无序数据(如uuid/md5),集合本身是B+ Tree,为保证树的平衡,会大副度调整内部存储数据结构;写入数据的代价很大,容易导致写入性能低;
MongoDB 数据是大小写敏感的,如业务不区分大小,建议冗余一个全部大写或小写字段,用于不区分大小写的数据检索效率*mongo中数据查询是大小写敏感的,例如{f,"aA"}的查询条件, 不能匹配字段为“aa”,“AA", “Aa” 值的文档。有的业务需忽略大小,需通过正则方式进行处理{f:aa/},虽实现忽略大小功能,但查询效率很低,同时很耗CPU资源。解决这类需求,希望冗余一个全大写(或小写)的字段,用于业务忽略大小的检索需求。例如对f字段冗余tupper字 段,存储字段内容全大写{f_upper."AA'}
对高频大字段进行压缩存储:很多高频的查询,如果存在返回较大字段数据(如10 KB以上),当QPS增加后很容易把MongoDB服务器网络带宽占满。或写入频次较高,会导数oplog实体很大。建议这类高频和较大的数据, 在业务层进行 压缩后,再存入MongoDB中。
ObjectId存储时,作为ObjectId存储,不可存成字符串类型;原因:
索引设计规范查询规范
应用程序连接配置合理设置读写分离,减少主节点压力,提高可集群可扩展性:
mongo客户端只读偏好支持5种模式
分片键规范好片键的要素
好的 shard key 应该拥有如下特性:
片键的选择决定了三个重要的方面:
读和写的分布其中最重要的一点是读和写的分布
如果你总是朝一台机器写,那么这台机器将会成为写瓶颈,则你的集群的写性能将会降低。这无关乎你的集群有多少个节点,因为所有的写操作都只在一个地方进行。因此,你不应该使用单调递增的_id或时间戳作为片键,这样将会导致你一直往最后一个副本集中添加数据。
相类似的是如果你的读操作一直都在同一个副本集上,那么你最好祈求你的任务能在机器内存所能承受的范围之内。通过副本集将读请求划分开能够使你的工作数据集大小随着分片数线性扩展。这样的话你能够将负载压力均分到各台机器的内存和磁盘之上。更多关于 MongoDB 数据库的学习文章,请参阅:,本系列持续更新中。
数据块的大小
其次是数据块的大小。MongoDB能够将大的数据块划分成更小的,但这种情况仅仅在片键不同的情况下发生。如果你有巨量的数据文档都使用了同样的片键,那么你相应的会得到巨大的数据块。出现巨大块是非常不好的,不仅仅因为它会导致数据的不平均分布,还因为一旦这个数据块的大小超过某个值,那么你就不能够在分片之间移动它了。
每个查询命中的分片数目
最后一点,如果能够保证大部分的查询请求都能够命中尽可能少的分片那就最好了。对于一个查询请求来说,其延迟直接取决于最慢的那个命中服务器的延迟;所以你命中的分片越少,那么理论上来说查询将会越快。这一点并不是硬性的规定,不过如果能够做到充分考虑那么应该是很有利的。因为数据块在分片上的分布仅仅是近似的遵循片键的顺序,而并不是严格的强制指定。
几种分片键的策略Hashed id 可以使用数据文档_id的哈希作为片键
读和写都能够平均分布,并且它能够保证每个文档都有不同的片键所以数据块能够很精细。对多个文档的查询必将命中所有的分片。
递增的sharding key
数据文件挪动小(优势)因为数据文件递增,所以会把insert的写IO永久放在最后一片上,造成最后一片的写热点。同时,随着最后一片的数据量增大,将不断的发生迁移至之前的片上。
随机的sharding key
数据分布均匀,insert的写IO均匀分布在多个片上。(优势)对多个文档的查询必将命中所有的分片;大量的随机IO,磁盘不堪重荷。
混合型key
为防止巨大块的产生,建议使用组合键,引入 _id 来细化。{keyname: 1, _id: 1}原则就是:keyname 可以是一个经常被查询的字段,尽可能基数较大;_id字段是有非常多不同的值可以供mongodb进行分割,这种策略适合大多业务情况;如果实在找不到keyname这样字段,那么就对_id进行Hashed吧。
更多关于 MongoDB 数据库的学习文章,请参阅:,本系列持续更新中。