我有一个对称用户关系表:
CREATE TABLE IF NOT EXISTS `friends` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_a` int(11) NOT NULL DEFAULT '0',
`user_b` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
此表包含以下信息:
- ID为1的用户是ID为2的用户的好友
- ID为3的用户是ID为1的用户的好友
得出结论:
- ID 为 1 的用户有 2 个朋友(ID 3 和 ID 2)
- 用户 ID 可以在 2 列中的任何一列中(参见用户 ID 1)
如何进行有效查询以检查用户 1 是否是用户 3 的朋友?
为什么我要问一种有效的方法?好吧,因为我有 3 种不同的解决方案(可能还有更多),但我正在努力选择最有效的解决方案。有什么帮助吗?
方法一:
SELECT user_b AS user_a
FROM friends
WHERE (user_a = :user_a AND user_b = :user_b)
UNION ALL
SELECT user_a
FROM friends
WHERE (user_b = :user_b AND user_a = :user_a)
方法二:
SELECT * FROM friends WHERE (user_a = :user_a AND user_b = :user_b) OR
(user_b = :user_a AND user_a = :user_b)
方法3:
SELECT user_a FROM (
SELECT user_b AS user_a
FROM friends
WHERE user_a = :user_a
UNION ALL
SELECT user_a
FROM friends
WHERE user_b = :user_a
) AS newtab WHERE newtab.user_a = :user_b;
PHP检查:
$my_id = 1;
$friend_id = 3;
$stmt = $dbh->prepare("SELECT ..."); // approach 1 or 2 or 3 or ...
$stmt->bindParam(':user_a', $my_id, PDO::PARAM_STR);
$stmt->bindParam(':user_b', $friend_id, PDO::PARAM_STR);
$stmt->execute();
if ($stmt->rowCount() > 0) {
echo "You are friends";}
else { echo "he is not your friend";}
性能方面 - 哪种方法更好?
编辑:
测试:
$start_2 = microtime(true);
for ($i = 1; $i <= 100; $i++) {
$stmt->execute();
}
$end_2 = microtime(true);
结果:
1:0.14095306396484
2:0.063449859619141
3:0.18946194648743