首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何处理数据库中的大量结果集

如何处理数据库中的大量结果集
EN

Stack Overflow用户
提问于 2008-10-23 22:35:07
回答 10查看 15.3K关注 0票数 6

我正在设计一个多层数据库驱动的web应用程序- SQL关系数据库,Java用于中间服务层,web用于UI。语言并不重要。

中间服务层执行数据库的实际查询。UI只是请求特定的数据,并没有数据库支持的概念。

问题是如何处理大型数据集?UI请求数据,但结果可能很大,可能太大而无法放入内存。例如,一个街道标志应用程序可能有一个服务层:

代码语言:javascript
代码运行次数:0
运行
复制
StreetSign getStreetSign(int identifier)
Collection<StreetSign> getStreetSigns(Street street)
Collection<StreetSign> getStreetSigns(LatLonBox box)

UI层要求获得满足某些条件的所有街道标志。根据条件的不同,结果集可能会很大。UI层可能会将结果分成单独的页面(对于浏览器),或者只是将它们全部呈现出来(服务于Goolge Earth)。潜在的巨大结果集可能是性能和资源问题(内存不足)。

一种解决方案是不返回完全加载的对象(StreetSign对象)。而是返回某种结果集或迭代器,这些结果集或迭代器懒惰地加载每个对象。

另一种解决方案是更改服务API以返回所请求数据的子集:

代码语言:javascript
代码运行次数:0
运行
复制
Collection<StreetSign> getStreetSigns(LatLonBox box, int pageNumber, int resultsPerPage)

当然,UI仍然可以请求一个巨大的结果集:

代码语言:javascript
代码运行次数:0
运行
复制
getStreetSigns(box, 1, 1000000000)

我很好奇这个场景的标准行业设计模式是什么?

EN

回答 10

Stack Overflow用户

发布于 2008-10-23 23:39:05

第一个问题应该是:

用户需要或有能力管理这些数据量?

虽然结果集应该是分页的,但如果它的潜在大小如此之大,答案将是“可能不是”,因此UI不应该尝试显示它。

我在医疗保健系统的J2EE项目中工作,这些项目处理海量的存储数据,字面上是数百万的患者,访问,表单等,一般规则是不显示超过100或200行的任何用户搜索,建议用户,这些标准集产生更多的信息,他可以理解。

实现这一点的方法因项目而异,可以强制UI在启动查询之前向服务层询问查询的大小,或者如果结果集增长太多,也可以从服务层抛出异常(但是,这种方式将服务层与UI的有限实现耦合在一起)。

注意!这并不意味着服务层上的每个方法在其结果大小超过100时都必须抛出异常,这条通用规则只适用于直接显示给用户的结果集,这是将控件放在UI中而不是服务层的更好理由。

票数 6
EN

Stack Overflow用户

发布于 2008-10-23 23:33:56

对于这种情况,我见过的最常见的模式是某种分页,通常在服务器端进行,以减少通过网络发送的信息量。

下面是一个使用表变量(通常比临时表更快)的SQL Server 2000示例以及您的街道标志示例:

代码语言:javascript
代码运行次数:0
运行
复制
CREATE PROCEDURE GetPagedStreetSigns
(
  @Page int = 1,
  @PageSize int = 10
)
AS
  SET NOCOUNT ON

  -- This memory-variable table will control paging
  DECLARE @TempTable TABLE (RowNumber int identity, StreetSignId int)

  INSERT INTO @TempTable
  (
     StreetSignId
  )
  SELECT [Id]
  FROM   StreetSign
  ORDER BY [Id]

  -- select only those rows belonging to the requested page
  SELECT SS.*
  FROM   StreetSign SS
         INNER JOIN @TempTable TT ON TT.StreetSignId = SS.[Id]
  WHERE  TT.RowNumber BETWEEN ((@Page - 1) * @PageSize + 1) 
                      AND (@Page * @PageSize)

在SQL Server2005中,您可以更巧妙地使用诸如公用表表达式和新的SQL排名函数之类的东西。但是一般的主题是使用服务器只返回属于当前页面的信息。

请注意,如果您允许最终用户对正在查看的数据应用动态过滤器,则此方法可能会变得混乱。

票数 2
EN

Stack Overflow用户

发布于 2008-10-23 22:41:13

我想说的是,如果存在大量数据的可能性,那么就采用分页路线。

您仍然可以设置您不希望它们超过的最大值。

例如,所以使用15,30,50的页面大小...

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/231827

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档