MongoDB 数据建模
一、基本原则:
优先内嵌,其次引用 ---- 主子压缩成1个表
1:1、 1:n 强关联聚合(主子) 子数量不是特别多时直接用内嵌文档
m:n 使用reference ,关联表, 更新等要保证事务性
二、模型例子
1、电商建模: https://blog.csdn.net/wanght89/article/details/77197400
product和分类
{
slug:"wheel-barrow-9092",
sku:"9092",
name:"Extra Large Wheel Barrow",
description:"Heavy duty wheel barrow",
details:{
weight:47,
weight_unite:"1bs",
model_num:40392882,
manufacturer:"Acme",
color:"Green"
},
total_review:4,
average_review:4.5,
pricing:
{
retail:589700,
sale:489700
},
price_history:[
{
retail:529700,
sale:429700,
start:new Date(2010,4,1),
end:new Date(2010,4,8)
},
{
retail:529700,
sale:529700,
start:new Date(2010,4,9),
end:new Date(2010,4,16)
}
],
cateory_ids:[
new ObjectId("59884ee3b53fab2a8024b6ae"),
new ObjectId("59884ee3b53fab2a8024b6af")
],
main_cate_id:new ObjectId("59884ee3b53fab2a8024b6b1"),
tags:["tools","gardening","soil"]
}
order 订单
{
_id:new ObjectId("6a5b1476238d3b4dd5000001"),
user_id:new ObjectId("4a5b1476238d3b4dd5000001"),
state:"CART",
line_items:[{
_id:new ObjectId("4a5b1472134d3b4dd5000921"),
sku:"9092",
name:"Extra Large Wheel Barrow",
quantity:1,
pricing:{
retail:5897,
sale:4897,
}
},
{
_id:new ObjectId("4a5b1472134d3b4dd5000922"),
sku:"10027",
name:"Rubberized Work Glove,Block",
quantity:2,
pricing:{
retail:1499,
sale:1299,
}
}
],
shipping_address:{
street:"588 5th Street",
city:"Brooklyn",
state:"NY",
zip:11215
},
sub_total:6196
}
用户
{
_id:new ObjectId("4a5b1476238d3b4dd5000001"),
email:"kylebanker@gl.com",
first_name:"Kyle",
last_name:"Banker",
hashed_password:"bd1cfa194c3a603e7186780824b04419",
address:[
{ name:"home",
street:"588 5th Street",
city:"Brooklyn",
state:"NY",
zip:10010
},
{
name:"work",
street:"1 E.23rd Street",
city:"New York",
state:"NY",
zip:10010
}
],
payment_methods:[{
name:"VISA",
last_four:2127,
crypted:"43f6baldfda6b8106dc7",
expiration_date:new Date(2014,4)
}
]
}
评论
{
_id:new ObjectId("4c4b1476238d3b4dd5000041"),
product_id:new ObjectId("59884b76b53fab2a8024b6ad"),
date:new Date(2010,5,7),
title:"Amazing",
text:"Has a squeaky wheel,but still a darn good wheel barrow",
rating:4,
user_id:new ObjectId("4a5b1476238d3b4dd5000001"),
user_name:"dgreenthumb",
helpful_votes:3,
voter_ids:[
new ObjectId("59884b76b53fab2a8024b600"),
new ObjectId("59884b76b53fab2a8024b601"),
new ObjectId("59884b76b53fab2a8024b602")
}
}
购物车 = items
2、博客:https://www.qikegu.com/docs/3277
1>user
2>article= comments+ tags + categorys + user
3、社交
关注: m:n 都比较大时,使用单独的关联表
朋友圈: 每个人存储1份url 使用bucket可以控制数组的大小
iot数据采集:可以采用分桶的方式提高性能(每一个小时的聚合到一个文档里,并做好聚合) 异构的优势
4、电影统计
actor
movie = reviews + 。。。
三、书籍和资料
https://www.lagou.com/lgeduarticle/28746.html
设计模式范式
https://cloud.tencent.com/developer/article/1405900
A Complete Methodology of Data Modeling for MongoDB
Advanced Schema Design Patterns, Daniel Coupal
<MongoDB应用设计模式>
四、常见问题,建模范式(访问模式需求,决定架构设计)
1、多态 每个document字段都不同,
适合场景:单一视图、内容管理、移动应用、产品目录
2、属性模式(Attribute Pattern)-- 把固定的列,变成kv的动态列
UserDefinedField https://martinfowler.com/bliki/UserDefinedField.html
动态属性子表或者固定的冗余列(分散到每个单据,集中有个配置的地方)
问题:部分文档有公共的属性,或者只关注部分属性
电影在多个国家有多个发行日期,怎么查询发行日期?
方案:统一到1个数组字段,里面obj是kv的结构
{
title: "Star Wars",
director: "George Lucas",
...
release_US: ISODate("1977-05-20T01:00:00+01:00"),
release_France: ISODate("1977-10-19T01:00:00+01:00"),
release_Italy: ISODate("1977-10-20T01:00:00+01:00"),
release_UK: ISODate("1977-12-27T01:00:00+01:00"),
...
}
{
title: "Star Wars",
director: "George Lucas",
...
releases: [
{
location: "USA",
date: ISODate("1977-05-20T01:00:00+01:00")
},
{
location: "France",
date: ISODate("1977-10-19T01:00:00+01:00")
},
{
location: "Italy",
date: ISODate("1977-10-20T01:00:00+01:00")
},
{
location: "UK",
date: ISODate("1977-12-27T01:00:00+01:00")
},
...
],
...
}
索引:{ "releases.location": 1, "releases.date": 1}
"specs": [
{ k: "volume", v: "500", u: "ml" },
{ k: "volume", v: "12", u: "ounces" }
]
{"specks.k": 1, "specs.v": 1, "specs.u": 1}
3、桶模式 定时分组+预先统计,减少索引带来的内存消耗
{
sensor_id: 12345,
timestamp: ISODate("2019-01-31T10:00:00.000Z"),
temperature: 40
}
{
sensor_id: 12345,
timestamp: ISODate("2019-01-31T10:01:00.000Z"),
temperature: 40
}
{
sensor_id: 12345,
timestamp: ISODate("2019-01-31T10:02:00.000Z"),
temperature: 41
}
{
sensor_id: 12345,
// 每个小时统计1次
start_date: ISODate("2019-01-31T10:00:00.000Z"),
end_date: ISODate("2019-01-31T10:59:59.000Z"),
measurements: [
{
timestamp: ISODate("2019-01-31T10:00:00.000Z"),
temperature: 40
},
{
timestamp: ISODate("2019-01-31T10:01:00.000Z"),
temperature: 40
},
...
{
timestamp: ISODate("2019-01-31T10:42:00.000Z"),
temperature: 42
}
],
transaction_count: 42,
sum_temperature: 2413
}
4、例外模式(Outlier)
问题:突然增长很多数据,比如:影评、书籍畅销榜、社交好友关系
添加个 "has_extras": "true",标记是否有非常多的数组元素,有的话去外部关联
{
"_id": ObjectID("507f191e810c19729de860ea"),
"title": "Harry Potter, the Next Chapter",
"author": "J.K. Rowling",
...,
"customers_purchased": ["user00", "user01", "user02", ..., "user999"],
"has_extras": "true"
}
5、计算模式 Computed Pattern
问题:
总收入、观看人数等聚合运算非常耗费性能,可以在后台计算。
方案:
每个子项目插入或更新时直接计算汇总的结果,同时记录时间戳表示上次更新的时间,适合写少读多
例子:iot时序数据、产品分类、大屏应用(single view applications)
6、The Subset Pattern 缩减内存使用
内存缓存提高性能,但是内存不足时怎么办? 加内存、做shard分片
场景:商品的评论,电影的演员 (大量非热点数据不应该放入内存)
方案:把全部存储到product,变成product存储热数据,comment存储历史数据 (需要join一次)
7、Extended Reference Pattern
场景:需要join多个表,来表达非热点数据
方案:不是纯粹的外键关联,而是把常用的字段直接关联复制进来
缺点:数据重复
8、近似模式 The Approximation Pattern
场景:不需要非常准确(具有统计意义就可以),但是需要足够快。比如一个城市的常驻人口数量。
方案:不是每行数据都进行更新,每100行,或每一段时间更新一次
9、The Tree Pattern 树形结构
关系模型:parent_id 或children(list)
MongoDB:后代同时维护 ancestors:[]和 parent
10、 Preallocation Pattern 预分配
使所有数据的数据结构是一致的,哪怕初始的时候是空的,后面再去填充
例子:电影院/酒店的每日订阅情况,4月的工作日有哪些(结构一致会使得算法简单了很多)
11、Document Versioning Pattern 文档版本 ---- 添加version字段
不仅是读最新数据,也需要读历史的版本信息。
前提:版本个数不多,需要多版本的文档也不多,大部分还是使用最新版本的数据
适合于强监管的行业,比如金融、医疗、法律、保险
场景:保险主体和附属条款
current:
{
version:19,
items:[]
}
history: 所有的历史版本
{
version:1,
items:[]
},
{
version:2,
items:[]
},
简单说:每次修改后,生成新版本,把老版本那一行拷贝到历史库。需要使用历史数据时,从历史库里进行查询
12、The Schema Versioning Pattern 结构多版本
添加 schema_version 字段,表示新的数据库模式,可以实现不强制升迁数据库的情况下,升级程序。或者同时有多个版本的存储结构
customer
{
"_id": "<ObjectId>",
"name": "Anakin Skywalker",
"home": "503-555-0000",
"work": "503-555-0010"
}
{
"_id": "<ObjectId>",
"schema_version": "2",
"name": "Anakin Skywalker (Retired)",
"contact_method": [
{ "work": "503-555-0210" },
{ "mobile": "503-555-0220" },
{ "twitter": "@anakinskywalker" },
{ "skype": "AlwaysWithYou" }
]
}
五、其他
https://blog.csdn.net/Real_Myth/article/details/51781099
设计模式策略
1、节点读写分离
2、事务
db.queue.insert( { _id : 123,
message : { },
locked : false,
tlocked : ISODate(),
try : 0 });
var timerange = date.Now() - TIMECONSTANT;
var doc = db.queue.findAndModify( { $or : [ { locked : false }, { locked : true, tlocked : {
$lt : timerange } } ], { $set : { locked : true, tlocked : date.Now(), $inc : { try : 1 } } }
);
//do some processing
db.queue.update( { _id : 123, try : doc.try }, { } );
3、path存储全路径
4、用嵌套避免join
https://mongoing.com/mongodb-advanced-pattern-design
文档最大16M。一个数组太大会严重影响性能
方法论:
数据量
场景
模型:做合适的内嵌
设计模式识别
树形结构:
1、关联 parent
2、存储children数组
3、关联 parent 和所有祖先
4、带有 编码结构的path
钱和时间的数据类型 https://docs.mongodb.com/manual/tutorial/model-time-data/
数据模型需要处理的问题:
实现 泛化
关联 1、聚合; 参照 2、组合; 主子
相关推荐
内容概要:本文详细介绍了如何利用Matlab构建、优化和应用决策分类树。首先,讲解了数据准备阶段,将数据与程序分离,确保灵活性。接着,通过具体实例展示了如何使用Matlab内置函数如fitctree快速构建决策树模型,并通过可视化工具直观呈现决策树结构。针对可能出现的过拟合问题,提出了基于成本复杂度的剪枝方法,以提高模型的泛化能力。此外,还分享了一些实用技巧,如处理连续特征、保存模型、并行计算等,帮助用户更好地理解和应用决策树。 适合人群:具有一定编程基础的数据分析师、机器学习爱好者及科研工作者。 使用场景及目标:适用于需要进行数据分类任务的场景,特别是当需要解释性强的模型时。主要目标是教会读者如何在Matlab环境中高效地构建和优化决策分类树,从而应用于实际项目中。 其他说明:文中不仅提供了完整的代码示例,还强调了代码模块化的重要性,便于后续维护和扩展。同时,对于初学者来说,建议从简单的鸢尾花数据集开始练习,逐步掌握决策树的各项技能。
《营销调研》第7章-探索性调研数据采集.pptx
Assignment1_search_final(1).ipynb
美团优惠券小程序带举牌小人带菜谱+流量主模式,挺多外卖小程序的,但是都没有搭建教程 搭建: 1、下载源码,去微信公众平台注册自己的账号 2、解压到桌面 3、打开微信开发者工具添加小程序-把解压的源码添加进去-appid改成自己小程序的 4、在pages/index/index.js文件搜流量主广告改成自己的广告ID 5、到微信公众平台登陆自己的小程序-开发管理-开发设置-服务器域名修改成
《计算机录入技术》第十八章-常用外文输入法.pptx
基于Andorid的跨屏拖动应用设计实现源码,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。
《网站建设与维护》项目4-在线购物商城用户管理功能.pptx
区块链_房屋转租系统_去中心化存储_数据防篡改_智能合约_S_1744435730
《计算机应用基础实训指导》实训五-Word-2010的文字编辑操作.pptx
《移动通信(第4版)》第5章-组网技术.ppt
ABB机器人基础.pdf
《综合布线施工技术》第9章-综合布线实训指导.ppt
很不错的一套站群系统源码,后台配置采集节点,输入目标站地址即可全自动智能转换自动全站采集!支持 https、支持 POST 获取、支持搜索、支持 cookie、支持代理、支持破解防盗链、支持破解防采集 全自动分析,内外链接自动转换、图片地址、css、js,自动分析 CSS 内的图片使得页面风格不丢失: 广告标签,方便在规则里直接替换广告代码 支持自定义标签,标签可自定义内容、自由截取、内容正则截取。可以放在模板里,也可以在规则里替换 支持自定义模板,可使用标签 diy 个性模板,真正做到内容上移花接木 调试模式,可观察采集性能,便于发现和解决各种错误 多条采集规则一键切换,支持导入导出 内置强大替换和过滤功能,标签过滤、站内外过滤、字符串替换、等等 IP 屏蔽功能,屏蔽想要屏蔽 IP 地址让它无法访问 ****高级功能*****· url 过滤功能,可过滤屏蔽不采集指定链接· 伪原创,近义词替换有利于 seo· 伪静态,url 伪静态化,有利于 seo· 自动缓存自动更新,可设置缓存时间达到自动更新,css 缓存· 支持演示有阿三源码简繁体互转· 代理 IP、伪造 IP、随机 IP、伪造 user-agent、伪造 referer 来路、自定义 cookie,以便应对防采集措施· url 地址加密转换,个性化 url,让你的 url 地址与众不同· 关键词内链功能· 还有更多功能等你发现…… 程序使用非常简单,仅需在后台输入一个域名即可建站,不限子域名,站群利器,无授权,无绑定限制,使用后台功能可对页面进行自定义修改,在程序后台开启生 成功能,只要访问页面就会生成一个本地文件。当用户再次访问的时候就直接访问网站本地的页面,所以目标站点无法访问了也没关系,我们的站点依然可以访问, 支持伪静态、伪原创、生成静态文件、自定义替换、广告管理、友情链接管理、自动下载 CSS 内的图。
【自然语言处理】文本分类方法综述:从基础模型到深度学习的情感分析系统设计
基于Andorid的下拉浏览应用设计实现源码,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。
内容概要:本文详细介绍了一个原创的P2插电式混合动力系统Simulink模型,该模型基于逻辑门限值控制策略,涵盖了多个关键模块如工况输入、驾驶员模型、发动机模型、电机模型、制动能量回收模型、转矩分配模型、运行模式切换模型、档位切换模型以及纵向动力学模型。模型支持多种标准工况(WLTC、UDDS、EUDC、NEDC)和自定义工况,并展示了丰富的仿真结果,包括发动机和电机转矩变化、工作模式切换、档位变化、电池SOC变化、燃油消耗量、速度跟随和最大爬坡度等。此外,文章还深入探讨了逻辑门限值控制策略的具体实现及其效果,提供了详细的代码示例和技术细节。 适合人群:汽车工程专业学生、研究人员、混动汽车开发者及爱好者。 使用场景及目标:①用于教学和科研,帮助理解和掌握P2混动系统的原理和控制策略;②作为开发工具,辅助设计和优化混动汽车控制系统;③提供仿真平台,评估不同工况下的混动系统性能。 其他说明:文中不仅介绍了模型的整体架构和各模块的功能,还分享了许多实用的调试技巧和优化方法,使读者能够更好地理解和应用该模型。
内容概要:本文详细介绍了基于ADMM(交替方向乘子法)算法在电力系统分布式调度中的应用,特别是并行(Jacobi)和串行(Gauss-Seidel)两种不同更新模式的实现。文中通过MATLAB代码展示了这两种模式的具体实现方法,并比较了它们的优劣。并行模式适用于多核计算环境,能够充分利用硬件资源,尽管迭代次数较多,但总体计算时间较短;串行模式则由于“接力式”更新机制,通常收敛更快,但在计算资源有限的情况下可能会形成瓶颈。此外,文章还讨论了惩罚系数rho的自适应调整策略以及在电-气耦合系统优化中的应用实例。 适合人群:从事电力系统优化、分布式计算研究的专业人士,尤其是有一定MATLAB编程基础的研究人员和技术人员。 使用场景及目标:①理解和实现ADMM算法在电力系统分布式调度中的应用;②评估并行和串行模式在不同应用场景下的性能表现;③掌握惩罚系数rho的自适应调整技巧,提高算法收敛速度和稳定性。 其他说明:文章提供了详细的MATLAB代码示例,帮助读者更好地理解和实践ADMM算法。同时,强调了在实际工程应用中需要注意的关键技术和优化策略。
内容概要:本文深入研究了交错并联Buck变换器的工作原理、性能优势及其具体实现。文章首先介绍了交错并联Buck变换器相较于传统Buck变换器的优势,包括减小输出电流和电压纹波、降低开关管和二极管的电流应力、减小输出滤波电容容量等。接着,文章详细展示了如何通过MATLAB/Simulink建立该变换器的仿真模型,包括参数设置、电路元件添加、PWM信号生成及连接、电压电流测量模块的添加等。此外,还探讨了PID控制器的设计与实现,通过理论分析和仿真验证了其有效性。最后,文章通过多个仿真实验验证了交错并联Buck变换器在纹波性能、器件应力等方面的优势,并分析了不同控制策略的效果,如P、PI、PID控制等。 适合人群:具备一定电力电子基础,对DC-DC变换器特别是交错并联Buck变换器感兴趣的工程师和技术人员。 使用场景及目标:①理解交错并联Buck变换器的工作原理及其相对于传统Buck变换器的优势;②掌握使用MATLAB/Simulink搭建交错并联Buck变换器仿真模型的方法;③学习PID控制器的设计与实现,了解其在电源系统中的应用;④通过仿真实验验证交错并联Buck变换器的性能,评估不同控制策略的效果。 其他说明:本文不仅提供了详细的理论分析,还给出了大量可运行的MATLAB代码,帮助读者更好地理解和实践交错并联Buck变换器的设计与实现。同时,通过对不同控制策略的对比分析,为实际工程应用提供了有价值的参考。
《综合布线施工技术》第8章-综合布线工程案例.ppt
内容概要:本文详细介绍了基于STM32F103C8T6的K型热电偶温度控制仪的设计与实现。硬件部分涵盖了热电偶采集电路、OLED显示模块、蜂鸣器电路、风扇控制电路以及EEPROM存储模块。软件部分则涉及ADC配置、OLED刷新、PID控温算法、EEPROM参数存储、风扇PWM控制等多个方面的具体实现。文中不仅提供了详细的代码示例,还分享了许多调试经验和注意事项,如冷端补偿、DMA传输优化、I2C时钟配置、PWM频率选择等。 适合人群:具有一定嵌入式系统开发经验的工程师和技术爱好者。 使用场景及目标:适用于需要进行温度监测与控制的应用场景,如工业自动化、实验室设备等。目标是帮助读者掌握STM32F103C8T6在温度控制领域的应用技巧,提升硬件设计和软件编程能力。 其他说明:本文提供的工程文件包含Altium Designer的原理图PCB文件,便于二次开发。此外,文中还提到了一些扩展功能,如加入Modbus通信协议,供有兴趣的读者进一步探索。