【问题标题】:best practice for SELECT JOIN WHERE querySELECT JOIN WHERE 查询的最佳实践
【发布时间】:2012-08-02 15:56:14
【问题描述】:

我有 2 个表,第一个称为 friendship,第二个称为 user,详细信息如下

friendship表字段:

uid1, uid2

user 表字段:

uid, username, primary_email, f_name, m_name, l_name, avatar, avatar_path

想法是当uid1 on friendship 表例如=1 时从user 表中获取所有朋友的详细信息,以下查询是这个想法的最佳实践吗?

SELECT 
   u.uid,
   u.username,
   u.primary_email,
   u.f_name,
   u.m_name,
   u.l_name,
   u.avatar,
   u.avatar_path 
FROM friendship AS f 
LEFT JOIN user AS u ON f.uid2=u.uid 
WHERE f.uid1=1

最佳实践是对单个查询使用联接还是使用 2 个查询,一个从友谊表中提取 id,第二个从用户表中提取每个 id 的详细信息,例如:-

SELECT uid2 from friendship WHERE uid1 =1

这个查询给了我 ids 2,4,6,5,9 的数组然后我在下面的查询中使用它

SELECT * from user WHERE uid IN (2,4,6,5,9)

最佳做法是什么?

【问题讨论】:

  • 你想知道有朋友的用户的名字和朋友的名字吗?还是只有朋友的名字?
  • @bluefeet 我想提取我朋友的所有详细信息

标签: mysql select join


【解决方案1】:

这个查询会给你主要人物的名字和他们朋友的名字:

create table users
(
    uid int,
    username varchar(10),
    fname varchar(10)
)

insert into users values(1, 'test', 'Jim')
insert into users values(2, 'blah', 'Tim')
insert into users values(3, 'xxx', 'Henry')
insert into users values(4, 'nada', 'Bob')

create table friendship
(
    uid1 int,
    uid2 int
)

insert into friendship values (1, 2)
insert into friendship values (1, 3)
insert into friendship values (2, 3)
insert into friendship values (3, 4)

select u2.uid personid
    , u2.fname personname
    , f.uid2 friendid
    , u1.username friendusername
    , u1.fname friendname
from users u1
inner join friendship f
    on u1.uid = f.uid2
left join users u2
    on f.uid1 = u2.uid

结果:

【讨论】:

  • 请注意,我使用代码为一个用户提取好友详细信息,而不是获取每个用户的所有好友
【解决方案2】:

你的“友谊”状态是定向的还是非定向的?即如果 user1 是 user2 的朋友,这意味着 user2 是 user1 的朋友?如果是这样,您必须更改您的ONWHERE 条件:

ON f.uid2 = u.uid OR f.uid1 = u.uid
WHERE u.uid = 1

除此之外,我认为该选择查询没有任何问题。

【讨论】:

  • 发现每个友谊都有两行 1->2 和 2->1
  • @MarcusAdams:在 WHERE 子句中使用 u.uid 不需要 OR
【解决方案3】:

如果您确定要使用所有数据,我会说在单个查询中提取结果是最佳做法。这将只需要一次访问数据库,而不是每个朋友一次(加上初始查询)。

但是请注意,由于您使用的是来自友谊的 LEFT OUTER JOIN,因此如果友谊表中没有对应的 uid 用户记录,则可能会返回 NULL 行。

尝试这样的 INNER JOIN:

SELECT 
   u.uid,
   u.username,
   u.primary_email,
   u.f_name,
   u.m_name,
   u.l_name,
   u.avatar,
   u.avatar_path 
FROM friendship AS f
JOIN `user` AS u
  ON u.uid = f.uid2
WHERE f.uid1 = 1

【讨论】:

  • 请注意,第二个查询会提取我使用 IN 所需的所有数据,因此无需遍历每个朋友
  • yes on query with join vs 2 simple queries 注意这个查询将被使用数千次​​pan>
  • @Dr_movi,JOIN 并不比两个简单的查询更有效。在内部,所有相同的工作都在进行。您是否暗示查询缓存可能能够弥补开销?如果是这样,我不得不说我从来没有赌过查询缓存。
猜你喜欢
  • 2013-05-10
  • 2014-01-31
  • 1970-01-01
  • 1970-01-01
  • 2013-10-02
  • 2013-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多