1.库设计规范
-
数据库命名规范:db_xxxx
-
库名全部小写,尽量不要使用任何_以外的特殊字符,尽量使用数字打头的库名,如:123_abc;
说明:库以文件夹的形式存在,使用特殊字符或其它不规范的命名方式会导致命名混乱
-
数据库名称最多为 64 个字符。
-
在创建新的库前应尽量评估该库的体积、QPS等,提前与DBA讨论是应该新建一个库还是专门为该库创建一个新的集群。
2.集合设计规范
-
集合名全部小写,禁止使用任何_以外的特殊字符,禁止使用数字打头的集合名,如:123_abc,禁止system打头; system是系统集合前缀;
-
集合名称最多为64字符;
-
一个库中写入较大的集合会影响其它集合的读写性能,如果业务比较繁忙的集合在一个DB中,建议最多80个集合,同时也要考虑磁盘I/O的性能;
-
如果评估单集合数据量较大,可以将一个大表拆分为多个小表,然后将每一个小表存放在独立的库中或者sharding分表;
-
MongoDB的集合拥有”自动清理过期数据”的功能,只需在该集合中文档的时间字段增加一个TTL索引即可实现该功能,但需要注意的是该字段的类型则必须是mongoDate(),一定要结合实际业务设计是否需要;
-
设计轮询集合—集合是否设计为Capped限制集,一定要结合实际业务设计是否需要。
3.创建集合规则
不同的业务场景是可以使用不同的配置;
db.createCollection("logs",
{ "storageEngine": { "wiredTiger":
{ "configString": "internal_page_max=16KB,
leaf_page_max=16KB,leaf_value_max=8KB,os_cache_max=1GB"
}
}
})
-
如果是读多写少的表在创建时我们可以尽量将 page size 设置的比较小 ,比如 16KB,如果表数据量不大 (“internal_page_max=16KB,leaf_page_max=16KB,leaf_value_max=8KB,os_cache_max=1GB”)
-
如果这个读多写少的表数据量比较大,可以为其设置一个压缩算法,例如:”block_compressor=zlib, internal_page_max=16KB,leaf_page_max=16KB,leaf_value_max=8KB”
-
注意:该zlib压缩算法尽量不要使用,对cpu消耗特别大,如果使用snapp消耗20% cpu,而且使用zlib能消耗90%cpu,甚至100%
4.文档设计规范
-
集合中的 key尽量不要使用任何 “_”(下划线)以外的特殊字符。
-
尽量将同样类型的文档存放在一个集合中,将不同类型的文档分散在不同的集合中;相同类型的文档能够大幅度提高索引利用率,如果文档混杂存放则可能会出现查询经常需要全表扫描的情况、
-
尽可能不要使用
_id
,如:向_id
中写入自定义内容。说明:MongoDB的表与InnoDB相似,都是索引组织表,数据内容跟在主键后,而
_id
是MongoDB中的默认主键,一旦_id
的值为非自增,当数据量达到一定程度之后,每一次写入都可能导致主键的二叉树大幅度调整,这将是一个代价极大的写入,所以写入就会随着数据量的增大而下降,所以一定不要在_id
中写入自定义的内容。 -
尽量不要让数组字段成为查询条件。
-
如果字段较大,应尽量压缩存放。
不要存放太长的字符串,如果这个字段为查询条件,那么确保该字段的值不超过1KB;MongoDB的索引仅支持1K以内的字段,如果你存入的数据长度超过1K,那么它将无法被索引。
-
尽量存放统一了大小写后的数据 。
-
如果评估单集合数据量较大,可以将一个大表拆分为多个小表,然后将每一个小表存放在独立的库中或者sharding分表。
5.索引设计规范
-
MongoDB 的组合索引使用策略与 MySQL 一致,遵循”最左原则”;
-
索引名称长度不要超过 128 字符;
-
应尽量综合评估查询场景,通过评估尽可能的将单列索引并入组合索引以降低所以数量,结合1,2点;
-
优先使用覆盖索引;
-
创建组合索引的时候,应评估索引中包含的字段,尽量将数据基数大(唯一值多的数据)的字段放在组合索引的前面;
-
MongoDB 支持 TTL 索引,该索引能够按你的需要自动删除XXX秒之前的数据并会尽量选择在业务低峰期执行删除操作;看业务是否需要这一类型索引;
-
在数据量较大的时候,MongoDB 索引的创建是一个缓慢的过程,所以应当在上线前或数据量变得很大前尽量评估,按需创建会用到的索引;
6.分片设计规范
在MongoDB分片集群中,分片的设计规范是非常重要的,它可以影响集群的性能、可扩展性和可靠性。以下是一些常见的MongoDB分片设计规范:
-
分片键的选择:分片键是用于分片集合的字段或字段组合。应该选择具有高选择性(即有区分度)的字段作为分片键,例如访问频率较高的字段或具有高度唯一性的字段。应该避免使用随机值或低选择性的字段作为分片键,因为这会导致数据分布不均衡,影响集群性能和可扩展性。
-
分片键的数据类型:分片键的数据类型应该选择适合应用程序和数据的数据类型。例如,如果查询经常使用时间戳,则可以将时间戳作为分片键,并选择适合的日期时间数据类型。
-
分片键的范围:分片键的范围应该选择适当的范围,以便在数据分片时能够均匀分布。例如,如果使用范围查询,则应该选择具有大范围的分片键,以便在多个分片上均匀分布数据。
-
分片集群的节点数:分片集群的节点数应该根据数据量、负载和可扩展性需求来选择。通常建议将分片集群的节点数设置为2的幂次方,例如2、4、8、16等,以便更好地管理和维护集群。
-
避免
_id
作为分片键 。_id
通常是有序的,不太符合分布广泛的要求。并且经常使用_id
作为查询条件,不利于分片。 -
分片的备份和恢复:在使用MongoDB分片集群时,应该定期备份和恢复数据,以保证数据的安全性和可靠性。可以使用MongoDB提供的备份和恢复工具或第三方工具来完成这些操作。
需要注意的是,在设计MongoDB分片集群时,应该根据具体的应用程序和MongoDB环境来选择合适的分片设计规范。在分片集群的运维和维护过程中,应该遵循MongoDB的最佳实践和规范,例如合理管理数据、监控集群性能和故障等。