进入MongoDB中文手册(4.2版本)目录
1 概述
通常,应用程序需要从数据库中存储的源数据中获取值。计算新值可能需要大量的CPU资源,尤其是在大型数据集或必须检查多个文档的情况下。
如果经常需要一个计算值,那么将其提前保存在数据库中会更有效。这样,当应用程序请求数据时,仅需要一个读取操作。
2 计算模式
如果读取的次数大大超过写入的次数,则计算模式将减少执行计算的频率。应用程序没有将计算负担附加到每次读取上,而是存储了计算值并根据需要重新计算。应用程序可以在每次写操作时重新计算该值,这些写操作会更改计算值的源数据,或者作为定时任务的一部分。
注意
使用定期更新时,不能保证计算值在任何给定的读取中都是准确的。但是,如果不要求精确性,则此方法可能值得提高性能。
3 示例
一个应用程序显示电影观众和收入信息。
考虑以下screenings集合:
// screenings collection
{
"theater": "Alger Cinema",
"location": "Lakeview, OR",
"movie_title": "Reservoir Dogs",
"num_viewers": 344,
"revenue": 3440
}
{
"theater": "City Cinema",
"location": "New York, NY",
"movie_title": "Reservoir Dogs",
"num_viewers": 1496,
"revenue": 22440
}
{
"theater": "Overland Park Cinema",
"location": "Boise, ID",
"movie_title": "Reservoir Dogs",
"num_viewers": 760,
"revenue": 7600
}
用户通常想知道有多少人看了一部电影以及该电影赚了多少钱。在此示例中,对于放映了标题为“ Reservoir Dogs”的电影, 您对该电影进行读取并对对num_viewers 和revenue字段的值求和。为了避免每次请求信息时都执行该计算,您可以计算总值并将其与电影记录本身一起存储在一个movies集合中:
// movies collection
{
"title": "Reservoir Dogs",
"total_viewers": 2600,
"total_revenue": 33480,
...
}
在低写入环境中,可以结合screenings数据的任何更新来完成计算。
在定期写入的环境中,可以按定义的时间间隔进行计算-例如每小时进行一次。screenings的源数据不受对movies集合的写入的影响,因此您可以随时运行计算。
这是一种常见的设计模式,可以减少CPU工作量并提高应用程序性能。每当您重复执行相同的计算并且读写比很高时,请考虑计算模式。
3.1 其他用例的示例
除了经常要求求和的情况(例如在电影数据库示例中获得总收入或观众数)之外,无论何时需要对数据进行计算,计算模式都非常合适。例如:
- 一家汽车公司对车辆数据进行大规模汇总查询,存储结果并在接下来的几个小时显示,直到重新计算数据为止。
- 一家消费者报告公司,它收集来自多个不同来源的数据并按顺序创建列表,例如“ 100个最佳审查小工具”。在独立更新基础数据的同时,可以定期重新生成列表。