假设我有三个表(MySQL),一个用于用户,一个用于标记,最后一个用于加入它们(多对多关系):
create table user_tag(
user_id int unsigned not null,
tag_id int unsigned not null,
primary_key (user_id, tag_id)
);
我想从数据库中获取完整的用户列表(或至少其中许多用户)以及他们关联的标签。我使用PHP作为服务器语言。
所以我的问题是,执行一个SQL查询是否更好地获取所有这些信息:
select user.name, user.image, ..., tag.name from user, tag, user_tag
where user.user_id = user_tag.user_id and tag.tag_id = user_tag.tag_id;
或者更好的是为用户执行一个第一个查询,然后获取他们的标签:
select user.name, user.image, ... from user;
然后为每个用户:
select tag.name from tag, user_tag where tag.tag_id = user_tag.tag_id
and user_tag.user_id = $USERID;
我觉得第二个是更好的选择,但我担心对数据库的查询可能太多(请注意,这是一般设计示例,但此模式可以在具有不同表的数据库上多次出现)。 / p>
哪个更好?优点和缺点?其他方式?
由于
PS:请不要考虑SQL语法,我还没有对真实数据库进行检查,这只是设计问题,谢谢答案 0 :(得分:2)
我只考虑两个选项:
一个查询:
SELECT user.user_id, user.name, user.image, ..., tag.tag_id, tag.name
FROM user
LEFT JOIN user_tag ON user.user_id = user_tag.user_id
LEFT JOIN tag ON user_tag.tag_id=tag.tag_id
两个问题:
SELECT user_id, name, image, ...
FROM user
SELECT user_tag.user_id, tag.tag_id, tag.name
FROM user_tag
INNER JOIN tag ON user_tag.tag_id=tag.tag_id
如果你有100个用户,那么发出100次相同的查询是没有意义的。
当我只提取几列时,我通常会选择#1,否则我会选择#2。在这种情况下,您似乎正在检索一个非常完整的用户配置文件,因此#2听起来不错。
答案 1 :(得分:1)
这实际上取决于许多特定项目,数据库大小,数据大小,使用情况,并发查询数量.....
我建议您尝试(表现)每种方法并应用最符合您要求/需求的方法。
我99%的时间都会使用一个查询 - 如果你有所有的相关索引IMO它发送单个查询的速度要快得多....在编码,服务器响应和制作东西方面更快更容易阅读 - 你可以理解数据库结构,因为你可以看到连接 - 你可以在另一个查询中使用不同的alises,这可能看起来很混乱。
答案 2 :(得分:1)
对此没有简单的答案,因为这取决于您的架构。找出的最佳方法是在您的架构中对这两个解决方案进行基准测试。但是,如果在一个查询和多个查询之间进行选择,只要您的表被正确编入索引,那么我将使用一个查询解决方案。这样你就可以节省数据库连接和文件读取的开销。
答案 3 :(得分:0)
更多选项:
选项3:两个查询。首先获取所有用户:
select user.name, user.image, ...
from user
ORDER BY user_id;
然后获取所有用户的标记(并在PHP中合并2个查询):
select user_tag.user_id, tag.name
from tag
JOIN user_tag
ON tag.tag_id = user_tag.tag_id
GROUP BY tag.user_id
ORDER BY tag.user_id
, tag.name;
选项4.在一个查询中获取所有内容,每个用户一行:
SELECT user.name, user.image, ...
, GROUP_CONCAT(tag.name ORDER BY tag_name SEPARATOR ' ') AS tags
FROM user
LEFT JOIN user_tag
ON user_tag.user_id = user.user_id
LEF JOIN tag
ON tag.tag_id = user_tag.tag_id
GROUP BY user.user_id
ORDER BY user.user_id;