我有一个相当复杂的操作,我只想用一个SQL查询来执行,但我不确定这是否比将其分解为n个查询更好或更不优。基本上,我有一个名为“Users”的表,其中包含用户ID及其关联的fb_ids(id为pk,fb_id可以为null)。
+-----------------+
| id | .. | fb_id |
|====|====|=======|
| 0 | .. | 12345 |
| 1 | .. | 31415 |
| .. | .. | .. |
+-----------------+
我还有另一个名为“Friends”的表,它代表两个用户之间的朋友关系。这使用了他们的id(而不是他们的fb_ids),应该是双向关系。
+----------------+
| id | friend_id |
|====|===========|
| 0 | 1 |
| 1 | 0 |
| .. | .. |
+----------------+
// user 0 and user 1 are friends
所以这就是问题: 我们得到一个特定用户的id(“my_id”)和该用户的Facebook好友的数组(一个名为fb_array的fb_ids数组)。我们想要更新Friends表,以便将Facebook友谊作为我们用户之间的有效友谊。值得注意的是,并非所有的Facebook好友都会在我们的数据库中拥有一个帐户,所以应该忽略这些朋友。每次用户登录时都会调用此查询,以便在Facebook上添加任何新朋友时可以更新我们的数据。这是我写的查询:
INSERT INTO Friends (id, friend_id)
SELECT "my_id", id FROM Users WHERE id IN
(SELECT id FROM Users WHERE fb_id IN fb_array)
AND id NOT IN
(SELECT friend_id FROM Friends WHERE id = "my_id")
第一个IN子句的要点是获取所有也是你的Facebook好友的用户的子集,这是我担心的主要部分。因为fb_ids是作为数组给出的,所以我必须将所有id解析成一个由逗号分隔的巨大字符串,这些字符串组成“fb_array”。我担心这个IN子句有这么大的字符串的效率(用户可能在Facebook上有成百上千的朋友)。您能想出更好的方法来编写这样的查询吗?
同样值得注意的是,这个查询并没有保持朋友关系的双重性质,但这并不是我所担心的(为此扩展它将是微不足道的。)
答案 0 :(得分:1)
如果我没有弄错的话,如果您对组合UNIQUE
有(id, friend_id)
约束,则可以简化您的查询:
INSERT IGNORE INTO Friends
(id, friend_id)
SELECT "my_id", id
FROM Users
WHERE fb_id IN fb_array ;
您应该在User (fb_id, id)
上设置索引并测试效率。如果数组中的itmes数量太大(超过几千),则可能必须拆分数组并多次运行查询。配置文件包含您的数据和设置。
答案 1 :(得分:1)
取决于以下列是否可为空(值可以是NULL
):
SELECT DISTINCT
"my_id", u.id
FROM Users u
WHERE u.fb_id IN fb_array
AND u.id NOT IN (SELECT f.friend_id
FROM FRIENDS f
WHERE f.id = "my_id")
SELECT "my_id", u.id
FROM Users u
LEFT JOIN FRIENDS f ON f.friend_id = u.id
AND f.id = "my_id"
WHERE u.fb_id IN fb_array
AND f.fried_id IS NULL
欲了解更多信息:
上述两篇文章中的测试包含100万行,有10,000个不同的值。