指标 (资料库)
资料指标(Data Cursor)或称游标,是在资料库引擎 (Database Engine)中,让开发人员或资料库管理员可以遍历、浏览检索结果的资料列(称为资料查询结果集, Result set),是主要用于在结果集中移动到某一资料列(row)的控制结构。游标可以被看作是指向一组列中,代表某一列的指针。游标一次只能引用一列,但可以根据需要移动到结果集的其他列。
游标有助于随检索之后的资料处理与遍历相结合,如添加和删除记录。它能遍历资料查询结果集的特性,类似于编程语言的迭代器概念。开发程序人员通常依需求而使用游标,来处理由资料库系统查询返回的整个结果集。在这种情况下,游标可使结果集中的资料列依照次序处理。在SQL程序中,使用游标可以定义检索集(多行资料列的条件选取组合)并逐行执行资料处理的逻辑。通过相同的机制,SQL程序也可将结果集直接返回给调用者或客户端应用程序;也常会被外部的资料存取介面所使用,像是 ADO、JDBC、 ADO.NET、PL-SQL 等都有资料指标的应用。
原理
资料指标是在资料库产生结果集时,由资料库引擎所产生的一个指标,用来指示目前正在存取的结果集的位置,经由这个指标,可以得到结果集中的资料列,并且可以依照需求来移动,但由于指标会占用伺服器的资源,并且在指标开启期间会启用共用锁定(Shared Lock),在多人使用的系统中容易造成死结的问题,因此目前大部份的应用程式都是使用仅前移型指标 (Forward-Only Cursor)。
种类
依照功能来区分,有四种[1]。
静态指标
静态指标 (Static Cursor) 是利用暂存资料表作为储存结果集空间的一种指标,它可以让应用程式可以快速的存取结果集,但在静态指标开启期间,任何对资料表所做的变更都不会反映在结果集中;同时,在静态指标中所作的修改,无法反映到资料库中,此种指标是消耗资源度第三的指标。
动态指标
动态指标 (Dynamic Cursor) 是可以反映资料库中修改的一种指标,不过它并不会让结果集的位置固定 (随机变动),因此无法确实的以指标位置来判断资料,并且它因为要随时反映资料库的变化,因此伺服器需要消耗较多的资源,此种指标是消耗资源第二高的指标。
索引键集型指标
索引键集指标 (Keyset Cursor) 是动态指标的强化版本,借由维护一个资料集位置对应表 (以 SQL Server 为例,会建立在 tempdb 的 keyset 资料表中),以维护在结果集中的顺序不受更新而变化,但这相对的也付出了伺服器效能和资源消耗的代价,因此索引键集指标是最消耗伺服器资源的一种指标,在实务上应避免使用。
仅前移型指标
仅前移型指标 (Forward-Only Cursor) 是一旦将指标往前移时,其走过的指标之前的结果集就会被舍弃,因此应用程式不能再往后移动指标,但也因此让伺服器只需要记住指标在结果集中目前的位置即可,这让它消耗的资源只有指标而已,是最省资源的一种指标,在实务中被广泛使用,像 ADO.NET 的 DataReader 就只限定只能使用 Forward-Only Cursor。
可卷动或不可卷动
资料库指标又分为可卷动性 (scrollable cursor) 指标与不可卷动性指标,可卷动性指标代表资料库指标可以依据指标的操作指令来移动,像是向前 (NEXT)、向后 (BACK)、朝指定位置移动等等性质。此种指标在执行资料库复制 (Replication) 时,是一个相当重要的能力,但可卷动性指标又会比不可卷动性指标消耗更多的资源。
缺点
资料库指标有三个缺点:
- 若在网路应用程式中使用,会造成大量的网路来回(Round-trip),让网路流量大增。
- 若在多人应用程式中大量使用指标,会造成大量的锁定,因此使用不当的话,让资料库发生死结的机率会大增。
- 在SQL预存程序或SQL预存函数使用时,如果在巢式回圈之中使用多个资料库指标,将使得资料的存取效能严重低落。