Kursory bazy danych
Dotyczy:
azure Data Explorer
Kursor bazy danych jest obiektem na poziomie bazy danych, który umożliwia wielokrotne wykonywanie zapytań względem bazy danych. Uzyskujesz spójne wyniki, nawet jeśli istnieją operacje data-append
lub data-retention
wykonywane równolegle z zapytaniami.
Kursory bazy danych są przeznaczone do rozwiązywania dwóch ważnych scenariuszy:
Możliwość wielokrotnego powtarzania tego samego zapytania i uzyskiwania tych samych wyników, o ile zapytanie wskazuje "ten sam zestaw danych".
Możliwość tworzenia zapytania "dokładnie raz". To zapytanie "widzi" tylko dane, których poprzednie zapytanie nie widziało, ponieważ dane nie były wówczas dostępne. Zapytanie umożliwia iterowanie, na przykład przez wszystkie nowo przybyłe dane w tabeli bez obawy o przetwarzanie tego samego rekordu dwa razy lub pomijanie rekordów przez pomyłkę.
Kursor bazy danych jest reprezentowany w języku zapytań jako wartość skalarna typu string
. Wartość rzeczywista powinna być uważana za nieprzezroczystą i nie ma obsługi żadnej operacji innej niż zapisanie jej wartości lub użycie następujących funkcji kursora.
Funkcje kursora
Usługa Kusto udostępnia trzy funkcje ułatwiające zaimplementowanie dwóch powyższych scenariuszy:
cursor_current(): użyj tej funkcji, aby pobrać bieżącą wartość kursora bazy danych. Tej wartości można użyć jako argumentu do dwóch innych funkcji.
cursor_after(rhs:string) : tej specjalnej funkcji można używać w rekordach tabeli z włączonymi zasadamiIngestionTime. Zwraca wartość skalarną typu bool
wskazującą, czy wartość kursora bazy danychingestion_time()
rekordu pochodzi po wartości kursora bazy danychrhs
.cursor_before_or_at(rhs:string) : tej specjalnej funkcji można używać w rekordach tabeli z włączonymi zasadamiIngestionTime. Zwraca wartość skalarną typu bool
wskazującą, czy wartość kursora bazy danychingestion_time()
rekordu jest wcześniejsza, czy narhs
wartości kursora bazy danych.
Dwie specjalne funkcje (cursor_after
i cursor_before_or_at
) również mają efekt uboczny: Gdy są używane, Usługa Kusto emituje bieżącą wartość kursora bazy danych do zestawu wyników @ExtendedProperties
zapytania. Nazwa właściwości kursora jest Cursor
, a jego wartość jest jedną string
.
Na przykład:
{"Cursor" : "636040929866477946"}
Ograniczenia
Kursory bazy danych mogą być używane tylko z tabelami, dla których włączono zasady IngestionTime. Każdy rekord w takiej tabeli jest skojarzony z wartością kursora bazy danych, który obowiązywał podczas pozyskiwania rekordu.
W związku z tym można użyć funkcji
Obiekt kursora bazy danych nie zawiera znaczącej wartości, chyba że baza danych ma co najmniej jedną tabelę z zdefiniowaną
Proces pozyskiwania najpierw zatwierdza dane, tak aby był dostępny do wykonywania zapytań, a następnie przypisuje rzeczywistą wartość kursora do każdego rekordu. Wykonywanie zapytań o dane bezpośrednio po pozyskaniu przy użyciu kursora bazy danych może nie uwzględniać dodanych ostatnich rekordów, ponieważ wartość kursora nie została jeszcze przypisana. Ponadto pobieranie bieżącej wartości kursora bazy danych może wielokrotnie zwracać tę samą wartość, nawet jeśli pozyskiwanie zostało wykonane między, ponieważ tylko zatwierdzenie kursora może zaktualizować jego wartość.
Wykonywanie zapytań względem tabeli na podstawie kursorów bazy danych gwarantuje jedynie "pracę" (zapewniając dokładnie jednokrotne gwarancje), jeśli rekordy są pozyskiwane bezpośrednio do tej tabeli. Jeśli używasz poleceń zakresów, takich jak .move extents lub .replace extents, aby przenieść dane do tabeli, lub jeśli używasz .rename tabeli, wykonywanie zapytań względem tej tabeli przy użyciu kursorów bazy danych nie ma gwarancji, aby uniknąć braku żadnych danych. Dzieje się tak, ponieważ czas pozyskiwania rekordów jest przypisywany podczas początkowego pozyskiwania i nie zmienia się podczas operacji przenoszenia.
Gdy zakresy zostaną przeniesione do tabeli docelowej, przypisana wartość kursora mogła już zostać przetworzona, a następne zapytanie przez kursor bazy danych przegapi nowe rekordy.
Przykład: Przetwarzanie rekordów dokładnie raz
W przypadku tabeli Employees
ze schematem [Name, Salary]
, aby stale przetwarzać nowe rekordy podczas pozyskiwania ich do tabeli, użyj następującego 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
Powiązana zawartość
- cursor_current()
- cursor_before_or_at()
- cursor_after()
- zasad
IngestionTime