在表中有一对朋友,如何制作一个抽象获取用户朋友列表的视图?

Posted

技术标签:

【中文标题】在表中有一对朋友,如何制作一个抽象获取用户朋友列表的视图?【英文标题】:having pairs of friends in table, how to make a view that would abstract getting list of user's friends? 【发布时间】:2013-07-09 01:03:23 【问题描述】:

我有一张谁和谁交朋友的表格,简单如下:

user_id1 | user_id2 | <some other data>

具有非唯一索引:index_on_user1index_on_user2

两列都包含相同类型的数据,友谊总是双向的。

1 | 2

=用户1是用户2的朋友,用户2是用户1的朋友。

我想要的是获得一个查询,该查询将始终为我提供我提供的任何 user_id 的朋友列表。

到目前为止,我一直在使用

SELECT if(`user_id1` = $user_id, `user_id2`, `user_id1`) as friend
FROM `Friends`
WHERE `user_id1` = $user_id OR `user_id2` = $user_id

但我有更多查询,我想在其中获取此信息作为子查询,并将包含此查询的视图作为子查询。所以我一直在寻找一种方法来抽象这个,有一些简单的选择,总能得到我朋友的 id,而没有if 声明的麻烦。

我对联合有了这个想法:

CREATE OR REPLACE VIEW get_friend AS 
SELECT 
    `user_id1` as subject,
    `user_id2` as friend,
    FROM `Friends` 
    USE INDEX (`index_on_user1`)
UNION
SELECT
    `user_id2` as subject,
    `user_id1` as friend,
    FROM `Friends` 
    USE INDEX (`index_on_user2`)

使用简单的SELECT friend FROM get_friend WHERE subject = $user_id 来获得结果,它可以工作。

但是explain select... 说它不使用索引,即使有提示也不使用。

我怎样才能让它使用这些索引?甚至可能吗?还有其他解决方案吗?

【问题讨论】:

存储过程可能会更好,因为它可以将 ID 替换到查询中。 【参考方案1】:

您需要在 UNION 语句的各个查询中包含 WHERE 子句才能使用索引。本质上,您对视图的查询正在执行此操作

SELECT subject, friend FROM
(SELECT 
    `user_id1` as subject,
    `user_id2` as friend,
    FROM `Friends` 
    USE INDEX (`index_on_user1`)
UNION
SELECT
    `user_id2` as subject,
    `user_id1` as friend,
    FROM `Friends` 
    USE INDEX (`index_on_user2`)
) WHERE friend = <some number>

尝试对 UNION 运行 EXPLAIN 查询并填写适当的 where 子句,您应该会看到正在使用索引。

【讨论】:

所以你的意思是不要使用视图,而是直接使用联合......这绝对可以。【参考方案2】:

您不能在一个视图上使用不同的索引。为了获得你想要的性能,你必须在你需要的地方编写原始 SQL(比如你的联合)。

更好的解决方案是存储关系的两个方向。这是一些非规范化的数据,但不多。这样做可以使您的查询变得简单且执行良好。

为避免保存“其他数据”,您可以创建一个仅包含 id 的新表。使用触发器填充它并使其与主表对齐。

【讨论】:

以上是关于在表中有一对朋友,如何制作一个抽象获取用户朋友列表的视图?的主要内容,如果未能解决你的问题,请参考以下文章

我在自定义表格视图中有 FB 朋友的图像和名称。如何获取 FB ID 中的选定行并将请求发送给多个朋友?

如何将另一个类对象添加到列表中

如何从 mongodb 获取数据并使用节点 js 将其显示在表中?

使用 Iphone 应用程序在朋友 Facebook 墙上发帖

如何在应用程序中获取用户 Facebook 朋友的姓名、数量和 ID? [关闭]

好友列表的 SQL 加入帮助