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

使用PHP创建高效的好友列表,php,mysql,arrays,database-design,tree-structure,Php,Mysql,Arrays,Database Design,Tree Structure,我想建立一个网站,有一个社会网络的一些元素 所以我一直在想一种有效的方法来存储好友列表(有点像Facebook) 在搜索了一点之后,我遇到的唯一建议是制作一个带有两个表示友谊的ID的“表” 这可能在小型网站上奏效,但似乎一点效率都没有 我有Java背景,但对PHP不够精通 我脑海中闪过一个想法,我认为这个想法可以很好地发挥作用,问题是我不知道如何实施它 其思想是将所有朋友的“id”保存在一个树数据结构中,该树中的每个节点类似于朋友id中的一个数字 首先从1个节点开始,然后在用户添加朋友时添加更多

我想建立一个网站,有一个社会网络的一些元素

所以我一直在想一种有效的方法来存储好友列表(有点像Facebook)

在搜索了一点之后,我遇到的唯一建议是制作一个带有两个表示友谊的ID的“表”


这可能在小型网站上奏效,但似乎一点效率都没有

我有Java背景,但对PHP不够精通

我脑海中闪过一个想法,我认为这个想法可以很好地发挥作用,问题是我不知道如何实施它

其思想是将所有朋友的“id”保存在一个树数据结构中,该树中的每个节点类似于朋友id中的一个数字

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

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

“X”标记Id的结尾

例如,请参见此树:

在此树中,用户有4个具有以下“id”的朋友:

  • 0
  • 143
  • 1436
  • 十五
更新:正如之前可能不清楚的那样,这个想法是每个用户都有一个多维数组形式的树,其中指针本身的存在表示朋友的“id”

如果每个用户都有这样一个多维数组,搜索id“y”是否是我的朋友,从我的朋友列表中删除id“y”或将id“y”添加到我的朋友列表都需要恒定的时间O(1),而不依赖于网站可能拥有的用户数,唯一的退步是,使用这样一个巨大的数组,序列化它并将其放入表的每一行似乎并不正确

-这甚至可以实现吗

-使用序列化将树插入到表中是否可行

-有没有更好的办法

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

我非常感谢您在实施此方法方面提供的任何帮助,或者对改进或更改此方法的其他方法提出的任何建议。

您应该查看Open Query graph存储引擎。它设计用于处理MySQL的高效树和图形存储

您也可以查看我的演示文稿,或者我对堆栈溢出的回答


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

你在标题中说“使用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);

我强烈建议不要这样做

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

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

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

这是我想到的大问题。但总的来说,我认为你考虑得太多了。

一些想法:

  • 有序列表-在有序列表中搜索速度很快,但排序本身可能更重
  • 水平分区数据
  • 摆脱过早的优化

“一点效率都没有。”为什么?一张只有两个
id
s的
友谊表是一个可靠的计划。不要实施会让你的继任者追捕到你并打到你脸上的事情。:)我可能错了,但看看我对Matt的回答的反应,为什么它效率低下。链接表似乎一点也不高效,为什么我要浏览一个包含网站上所有关系的列表(可能与用户数量成指数关系),而实际上我只能有一个朋友,显然,任何需要处理大量不必要数据的方法都不是最优的。特别是如果“不必要的数据”是其他10亿个关系,我相信你看错了链接表。若一个用户有一个朋友,那个么只有一行存在。您将构建脚本来搜索两个id列,以消除反向重复。我在回答中添加了数据库表的说明。我看表的时候好像它没有被排序,但排序当然要好得多,也就是说,在每次插入后排序表将花费时间,我假设为O(log(n))即使数据库自己独立运行,最好也不用我编写代码。我真的认为你错过了索引将发挥多少作用