为啥查询的数据在结果集中返回而不是在数组中?
Posted
技术标签:
【中文标题】为啥查询的数据在结果集中返回而不是在数组中?【英文标题】:Why is queried data returned in a result set and not in an array?为什么查询的数据在结果集中返回而不是在数组中? 【发布时间】:2014-07-16 14:59:17 【问题描述】:为什么大多数编程语言在从数据库返回数据时都使用结果集的概念?为什么不直接以更常见的、立即可用的结构(如数组)返回结果?为什么在查询和能够更好地或必要地使用结果之间增加一层?
【问题讨论】:
【参考方案1】:数组只是数据的容器。结果集是一种更强大的抽象,它封装了数据库服务器和发出数据检索请求的客户端程序之间非常复杂的交互。
“立即可用”……这很幼稚。是的,当然,通常您只需要数据,而且通常一切顺利,结果集对象可能看起来有点障碍。但是您应该停下来想想您正在执行的数据检索背后的复杂性。
数据提取
第一个也是最重要的考虑因素是数组是包含所有行的所有数据的静态结构。虽然这对于小型查询来说似乎是一个很好的解决方案,但我向您保证,在大多数情况下并非如此。它假定获取所有数据只需要很少的时间和内存,但情况并非总是如此。
RDBMS 一次返回一行……这就是通常的工作方式。这样他们就可以为许多客户提供服务...您也可以取消您的数据检索...或者如果您占用太多资源,RDBMS 可能会让您失望。
结果集处理从后端获取一行或一页行或所有行的复杂性,可能会在内部缓存结果。然后它确实允许程序一次只访问一行数据,添加来回导航的方法,而不必考虑幕后发生的事情。这不是你通常知道的,但有很多优化和陷阱。
单向查询
如果单向执行,某些 RDBMS 上的某些查询会更有效。那就是你告诉服务器你永远不需要查找你已经获取的一行数据。但是结果集对象通常可以在内部缓存这些数据并允许程序导航回它(不会干扰服务器)。
可更新查询
一些 RDBMS 支持 SELECT FOR UPDATE。结果集对象通常可以允许程序修改获取的数据,然后在内部处理所有必要的操作,以在底层数据库上反映这些更新……在许多语言中,即使 RDBMS 不支持 SELECT FOR UPDATE,这也是可能的。
更好地处理异常
当您请求数据时,如果一切顺利,您会得到一个可以放入数组中的数据流……如果出现问题,您会得到一个需要处理不同结构的信息流。结果集对象可以为客户端程序提供结构化信息......并且还可以提供一种恢复方式。
我正在添加一些关于游标的更多信息,即使它与这个问题不太相关。通过使用 CURSOR 从服务器获取行。它通常包含 4 个步骤(声明游标,打开它,使用它来获取数据,然后关闭它)。声明和打开 CURSOR 会在服务器上分配资源,这些资源用于记住特定客户端要求的内容以及已经返回的数据。 FETCHing 允许导航结果集并检索另一行数据(不一定是下一行)。关闭游标告诉服务器您已完成该请求并允许它释放这些资源。
【讨论】:
很好的答案,谢谢!我不知道“RDBMS 一次返回一行”。您能否向我指出有关该主题的更多信息(当然,或者将其添加到您的答案中)? 这是一个艰难的...有很多来源,我不知道哪个是权威的。您可以查看 Terry Halpin 和 Tony Morgan 的“信息建模和关系数据库”。您需要寻找的是 CURSOR。【参考方案2】:因为数组需要一次分配所有内存,并立即提取所有结果。您可能希望流式传输数 TB 的数据。或者您可能希望停止提取结果并在中途中止查询。
另请注意,特定 API 公开查询结果的方式是任意的。您可以自己编写一个 API,将数据作为数组公开给您。这是 API 的创建者的设计选择。
【讨论】:
以上是关于为啥查询的数据在结果集中返回而不是在数组中?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 WMI 不会在 ManagementObjectCollection 中返回完整的结果集?
Grafana/InfluxDB:查询在面板中工作,而不是在变量中