处理(嵌套)记录集的最佳方法是什么?

时间:2009-04-03 06:45:05

标签: .net sql ado.net

将一对多关系从数据库服务器传递到客户端的最佳(更干净,资源更少)方法是什么?

想象一下,我有一个Author表和一个Book表。我想要检索名称以“a”开头的所有作者以及他们写的所有书籍。然后,在客户端生成一个对象数组“作者”,其“书籍”字段是一组对象“书籍”。

我想到的两个穷人解决方案是:

  1. 检索所有作者,在客户端上循环浏览并执行其他查询以获取所有书籍
  2. “SELECT a。* FROM author a,book b WHERE a.name like'A%'and b.author_id = a.id”
  3. 第一个解决方案实际上是数据库方面的密集型(如果我有1000个作者,我必须执行1001个查询)。

    第二个需要在客户端进行一些密集的工作,因为程序会解析结果,因为它具有每行重复的Author共同的数据。

    另一种解决方案是从存储过程返回多个记录集。我从来没有处理过多个记录集,我不确定所有的语言/适配器类都支持它们。

    当然,如果任何作者可以拥有书籍论文,并且每本书都可以有样本页面等,情况会变得更糟。

    有什么想法吗? 感谢

    编辑: 我正在使用.net,所以ado的datarelations是一个选项。他们支持我的oracle和mysql吗?

5 个答案:

答案 0 :(得分:2)

这里有两个问题。一个是如何最有效地收集数据,另一个是如何处理您收到的数据。

首先如何收集它:

SELECT a.* FROM Author a INNER JOIN Book b ON a.id=b.author_id WHERE left(a.name,1)='a'

喜欢非常昂贵,如果可以,请避免使用它。内连接是比较表最便宜的方法 - 特别是如果主键(id)和外键(author_id)上有索引 如果有作者没有书籍(我猜不会是作者),请使用LEFT JOIN(相同的语法只需将'inner'改为'left')

二。如果你正在谈论1000条记录,你可能会想到以两个单独的方式收集数据(比如你认为的第一选择),除非你希望用户永远等待页面加载。例如:用户选择以a开头并收到列表的所有作者 - 你甚至可以统计该作者的文章。

SELECT a.Name count(b.author_id) titles 
FROM Author a INNER JOIN Book b ON a.id=b.author_id 
WHERE left(a.name,1)='a'
GROUP BY a.Name

他们会看到

John Adam:  35 Titles
Jane Acaba: 18 Titles
Jim Allan:  3 Titles

然后,用户点击作者,加载该作者的书籍列表。

Jim Allan's Titles:
   Froggy went a court'n
   Death on the Nile
   Life in Africa

如果你希望它看起来像是完全一次拉,但你希望它快速过来使用xmlhttp或ajax来显示作者列表。这是另一个主题。 :)

我还应该补充说,存储过程是必须的。这将大大增加应用程序的可移植性以及大多数数据库的性能。

HTH

答案 1 :(得分:0)

我认为后者可能比前者更接近一个好的解决方案。

也就是说,您可能希望在客户端和数据库之间引入一个层 - 在数据库机器上 - 可以过滤并处理从DB到您选择的数据结构的行。

答案 2 :(得分:0)

这可能取决于RDBMS的选择,其中一些可能支持某些功能,可以启用您想要的功能,尽管该功能可能无法移植到另一个RDBMS。

例如,Microsoft SQL Server从SQL 2000开始支持SELECT FOR XML。当仔细精心制作XML模式(例如FOR XML EXPLICIT)时,这将完全符合您的要求 - 返回一个XML,它为您提供数据的层次结构。如果您还使用ADO.NET,并选择使用SqlDataAdaptor将其加载到DataSet中,则结果DataSet实际上已将所有数据设置到DataTable中,并在DataTable之间设置正确的DataRelations。但是,这可能是特定于MS-SQL的功能,而在另一个RDBMS中工作可能需要一些其他技术。

答案 3 :(得分:0)

我们使用多个记录集。如果您有另一个实体链接到作者,只需添加另一个记录集。不确定Oracle和MySQL,但是如果IDataReader的相应实现让NextResult()没有抛出NotSupportedException,那么这应该适用于它们。

答案 4 :(得分:0)

假设一个典型案例,您的数据量将主要位于“图书”表中。采用最简单的解决方案,对于您希望对用户造成的任何显示大小,惩罚较小 - 将两者连接在一起并返回单个行集,其中“Authors”列数据中包含一定量的冗余。其他解决方案需要多个查询,在整个方案中,在大多数情况下,这些查询都更加昂贵和复杂。

我的优先顺序通常是:提供最佳用户界面体验所需的内容,为最简单的实施而构建(通常的免责声明指出了不寻常的设计)。

这也可能最好地将您的数据策略与UI设计中的更改分离,因为所有内容都在一个易于导航的结果集中。