你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

数据库游标

适用于:✅Azure 数据资源管理器

数据库游标 是一个数据库级对象,可用于多次查询数据库。 即使查询并行发生 data-appenddata-retention 操作,也会获得一致的结果。

数据库游标旨在解决两个重要方案:

  • 只要查询指示“同一数据集”,就能够多次重复相同的查询并获取相同的结果。

  • 能够进行“恰好一次”查询。 此查询仅“查看”上一个查询未看到的数据,因为数据当时不可用。 例如,通过查询,可以循环访问表中所有新到达的数据,而不必担心处理同一记录两次或错误跳过记录。

数据库游标以查询语言表示为 string类型的标量值。 实际值应被视为不透明,除了保存其值或使用以下游标函数之外,不支持任何其他操作。

游标函数

Kusto 提供了三个函数来帮助实现上述两种方案:

这两个特殊函数(cursor_aftercursor_before_or_at)也有副作用:使用时,Kusto 会将数据库游标的 当前值发出 到查询 @ExtendedProperties 结果集。 游标的属性名称为 Cursor,其值为单个 string

例如:

{"Cursor" : "636040929866477946"}

限制

数据库游标只能用于启用了 IngestionTime 策略 的表。 此类表中的每个记录都与引入记录时生效的数据库游标的值相关联。 因此,可以使用 ingestion_time() 函数。

除非数据库至少有一个表定义了 IngestionTime 策略,否则数据库游标对象没有有意义的值。 此值可以保证根据需要将引入历史记录更新到此类表和运行查询中,以引用此类表。 在其他情况下,它可能会更新或不更新。

引入过程首先提交数据,以便它可用于查询,然后只向每个记录分配实际游标值。 使用数据库游标引入后立即查询数据可能不会合并添加的最后一条记录,因为尚未分配游标值。 此外,重复检索当前数据库游标值可能会返回相同的值,即使引入是在两者之间完成的,因为只有游标提交可以更新其值。

如果记录直接引入到该表中,则基于数据库游标查询表只能保证“工作”(仅提供一次保证)。 如果使用盘区命令(例如 .move 盘区.replace 盘区 将数据移入表中;如果使用 .rename 表,则不能保证使用数据库游标查询此表以避免丢失任何数据。 这是因为在最初引入记录时分配记录的引入时间,在移动盘区操作期间不会更改。

将盘区移动到目标表中时,分配的游标值可能已经处理,数据库游标的下一个查询将错过新记录。

示例:完全处理记录一次

对于具有架构 [Name, Salary]的表 Employees,若要在将新记录引入表中时持续处理新记录,请使用以下过程:

// [Once] Enable the IngestionTime policy on table Employees
.set table Employees policy ingestiontime true

// [Once] Get all the data that the Employees table currently holds 
Employees | where cursor_after('')

// The query above will return the database cursor value in
// the @ExtendedProperties result set. Lets assume that it returns
// the value '636040929866477946'

// [Many] Get all the data that was added to the Employees table
// since the previous query was run using the previously-returned
// database cursor 
Employees | where cursor_after('636040929866477946') // -> 636040929866477950

Employees | where cursor_after('636040929866477950') // -> 636040929866479999

Employees | where cursor_after('636040929866479999') // -> 636040939866479000