这听起来像是你需要BFS http://en.wikipedia.org/wiki/Breadth-first_search
在线方法:
我认为这可能会很昂贵,具体取决于您想如何使用它。
在最坏的情况下,您将迭代数据库中的所有数据:成本运行时间O(n)
(假设您有一个查找函数以在运行时O(1)
中查找图中的用户)。
离线方法:
您可以进行离线预计算并存储距离作为查找函数,但这需要一些额外的内存O(n*n)
,其中n是用户数量。现在查找函数的成本仅为O(1)
或O(logn)
,具体取决于您如何实现它
(忽略离线运行时间,我认为它将在O(n)
到O(n*n)
范围内)。
策略
你想要遵循的策略取决于你所期望的用户数量上限以及用户之间的连接程度。如果你只有少量用户,在线方法可能就可以,但如果你有数百万用户,则可能需要离线方法,但这将耗费一些内存。
其他考虑事项
- 混合在线和离线方法
- 使用缓存策略
- 每当更新用户的新参考时,请更新距离查找功能
更新的答案 有1700万用户,我们需要采用离线方法。
我会选择离线版本。你应该避免O(n*n)
运行时间,我认为这是可能的。
数据库模型
你应该考虑如何建模数据库,因为这将是此实现中最昂贵的部分。
可能是这样的:
为每个用户创建一个表(表名可以是userId)。每个表都有每个用户的条目(记录键是userId)。
这将导致17百万个表,每个表都有17百万个条目(这是O(n*n)
成本)。
离线,您可以在运行BFS时跟踪已访问的用户和BFS迭代中的级别,并将距离保存到数据库中。我还没有完全考虑清楚这部分,但我认为这种策略是可行的。记得对每个节点运行BFS,即直到您访问了所有用户。
如果此策略不可行,则可以从每个节点运行BFS,其运行时间为O(n*n)
。这意味着在最坏情况下可能需要一个月才能运行,即您的距离数据可能过时。运行速度取决于您的用户连接程度。
或者,如果可能的话,您可以采用“每当更新用户的新引用时,请更新距离查找函数”的方法。这将运行一次BFS,其运行时间为O(n)
,即几秒钟。在第一次事件上调用BFS(userId),之后在引用更新时调用。
在线,您可以使用userId按表名获取表格,并通过另一个userId获取条目以获取距离。