Sdílet prostřednictvím


Kurzory databáze

Platí pro: ✅Azure Data Explorer

Kurzor databáze je objekt na úrovni databáze, který umožňuje dotazovat databázi vícekrát. Konzistentní výsledky získáte i v případě, že souběžně s dotazy probíhají data-append nebo data-retention operace.

Kurzory databáze jsou navržené tak, aby řešily dva důležité scénáře:

  • Možnost opakovat stejný dotaz několikrát a získat stejné výsledky, pokud dotaz označuje stejnou sadu dat.

  • Možnost vytvořit dotaz "přesně jednou". Tento dotaz zobrazuje pouze data, která předchozí dotaz neviděl, protože data pak nebyla k dispozici. Dotaz vám například umožňuje iterovat všechna nově příchozí data v tabulce bez obav o zpracování stejného záznamu dvakrát nebo vynechání záznamů omylem.

Kurzor databáze je reprezentován v dotazovacím jazyce jako skalární hodnota typu string. Skutečná hodnota by měla být považována za neprůhlenou a žádná jiná operace než uložení její hodnoty nebo použití následujících funkcí kurzoru neexistuje.

Funkce kurzoru

Kusto poskytuje tři funkce, které vám pomůžou implementovat dva výše uvedené scénáře:

  • cursor_current(): Pomocí této funkce načtěte aktuální hodnotu kurzoru databáze. Tuto hodnotu můžete použít jako argument pro dvě další funkce.

  • cursor_after(rhs:string): Tuto speciální funkci je možné použít u záznamů tabulky, které mají povolené zásady IngestionTime. Vrátí skalární hodnotu typu bool označující, zda hodnota kurzoru databáze ingestion_time() záznamu přichází za rhs hodnotu kurzoru databáze.

  • cursor_before_or_at(rhs:string): Tuto speciální funkci je možné použít u záznamů tabulky, které mají povolené zásady IngestionTime. Vrátí skalární hodnotu typu bool označující, jestli hodnota kurzoru databáze ingestion_time() záznamu předchází nebo na rhs hodnotě kurzoru databáze.

Dvě speciální funkce (cursor_after a cursor_before_or_at) mají také vedlejší efekt: Když se používají, Kusto vygeneruje aktuální hodnotu kurzoru databáze do @ExtendedProperties sady výsledků dotazu. Název vlastnosti kurzoru je Cursora jeho hodnota je jedna string.

Například:

{"Cursor" : "636040929866477946"}

Omezení

Kurzory databáze lze použít pouze s tabulkami, pro které je povolená zásada IngestionTime. Každý záznam v takové tabulce je přidružený k hodnotě kurzoru databáze, která byla platná při ingestování záznamu. Funkci ingestion_time() lze použít.

Objekt kurzoru databáze nemá žádnou smysluplnou hodnotu, pokud databáze nemá alespoň jednu tabulku, která má zásadu IngestionTime definována. Tato hodnota se zaručuje, že se podle potřeby aktualizuje podle historie příjmu dat do takových tabulek a spuštěných dotazů, které na takové tabulky odkazují. V jiných případech se může aktualizovat nebo nemusí.

Proces příjmu dat nejprve potvrdí data, aby byla k dispozici pro dotazování, a teprve potom každému záznamu přiřadí skutečnou hodnotu kurzoru. Dotazování na data bezprostředně po příjmu dat pomocí kurzoru databáze nemusí zahrnovat poslední přidané záznamy, protože hodnota kurzoru ještě nebyla přiřazena. Načítání aktuální hodnoty kurzoru databáze může také opakovaně vracet stejnou hodnotu, i když byl příjem dat proveden mezi, protože pouze potvrzení kurzoru může aktualizovat jeho hodnotu.

Dotazování na tabulku na základě kurzorů databáze je zaručeno, že "funguje" (poskytuje přesně jednou záruky), pokud se záznamy ingestují přímo do této tabulky. Pokud používáte příkazy rozsahů, například rozsahy .move nebo .replace rozsahy, přesunout data do tabulky, nebo pokud používáte .rename table, pak dotazování této tabulky pomocí kurzorů databáze není zaručeno, aby nedošlo k chybějícím datům. Důvodem je to, že čas příjmu dat záznamů je přiřazen při počátečním ingestování a během operace rozsahů přesunu se nemění.

Když se rozsahy přesunou do cílové tabulky, je možné, že přiřazená hodnota kurzoru už byla zpracována a další dotaz kurzorem databáze vynechá nové záznamy.

Příklad: Zpracování záznamů přesně jednou

Pro tabulku Employees se schématem [Name, Salary]můžete průběžně zpracovávat nové záznamy při jejich ingestování do tabulky pomocí následujícího procesu:

// [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
  • cursor_current()
  • cursor_before_or_at()
  • cursor_after()
  • zásad pro příjem dat