我只是想在 MySQL 中找到一个数据库结构来获取所有用户的 friend 的 friend 和相应的查询来检索他们。 (好友链接是双向的)
我找到了一些与此相关的帖子,但我担心的是性能:
结构一
许多帖子建议使用一种结构,其中您有一个表格,其中每一行代表一个友谊链接,例如:
CREATE TABLE `friends` (
`user_id` int(10) unsigned NOT NULL,
`friend_id` int(10) unsigned NOT NULL,
)
说用户 '1' 有三个 friend '2','3','4' 而用户 '2' 有两个 friend '1','5' 。你的 friend 表看起来像这样:
user_id | friend_id
1 | 2
1 | 3
1 | 4
2 | 1
2 | 5
friend 的 friend 查询:如何选择 friend 的 friend 可以看这里SQL to get friends AND friends of friends of a user .用户“1”的查询结果应该是 (1,2,3,4,5)
我担心的是:fb 用户平均有大约 140 个 friend 。经常使用的用户会有更多。 如果我有 20.000 个用户,这将至少有 300 万行。
结构二
如果我可以使用这样的结构:
CREATE TABLE `friends` (
`user_id` int(10) unsigned NOT NULL,
`friend_1` int(10) unsigned NOT NULL,
`friend_2` int(10) unsigned NOT NULL,
`friend_3` int(10) unsigned NOT NULL,
`friend_4` int(10) unsigned NOT NULL,
....
)
我的表格看起来像这样(以上面的例子为例):
user_id | friend_1 | friend_2 | friend_3 | ...
1 | 2 | 3 | 4 |
2 | 1 | 5 | |...
现在我只有 20.000 行。
friend 的 friend 查询:选择我试过的 friend 的用户 friend
Select * FROM friends as a
WHERE a.user_id
IN (
SELECT * FROM friends AS b
WHERE b.user_id = '1'
)
但我收到错误消息“#1241 - Operand should contain 1 column(s)”。我认为问题是,子选择传递的是一行,而不是一列?
问题
希望您能理解我的担忧。对于这些问题的任何输入,我都会非常高兴
1) 在结构 2 中找到返回指定用户的 friend 的所有 friend 的查询?
2) 哪种结构可以让我更快地返回 friend 的 friend ? 在结构 2 中,我认为“将行与列连接起来”可能会很慢,如果它甚至可以在这里使用连接的话。谢谢你的任何建议。如果您能想到任何其他结构,也许可以利用小世界网络类型,我很乐意听到它们。
谢谢!!
最佳答案
肯定用第一种结构。由于子句复杂,对第二种结构的查询将非常庞大、难以维护且速度缓慢。
第一种方法的足够快的查询:
(
select friend_id
from friends
where user_id = 1
) union (
select distinct ff.friend_id
from
friends f
join friends ff on ff.user_id = f.friend_id
where f.user_id = 1
)
为了获得最佳性能,您需要拥有这些索引:
ALTER TABLE `friends` ADD UNIQUE INDEX `friends_idx` (`user_id` ASC, `friend_id` ASC);
ALTER TABLE `friends` ADD INDEX `friends_user_id_idx` (`user_id` ASC);
关于MySQL 检索 friend 的 friend 结构和性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7138197/