【问题标题】:What is the best way to handle (nested) record sets?处理(嵌套)记录集的最佳方法是什么?
【发布时间】:2009-04-03 06:45:04
【问题描述】:

将一对多关系从数据库服务器传递到客户端的最佳(更简洁、资源成本更低)的方法是什么?

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

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

  1. 检索所有作者,在客户端循环浏览他们并执行附加查询以获取所有书籍
  2. "SELECT a.* FROM author a, book b WHERE a.name like 'A%' and b.author_id = a.id"

第一个解决方案确实是数据库端密集型的(如果我有 1000 个作者,我必须执行 1001 个查询)。

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

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

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

有什么想法吗? 谢谢

编辑: 我正在使用 .net,所以 ado 的数据关系是一种选择。他们支持我的 oracle 和 mysql 吗?

【问题讨论】:

    标签: .net sql ado.net


    【解决方案1】:

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

    首先如何采集:

    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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

        • 我正在寻找一个可移植的解决方案,因为我在 .net 中开发,但连接到 ms-sql、oracle 和 mysql 数据库
        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          假设一个典型案例,您的数据量将主要在“图书”表中。采用最简单的解决方案,对于您希望对用户施加的任何显示尺寸而言,惩罚都是很小的 - 将两者结合在一起并返回单个行集,在“作者”列数据中具有一定量的冗余。其他解决方案需要多个查询,这在总体方案中在大多数情况下既昂贵又复杂。

          我的优先顺序通常是:提供最佳 UI 体验所需的内容,以最简单的实施方式构建(关于异常情况的正常免责声明决定了不寻常的设计)。

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-10-28
            • 1970-01-01
            • 2019-06-29
            • 2010-09-06
            • 2012-04-17
            • 2021-12-10
            • 2011-06-23
            • 2010-10-12
            相关资源
            最近更新 更多