为500,000名用户存储权重对的最佳方式?

时间:2011-03-07 06:09:47

标签: database algorithm vector nosql matching

我正在建立一个我希望按照共同兴趣匹配人们的网站。我这样做是通过计算每个用户之间的权重并确定谁是最佳匹配 - 那些权重较高的人:

示例:

user 1 with user 2 = weight of 1
user 1 with user 3 = weight of 10
user 1 with user 4 = weight of 20

我想将权重放在数据库中。问题是如果我有500,000个用户,它是500,000 x 500,000个可能的组合,或者125,000,000,000个条目 - 在mysql DB中。在很多表格中插入这么多数据是不现实的。

我的问题是:有没有办法使用其他类型的数据库处理如此多的权重配对?我已经阅读了关于向量和事物的内容,但对此不太了解。

我查看了以下文档:

  • NoSQL数据库:MongoDB
  • 对象数据库:(db4o,Versant)
  • 图形数据库:neo4j,sones ...
  • 宽栏:Hadoop,HBASE
  • 文档存储:CouchDB
  • Key Value Store:Redis,Voldemort
  • 网格数据库:Gigaspaces ..
  • XML数据库。

但其中我没有看到解决方案。有没有人遇到这个问题,可以给我一个提示?

7 个答案:

答案 0 :(得分:1)

我打算走出去,说这个问题没有好的解决方案。似乎没有办法避免在提出问题的情况下存储125B用户/权重值。

查看其他数据库类型无济于事。您根本无法解决需要存储125B值的事实。

围绕这个

有几种方法
  • 找出用户和权重之间的关系。例如。如果权重总是等于两个用户ID的总和(假设用户有ID),那么你不必存储权重。
  • 动态计算,不存储

答案 1 :(得分:1)

根据你的解释,我认为不应该存储这些权重。它们是您已经完成的一些计算的缓存。您无需存储结果,因为您可以在需要时重复计算。您仍然可以存储权重,但请记住它的缓存,并且当缓存已满时,其中的数据可以删除。

BTW,用户通常都有过滤器。这些过滤器可能会自动忽略95%的用户群。你可以利用这个优势。

答案 2 :(得分:0)

从问题看来,结构似乎代表一个网格,其中每个用户都连接到其他用户(500K X(500k -1))。听起来很复杂。做出一些启发式假设,可能会进行优化。

假设情况1:并非每个用户对都可能具有权重,这可能导致稀疏矩阵。那么为什么不单独存储非零权重

假设案例2:我强烈认为权重范围可能会受到限制。我认为不会有500k不同的重量,可能有500种不同的重量。如果是这种情况,请创建500个不同的组,用于存储用户对。空间节省不多,但是分区方法。

为了使用案例2节省空间,无需在这些组下存储用户。聚合感兴趣的特征(下限和上限)。要获取给定用户的匹配项,请执行以下操作:

  1. 遍历500多个重量分组并获取最合适的下限和上限。你不会知道确切的用户,但你现在知道他/她如何映射。
  2. 在用户表中搜索落入此边界的用户
  3. 对第2步返回的实际用户组进行更深入的分析。
  4. 我的假设可能是错误的。在哪种情况下,只是给了一个好友。

答案 3 :(得分:0)

只要您的设计涉及存储所有组合的所有权重,就无法避免存储问题。只有优化设计本身才能实现合理的空间优化。下面的questzen提出了一些好的方法。稀疏矩阵方法最初可能有效,但随着越来越多的用户连接,它可能变得无用。例如,识别权重的固定桶(范围)而不是绝对权重值会更好。

或者,看看你是否可以丢弃完全连接的网状拓扑并采用稀疏连接的集群或层次结构等。如果是这样,那么每个这样的集群都可以被赋予一个Id,你可以为每个用户赋予权重与他/她自己的集群(一定程度的归属感)和集群到集群连接的权重。然后,可以根据群集间权重和用户对其群集的“归属程度”来推导从群集1中的user-1到群集2中的user-2的连接的权重。

答案 4 :(得分:0)

我认为这是一个非常简单而有趣的问题,特别是如果你不能使用任何技巧来减少存储的权重数量。最终,您拥有键值对,其中键由用户对组成。只要您只想在给定的用户对中检索单个权重,就可以使用分片。

如果您的数据没有经常更改并且您有多台计算机可以使用,那么您应该能够实现自己的简单分片策略或使用Gizzard来管理具有兼容键值的简单群集每台计算机上的数据存储区。 (Gizzard要求所有操作都是可交换的和幂等的。)

答案 5 :(得分:0)

您是否愿意从头开始构建解决方案?
如果你做到了,也许你应该创建500000个文件,每个用户一个,并在每个文件中存储500000个权重,按用户ID排序,具有固定长度。然后,您可以转到所需文件中的特定位置并读取值,而不使用分隔符或实际存储用户ID。 (如果您的用户ID不是1-500000的数字,您还需要从用户ID到1-500000的新ID的映射,并且您将按此id排序)

您的体重需要什么样的粒度?
您可以将每个权重四舍五入到最接近的n /(2 ^ k)倍数,以满足您的需要。在3位小数的情况下,您可以将每个数字存储为10位,k = 10。这样每个文件只有500000 * 10bits = 625Kb,整个数据集将是312.5Gb。你甚至可以压缩文件,只在需要时解压缩它们,这取决于你愿意在速度和空间之间做出的权衡取舍。此解决方案还假设很少进行更改,并且您一次只检索一个值(或某种值的范围)。

答案 6 :(得分:-1)

在我看来,问题不存在。因为一个人知道500k人是不现实的。可能是一个人被500,000人所知,但这个人可能只知道他们中的一小部分,例如Lady Gaga

对于整个生活中的社交网络来说,一个现实的平均值可能是300。所以你“只有”了150到2亿的关系。

我会使用图形数据库,因为使用它们可以很容易地建立关系模型。