论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com
»
论坛
›
软件与程序人生
›
后端开发
›
.Net
›
MongoDB - 模式设计
MongoDB - 模式设计
欢乐狗
论坛元老
|
2022-12-27 00:20:47
|
显示全部楼层
|
阅读模式
楼主
主题
1018
|
帖子
1018
|
积分
3054
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
注意事项
模式设计,即在文档中表示数据的方式,对于数据表示来说时非常关键的。
为 MongoDB 做模式设计时,在性能、可伸缩性和简单性方面是重中之重,也需要考虑一些特别的注意事项。
限制条件
与常见的 SQL 相比而言,MongoDB 有自己的限制条件:
文档最大限制为 16M 大小
从磁盘读写完整文档
更新会重写整个文档
在文档级别进行原子更新
访问模式
设计模式时最需要关注的就是数据库的读操作,在数据库运行过程中,应尽量减少查询的数量,这就需要在设计时确保一起查询的数据存储在同一个文档中。
其实,就是考虑是否是否可以将动态(读/写)数据和静态(主要是读)数据分离开,如未经常使用的数据应该移到不同的集合中。
在进行模式设计时,提高最常见查询的优先级会获得最佳的性能。
关系类型
数据之间的关系影响着文档之间应该是内嵌还是引用。
比如说,需要弄清楚如何在不执行其他查询的情况下引用文档,以及当关系发生变化时需要更新多少文档。
关系基数对于文档之间的关系非常重要,如一对一、一对多、多对多、一对百万、多对百万等等关系基础,影响的程度差距非常大,应选取最佳格式去做建模。
在关系基数的基础上,还需关注访问的情况、重要数据更新与读取的比例,这些充分考虑之后,将有助于确定应采用内嵌文档还是引用文档。
范式化和反范式化
基本概念
通常来说,多文档之间的关系可以使用反范式化(内嵌)或范式化(引用)。
范式化是指在文档中引用外部数据的标识,同一份数据只存在一个地方。
在查询时,查询完整的数据需要做 JOIN 的操作,需要查询多次才可能获取到所需内容;但是在更改时仅需修改一处地方,不需要担心破坏数据的完整性。
反范式化是指将外部数据复制一份存储在文档中,也就是说同一份数据存在多处地方。
在查询时,只需查询一次即可得到所需内容,查询效率比较可观;而在更改时,需要更新多处地方,可能会出现数据不一致的情况,不能保证完整性。
范式化选择
决定何时采用范式化以及何时采用反范式化是比较困难的:通常,范式化的写入速度更快,而反范式化的读取速度更快。
通过判断以下因素可决策选择使用范式化还是反范式化:
更适合范式化更适合反范式化较大子文档较小子文档数据经常变更数据不经常变更数据要强一致数据最终一致即可文档数据大幅增加文档数据小幅增加数据通常不包含在结果中数据通常需要执行二次查询才能获得快速写入快速读取
模型设计小技巧
指导原则
通常来说,具有类似模式的文档应该保存在同一个集合中。
对于集合来说,需要考虑的一个大问题是锁机制(每个文档都有一个读/写锁)和存储。
当使用 --directoryperdb 选项时,每个数据库都可以保留在自己的目录中,这允许你将不同的数据库挂载到不同的卷中。
同一个应用程序连接的数据库可以根据业务进行划分,也许可以将高价值的业务数据存储在 SSD 上,或者是使用 RAID10 进行存储,而低价值的数据可以存储在 RAID0 上。
删除旧数据
有些数据只在短时间内比较重要,过了这段时间,保存这些数据只是再浪费存储空间。
删除旧数据有 3 种常见的方式:使用固定集合、使用 TTL 索引、使用多个集合。
最简单的方式是使用固定集合:将集合大小设置成一个较大的值,并让旧数据从固定集合的末尾被“删除”。
第二种方式是使用 TTL 集合:TTL 集合可以更精确地控制删除文档的时间,但其在写入量过大的集合中操作速度不够快。
最后一种方式是使用多个集合:例如每个月的文档都单独使用一个集合。
一致性管理
MongoDB 支持多种一致性级别,从总是能够读取自己所写的数据到读取不确定的旧数据。
其内部实现是服务器端为每一个数据库连接都维护了请求队列,同一个连接发来的请求都会被添加到队列的末尾,连接中的任何后续请求都将依次得到处理。
这个管理方式涉及到多个客户端连接会出现并发问题,在一个连接中插入文档后,在另一个连接的后续查询却不一定会返回这个文档(实际上已经插入成功)。
同样的一致性问题在 MongoDB 拥有副本集时也会出现,副本节点的数据与主节点的数据总是会有时间差,高并发的请求同样存在读取到旧数据的风险。
MongoDB 提供了 readConcern 选项来控制被读取数据的一致性和隔离性。它通常与 writerConcern 组合使用,以控制为应用程序提供的一致性和可用性保证:
如果 readConcern=local,从当前实例查询并返回结果,不能保证数据已经写入大多数副本集成员。默认在主库读,如果本次读取使用了 causally consistent 则在从库读。
如果 readConcern=available,从当前实例查询并返回结果,不能保证数据已经写入大多数副本集成员。默认在从库读,并且此选项与 causally consistent 不能同时使用。
如果 readConcern=majority,查询结果返回被副本集的大多数成员确认的数据,读操作返回的文档是持久化的。前提是 MongoDB 必须是 WiredTiger 存储引擎。
如果 readConcern=linearizable,查询可能会等待并发执行的写操作传播到大多数副本集成员,然后再返回结果。
如果 readConcern=snapshot,这是适用于多文档事务中的操作,通常情况下使用较少。
模式迁移
随着应用程序的增长和需求的变化,数据库模式也可能需要随之增长和改变。理想情况下,如果可以的话,应该考虑使用文档版本控制模式。
最简单的方式是根据应用程序的需要改进数据库模式,以确保应用程序支持所有的旧版模式。但是这种方式可能会导致混乱,特别是当不同版本的模式存在冲突时。
为了以一种更结构化的方式处理不断变化的需求,可以在每个文档中包含一个 version 字段,并使用它来确定应用程序将接受的文档结构。
最后一种方式是在模式变更时迁移所有数据。但这通常不是一个好主意:会给系统带来压力,还必须确保所有文档都被更新成功。
模式管理
MongoDB 3.2 引入了模式验证,其可以在更新和插入操作期间对数据进行验证。
MongoDB 3.6 又通过 $jsonSchema 运算符添加了 JSON 模式验证,现在这是 MongoDB 中所有模式验证的推荐方法。
只有当文档被更改时,验证功能才会检查这些文档,并且此功能是每个集合都需要单独配置的。
要向现有集合添加验证功能,可以在 collMod 命令中使用 validator 选项。在使用 db.createCollection() 时,可以通过指定 validator 选项将验证添加到新集合中。
MongoDB 还提供了两个额外的选项:
validationLevel: 决定了在更新过程中验证规则对现有文档检查的严格程度
validationAction: 决定了是应该在发生错误时拒绝请求,还是允许请求并发出警告
当然,更详细的相关内容可以查看
官方文档
。
编写代码来处理数据完整性问题
为保证 MongoDB 数据的完整性,有可能需要在应用程序中增加必要的逻辑代码进行处理,也需要增加定时任务来保持数据的一致性。
有可能需要有以下的任务:
一致性修复程序:检查计算和重复数据以确保每个人都具有一致的值
预填充器:创建将来需要的文档
聚合:保持内联聚合为最新
架构检查器:确保当前使用的文档集都具有一组字段,可以自动更正它们
定时备份:定期锁定和转储数据库
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
欢乐狗
论坛元老
这个人很懒什么都没写!
楼主热帖
C# 读写文件从用户态切到内核态,到底 ...
LeetCode刷题100道,让你滚瓜烂熟拿下S ...
我的 Java 学习&面试网站又又又升级了 ...
SQL server 2008 r2 安装教程
不到一周我开发出了属于自己的知识共享 ...
基于梯度优化的混沌PSO算法matlab仿真 ...
x64dbg 配置插件SDK开发环境
dfs学习笔记
Spring Boot 多数据源配置
SAP集成技术(十一)SAP混合集成平台 ...
标签云
AI
运维
CIO
存储
服务器
浏览过的版块
容器及微服务
MES
SQL-Server
网络安全
DevOps与敏捷开发
云原生
IOS
物联网
虚拟化与私有云
快速回复
返回顶部
返回列表