使用PHP创建有效的好友列表

时间:2011-08-01 18:07:07

标签: php mysql arrays database-design tree-structure

我想建立一个拥有社交网络元素的网站。

所以我一直试图想出一种存储朋友列表的有效方式(有点像Facebook)。

在搜索了一下后,我遇到的唯一建议是制作一张带有两个“ids”的“桌子”,表示友谊。

这可能适用于小型网站,但它似乎并不高效。

我有Java背景,但我对PHP不够熟练。

我认为一个想法可以很好地运作,问题是我不知道如何实现它。

这个想法是将你朋友的所有“id”保存在树状数据结构中,该树中的每个节点都与朋友的id中的一个数字相似。

首先从1个节点开始,然后在用户添加好友时添加更多节点。 (有点像Lempel-Ziv)。

每个节点都能指向其他11个节点,0到9和X.

“X”标志着Id的结束。

例如,请参阅此树:

An Example

在这棵树中,用户有4个朋友,其中包含以下“id”:

  • 0
  • 143
  • 1436
  • 15

更新:因为之前可能还不清楚,我的想法是每个用户都会有一个多维数组形式的树,其中指针本身的存在表明了朋友的“id”

如果每个用户都有这样一个多维数组,搜索id“y”是否是我的朋友,从我的朋友列表中删除id“y”或将id“y”添加到我的朋友列表中都需要恒定时间O( 1)不依赖于网站可能拥有的用户数量,只有抽取,采用如此庞大的数组,将其序列化并将其推入表格的每一行似乎都不正确。

- 这甚至可以实现吗?

- 使用序列化将该树插入表中是否实用?

- 有没有更好的方法呢?

我选择这个的好处是,即使有非常大量的ID(数百万或数十亿),搜索,添加,删除时间也是线性的(取决于位数)。

我非常感谢您在实施此方面提供的任何帮助或任何有关改进或更改此方法的替代方法的建议。

4 个答案:

答案 0 :(得分:3)

我强烈建议不要这样做。

  • 存储节省不大,可能(可能?)更糟。在真实的数据集中,使用这种方法为您提供的实际空间节省是最小的。计算平均节省是一个非常困难的问题,但是使用一些实数并尝试使用随机ID的一些样本。如果您有一百万用户,请考虑拥有15位朋友的用户。你用这个approch保存了多少数据?实际上,您可能会使用更多空间,因为树邻接模型可能需要大量数据。

  • “呈现”用户列表需要CPU投资。

  • 插入是非确定性且非平凡的。当您将新用户添加到现有树时,您将有多种插入方法。假设您没有任意选择,很难计算哪种方法最好(并且只能基于启发式方法)。

这是我想到的最重要的事情。但总的来说,我认为你过分在想这个。

答案 1 :(得分:2)

您应该查看开放查询图存储引擎OQGRAPH。它旨在处理MySQL的高效树和图存储。

您还可以在Stack Overflow上查看我的演示文稿Models for Hierarchical Data with SQL and PHP或我对What is the most efficient/elegant way to parse a flat table into a tree?的回答。

我描述了一个我称之为 Closure Table 的设计,它记录了层次结构中祖先和后代之间的所有路径。

答案 2 :(得分:2)

你在标题中说“使用PHP”,但这似乎只是一个数据库问题。不管你信不信,联系表是迄今为止最好的方式。特别是如果你有数百万或数十亿的用户。处理起来会更快,在PHP代码中更容易处理,存储起来更小。

<强>更新

用户表:

  id    |   name   |   moreInfo
   1    |    Joe   |     stuff
   2    |    Bob   |     stuff
   3    |   Katie  |     stuff
   4    |   Harold |     stuff

友谊表:

   left   |   right
    1     |     4
    1     |     2
    3     |     1
    3     |     4

在这个例子中,乔认识每个人,凯蒂知道哈罗德。

这当然是一个简化的例子。

我很想知道某人是否有更好的左右逻辑和解释原因。

<强>更新

我在下面的评论中提供了一些PHP代码,但它被标记错了所以这里又是。

$sqlcmd = sprintf( 'SELECT IF( `left` = %1$d, `right`, `left`) AS "friend" FROM `friendship` WHERE `left` = %1$d OR `right` = %1$d', $userid);

答案 3 :(得分:1)

很少有想法:

  • 有序列表 - 通过有序列表搜索很快,但订购本身可能更重;
  • 水平分区数据;
  • 摆脱过早的优化。