1个更新文档vs许多更小的插入文档



我需要为用户开发一个数据集,存储他们最喜欢的项目——可能5%的用户会有最喜欢的,而对于那些可能平均有5-10个最喜欢的用户,最多50个。几乎每个用户都会有一个"获取收藏夹"的调用,无论他们是否有,但可能很少添加

我的假设是:"获取收藏夹"可能比"添加/发布收藏夹"多100倍。

在mongo中使用这种结构会更好吗?这可能会减慢插入速度(因为每个用户需要更新一个文档),但检索所有文档可能会更快。

{
_id : 123456,  (the user id)
favourites : [
{ item_id : 43563, created_date : ... },
{ item_id : 31232, created_date : ... },
{ item_id : 23472, created_date : ... }
]
}

或者每个喜爱的一个文档

{
_id: ...,
user_id : 123456,
item_id : 43563,
created_date:...
}
{
_id: ...,
user_id : 123456,
item_id : 31232,
created_date:...
}
{
_id: ...,
user_id : 123456,
item_id : 23472,
created_date:...
}

对于未来的需求变化,第二种结构可能更灵活,但我认为第一种结构会将所有数据定位在磁盘上的一个区域中,读取速度可能会快得多。

再说一遍,我不确定(通过多次更新)更改收集文档的大小是否会产生有害影响?(即低级别,它必须在磁盘上移动文档,还是无论如何都会对数据进行分段,因为它可能在第一次插入时没有为其在存储中预先分配足够的空间)

问题是:一种方法是推荐的还是比另一种方法更高效。

设计Mongo集合的一种方法是考虑最有可能使用数据的方式,并为此目的进行设计。在您的情况下,您的用户会更频繁地查询添加收藏夹的收藏夹。因此,集合的设计应优化此查询。

考虑到这一点,第一个选项是两个选项中最理想的。但是,您可能需要考虑对该结构进行一点修改。

正如您所说,getFavourites方法将为所有用户调用,但只会为5%的用户返回收藏夹列表。此调用必须检索收藏夹数组并确定它是否包含内容。虽然这不会花费太多费用,但您可以通过添加一个额外的字段来预先计算此调用,该字段只有在用户有收藏夹时才为true。因此,如果返回的值为true,则只需要查询此字段,然后只查询收藏夹。

我想象一个结构如下:

{
_id : 123456,  (the user id),
hasFavourites: 1,
favourites : [
{ item_id : 43563, created_date : ... },
{ item_id : 31232, created_date : ... },
{ item_id : 23472, created_date : ... }
]
}

此文档有收藏夹,因此"收藏夹"字段为1,如果没有,则为0。

最新更新