2010-05-10 84 views
3

假设我有两个表:的Sql查询,组关系

Group 
(
    id integer primary key, 
    someData1 text, 
    someData2 text 
) 

GroupMember 
(
    id integer primary key, 
    group_id foreign key to Group.id, 
    someData text 
) 

我知道,我的SQL语法不正确:)希望是非常明显的。我的问题是这样的:我想加载一个组记录和与该组关联的所有GroupMember记录。正如我所看到的,有两种选择。

一个单一的查询:

SELECT Group.id, Group.someData1, Group.someData2 GroupMember.id, GroupMember.someData 
FROM Group INNER JOIN GroupMember ... 
WHERE Group.id = 4; 

两个查询:

SELECT id, someData2, someData2 
FROM Group 
WHERE id = 4; 

SELECT id, someData 
FROM GroupMember 
WHERE group_id = 4; 

第一溶液只有是一个数据库往返的优点,但是具有返回冗余数据的缺点(所有组数据为每个组成员重复)

第二种解决方案不会返回重复的数据,但会涉及到数据库的两次往返。

这里有什么可取的?我想有一些门槛,如果组大小变得足够大,返回所有冗余数据的成本将大于额外数据库调用所涉及的开销。我应该在这里考虑什么其他的东西?

感谢, 乔丹

+0

下面我回答,但你使用的是什么数据库? – Jeremy 2010-05-10 15:00:50

+0

我正在使用postgres。 – Jordan 2010-05-10 15:36:21

回答

3

如果你真的想要的结果加入,我相信它始终是更有效地做在服务器级别的加盟。 SQL处理器旨在匹配数据集。 如果您确实需要2个sql语句的结果,您总是可以在一个批处理中以分号分隔发送两个语句,并且返回两个结果集并返回一个往返数据库。

1

如果你每次都要向数据库发送一个单组记录,那么我会选择第二个选项。如果您正在检索多个组记录和关联的组成员记录,请使用联接,因为它会更快。

2

数据最终如何使用是一个重要和未知的因素。

我建议大多数应用程序的单一查询方法。正确的索引将使查询比两种查询方法更有效。

如果您需要选择多个组,则单个查询方法还具有保持有效的优势。

-2

在这样一个简单的查询中,我会尝试在一个查询中执行它。两次数据库调用的开销可能会超过查询中额外的SQL处理时间。

工会的条款会为你做到这一点:

SELECT id, someData1, someData2 
FROM Group 
WHERE id = 4 
UNION 
SELECT id, someData, null 
FROM GroupMember 
WHERE group_id = 4; 
+0

你会如何区分组别记录和其他?为什么你会认为这些列是兼容的? – JeffO 2010-05-10 15:06:26

+0

问题没有问区分组记录,并根据给定的资料,someData领域是没有指定长度的文本。 – 2010-05-10 15:10:56

0

一般而言,这取决于你想显示什么类型的数据。

如果您显示的是单个组及其所有成员,则两个选项之间的性能差异可以忽略不计。

如果您显示了许多组及其所有成员,则必须为每个后续组执行数据库往返操作的开销将超过您从接收少量数据获得的任何好处。

你可能想在你的推理

  • 结果集的大小要考虑一些其他的东西 - 对于许多团体和成员,你的结果集的大小可能成为大小的限制因素,以获取和保持它在记忆力增加。第二种选择可能会发生这种情况。您可能需要考虑分页数据,以便一次只检索某个子集。

  • 延迟加载 - 如果你只得到一些团体的成员,或用户请求的成员一组在同一时间,考虑延迟加载。这意味着只需要额外的查询就可以在需要时获取组的成员。这只在某些使用情况下才有意义,但它可能比预先检索所有数据更有效。

0

根据数据库的类型和您的前端应用程序,你可以回报一次旅行(在例如SQL Server 2005中存储过程)两个SQL语句的结果。

如果要创建一个需要从组表许多领域的报告,您可能不希望数据与第一查询量的增加。

如果这是某种类型的数据录入应用程序,您可能已经向用户展示了组数据,所以他们可以在where子句中填入组ID(或者最好通过某个参数),现在他们需要成员结果。

0

这真的,真的,真的取决于你使用会使数据。

如果您想组装一个邮件群组的成员列表,并且您需要为要发送给成员的每封信的群组名称,并且您没有用于群组级别,那么单个连接的查询很有意义。

但如果说,你的编码主从屏幕或报告,以及每个组的页面,并在本集团及会员级别显示信息,则两个单独的查询可能是最有用的。

除非您检索的数据量非常大(数以万计的每组数百个成员或类似数量级的组),否则您不太可能看到两种方法的性能差异很大。