MySQL 检索 friend 的 friend 结构和性能

标签 mysql database performance structure

我只是想在 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/

相关文章:

php - 如何从 Mysql 中选择逗号分隔的变量

php - 在 cakephp 中使用内连接显示两个表的数据

mysql - 经常使用sql查询,如何将在线MySQL数据库中的数据插入到本地MySQL数据表中?

php - 使用 PHP/Joomla 以编程方式将 MySql 数据库导出到 CSV

相同算法的 Java 与 C 版本

php - 优化高级SQL查询

php - 想要将 cakephp 2.0 中的时间戳更改为日期

MySQL 将主键从 varchar 移至 int

javascript - 如何在单个查询中选择多个文档引用?

php - MVC 的缓存层 - 模型还是 Controller ?