Cursores de base de datos
Un cursor de base de datos es un objeto de nivel de base de datos que permite consultar una base de datos varias veces. Obtiene resultados coherentes incluso si hay data-append
o data-retention
operaciones que se producen en paralelo con las consultas.
Los cursores de base de datos están diseñados para abordar dos escenarios importantes:
La capacidad de repetir la misma consulta varias veces y obtener los mismos resultados, siempre y cuando la consulta indique "el mismo conjunto de datos".
La capacidad de realizar una consulta "exactamente una vez". Esta consulta solo "ve" los datos que no vio una consulta anterior, ya que los datos no están disponibles entonces. La consulta le permite iterar, por ejemplo, a través de todos los datos recién llegados de una tabla sin miedo a procesar el mismo registro dos veces o omitir registros por error.
El cursor de base de datos se representa en el lenguaje de consulta como un valor escalar de tipo string
. El valor real debe considerarse opaco y no hay compatibilidad con ninguna operación que no sea para guardar su valor o usar las siguientes funciones de cursor.
Funciones de cursor
Kusto proporciona tres funciones para ayudar a implementar los dos escenarios anteriores:
cursor_current(): use esta función para recuperar el valor actual del cursor de base de datos. Puede usar este valor como argumento para las otras dos funciones.
cursor_after(rhs:string) : esta función especial se puede usar en los registros de tabla que tienen habilitada la directiva ingestionTime de. Devuelve un valor escalar de tipo bool
que indica si el valor del cursor de base de datosingestion_time()
del registro viene después del valor del cursor de base de datosrhs
.cursor_before_or_at(rhs:string) : esta función especial se puede usar en los registros de tabla que tienen habilitada la directiva ingestionTime de. Devuelve un valor escalar de tipo bool
que indica si el valor del cursor de base de datosingestion_time()
del registro viene antes o en el valor del cursor de base de datosrhs
.
Las dos funciones especiales (cursor_after
y cursor_before_or_at
) también tienen un efecto secundario: Cuando se usan, Kusto emite el valor actual del cursor de base de datos al conjunto de resultados @ExtendedProperties
de la consulta. El nombre de propiedad del cursor es Cursor
y su valor es un solo string
.
Por ejemplo:
{"Cursor" : "636040929866477946"}
Restricciones
Los cursores de base de datos solo se pueden usar con tablas para las que está habilitada la directiva ingestionTime de
El objeto de cursor de base de datos no contiene ningún valor significativo a menos que la base de datos tenga al menos una tabla que tenga una directiva ingestionTime de definida. Este valor se garantiza que actualice, según sea necesario, en el historial de ingesta, en estas tablas y las consultas ejecutadas, que hacen referencia a dichas tablas. Es posible que, o no, se actualice en otros casos.
El proceso de ingesta confirma primero los datos, de modo que esté disponible para realizar consultas y solo asigna un valor de cursor real a cada registro. La consulta de datos inmediatamente después de la ingesta mediante un cursor de base de datos podría no incorporar los últimos registros agregados porque aún no se asignó el valor del cursor. Además, recuperar el valor actual del cursor de base de datos repetidamente podría devolver el mismo valor, incluso si la ingesta se realizó entre sí, ya que solo una confirmación del cursor puede actualizar su valor.
La consulta de una tabla basada en cursores de base de datos solo se garantiza que "funcione" (proporcionando garantías exactamente una vez) si los registros se ingieren directamente en esa tabla. Si usa comandos de extensiones, como .move extensiones o .replace extensiones para mover datos a la tabla o si usa tabla .rename, no se garantiza que consulte esta tabla mediante cursores de base de datos para evitar que falten datos. Esto se debe a que el tiempo de ingesta de los registros se asigna cuando se ingiere inicialmente y no cambia durante la operación de extensión de movimiento.
Cuando las extensiones se mueven a la tabla de destino, es posible que el valor del cursor asignado ya se haya procesado y la siguiente consulta del cursor de base de datos perderá los nuevos registros.
Ejemplo: Procesamiento de registros exactamente una vez
Para una tabla Employees
con el esquema [Name, Salary]
, para procesar continuamente nuevos registros a medida que se ingieren en la tabla, use el siguiente proceso:
// [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
Contenido relacionado
- cursor_current()
- cursor_before_or_at()
- cursor_after()
- de directiva ingestionTime de