我在我的项目中使用MongoDB进行统计和数据分析。我的目标是设计数据具有最佳性能和可扩展性。
我们假设每家商店都有几家商店和一系列独特的商品。我需要查询一些有关产品的数据,计算一些基本的统计数据(仅限幕布店)。
从性能的角度来看哪种方式更好:在Shop文档和产品列表中,然后根据此文档进行查询。
或者更好的是将每个商店的所有产品单独收集,然后为该系列构建查询?
也许问题本身就是:mongodb可以通过许多文档以如此有效的方式查询一个文档的正文。
UPD 1: 现在让我们假设产品本身非常小(Id,价格,名称,数量),并且它的数量是有限的。 (所以我肯定知道每家商店不会超过1000种产品)
UPD2 还假设我不想为了查看目的而读取该数据库,仅用于统计。 (售出多少,哪个最有趣,哪些小组等等)
答案 0 :(得分:2)
与所有这些问题一样,主要决定因素之一是数据规模和增长。
每家商店的数据是否超过16兆?根据商店可以拥有多少商品以及只有一件物品可以归结为多少商品,我很快就会这样做。
我的意思是想象一下产品有多少个字段:
其中一些领域会很大,例如,产品的描述可能非常庞大。
然而,如果有机会这是一个非常简单的应用程序,你正在寻找一个可以完全包含在单个数据行和商店中的产品,这些产品永远不会有超过5-8,000个项目,那么你可以做得更好使用排序的子文档:
{
_id: ObjectId(),
shop_name: 'toys r us',
items: [
{ p_id: ObjectId(), price: '1000000', currency: 'GBP', description: 'fkf' }
]
}
但是,子文档并非没有它们的价格。想象一下,你有一个只有一个子文档的文档,在10天内有100和20,1000。
持续增长的文件造成的碎片可能非常重要。这会降低您的性能。您的性能不仅会成为一个问题,而且修复碎片也不是一件好事,之后在应用程序逻辑中解决它会更加困难。
要了解有关MongoDB实际工作原理的更多信息,您可以查看此演示文稿:http://www.10gen.com/presentations/storage-engine-internals
至于查询子文档,它确实需要在MongoDBs上做一些额外的工作,但它仍然非常便宜(比多次往返便宜),只要你设置正确。
根据我上面提供的信息,我个人会选择两个系列,但我不知道你的方案的真实程度......
UPD 1:现在让我们假设产品本身非常小(Id,价格,名称,数量),而且数量有限。 (所以我肯定知道每家商店不会超过1000种产品)
好的,所以你的文件很小,每个文件可能只有几个字节。在这种情况下,您可以在此处使用具有2个大小分配功能的子文档来修复某些碎片:http://docs.mongodb.org/manual/reference/command/collMod/#usePowerOf2Sizes
这可能会创建一个高性能的操作,仍然有1到1000个子文档可能导致碎片,但是这些碎片应该在它们出现时由较小的“新”商店文档填充。
UPD2还假设我不想为视图目的读取该数据库,仅用于统计。 (销售量多少,最有趣的是什么,哪些群体等等)
因此,对于每个商店,使用子文档,您可以轻松获得每个商店的销售总额,如:
db.shops.aggregate([
// Match shop id 1
{$match: {_id: 1}},
// unwind the products for that shop
{$unwind: '$products'},
// Group back up by shop id and total amount sold
{$group: {_id: '$_id', total_sold: {$sum: '$products.sold'}}}
])
使用新的聚合框架(自2.1版开始):http://docs.mongodb.org/manual/applications/aggregation/
因此,子文档也可以像两个单独的集合一样容易查询。