Cursori di database
Un cursore di database è un oggetto a livello di database che consente di eseguire più volte query su un database. Si ottengono risultati coerenti anche se sono data-append
presenti operazioni o data-retention
in parallelo con le query.
I cursori del database sono progettati per affrontare due scenari importanti:
Possibilità di ripetere la stessa query più volte e ottenere gli stessi risultati, purché la query indichi "stesso set di dati".
Possibilità di eseguire una query "esattamente una volta". Questa query visualizza solo i dati non visualizzati da una query precedente, perché i dati non erano disponibili. La query consente, ad esempio, di scorrere tutti i dati appena arrivati in una tabella senza timore di elaborare lo stesso record due volte o ignorare i record per errore.
Il cursore del database è rappresentato nel linguaggio di query come valore scalare di tipo string
. Il valore effettivo deve essere considerato opaco e non è disponibile alcun supporto per alcuna operazione diversa da salvare il valore o usare le funzioni cursori indicate di seguito.
Funzioni per i cursori
Kusto offre tre funzioni che consentono di implementare i due scenari precedenti:
cursor_current(): usare questa funzione per recuperare il valore corrente del cursore del database. È possibile usare questo valore come argomento per le due altre funzioni.
cursor_after(rhs:string): questa funzione speciale può essere usata nei record di tabella in cui è abilitato il criterio IngestionTime . Restituisce un valore scalare di tipo
bool
che indica se il valore del cursore del database del record viene restituito dopo il valore del cursore delingestion_time()
rhs
database.cursor_before_or_at(rhs:string): questa funzione speciale può essere usata nei record di tabella in cui è abilitato il criterio IngestionTime . Restituisce un valore scalare di tipo
bool
che indica se il valore del cursore del database delingestion_time()
record è precedente o al valore del cursore delrhs
database.
Le due funzioni speciali (cursor_after
e cursor_before_or_at
) hanno anche un effetto collaterale: quando vengono usate, Kusto genererà il valore corrente del cursore del database al @ExtendedProperties
set di risultati della query. Il nome della proprietà per il cursore è Cursor
e il relativo valore è un singolo string
oggetto .
Ad esempio:
{"Cursor" : "636040929866477946"}
Restrizioni
I cursori di database possono essere usati solo con le tabelle per cui è stato abilitato il criterio IngestionTime . Ogni record in una tabella di questo tipo è associato al valore del cursore di database attivo al momento dell'inserimento del record. Di conseguenza, è possibile usare la funzione ingestion_time().
L'oggetto cursore del database non contiene alcun valore significativo, a meno che il database non disponga di almeno una tabella con criteri Di inserimentoTime definiti. Questo valore viene sicuramente aggiornato, in base alle esigenze della cronologia di inserimento, in tali tabelle e nelle query eseguite, che fanno riferimento a tali tabelle. Potrebbe, o meno, essere aggiornato in altri casi.
Il processo di inserimento esegue innanzitutto il commit dei dati, in modo che sia disponibile per l'esecuzione di query e quindi assegna un valore di cursore effettivo a ogni record. Se si tenta di eseguire una query per i dati immediatamente dopo il completamento dell'inserimento usando un cursore di database, i risultati potrebbero non incorporare ancora gli ultimi record aggiunti, perché non sono ancora stati assegnati al valore del cursore. Inoltre, il recupero ripetuto del valore del cursore del database corrente potrebbe restituire lo stesso valore, anche se l'inserimento è stato eseguito tra, perché solo un commit del cursore può aggiornarne il valore.
L'esecuzione di query su una tabella basata su cursori di database è garantita solo per il "funzionamento" (fornendo garanzie di tipo exactly-once) se i record vengono inseriti direttamente in tale tabella. Se si usano comandi extent, ad esempio move extents.replace/extents per spostare i dati nella tabella o se si usa la tabella con estensione rename, non è garantito che non si verifichino errori di dati per l'esecuzione di query su questa tabella usando i cursori del database. Ciò è dovuto al fatto che il tempo di inserimento dei record viene assegnato all'inserimento iniziale e non cambia durante l'operazione degli extent di spostamento. Pertanto, quando gli extent vengono spostati nella tabella di destinazione, è possibile che il valore del cursore assegnato ai record in questi extent sia già stato elaborato (e la query successiva eseguita dal cursore del database perderà i nuovi record).
Esempio: Elaborazione di record una sola volta
Per una tabella Employees
con schema [Name, Salary]
, per elaborare continuamente nuovi record durante l'inserimento nella tabella, usare il processo seguente:
// [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
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per