Databasecursors

Een databasecursor is een object op databaseniveau waarmee u meerdere keren een query kunt uitvoeren op een database. U krijgt consistente resultaten, zelfs als er of data-retention bewerkingen parallel met de query's worden data-append uitgevoerd.

Databasecursors zijn ontworpen voor twee belangrijke scenario's:

  • De mogelijkheid om dezelfde query meerdere keren te herhalen en dezelfde resultaten te krijgen, zolang de query 'dezelfde gegevensset' aangeeft.

  • De mogelijkheid om een 'exactly once'-query te maken. Deze query 'ziet' alleen de gegevens die een vorige query niet heeft gezien, omdat de gegevens toen niet beschikbaar waren. Met de query kunt u bijvoorbeeld alle nieuw aangekomen gegevens in een tabel doorlopen zonder dat u bang hoeft te zijn dat dezelfde record tweemaal wordt verwerkt of records per ongeluk worden overgeslagen.

De databasecursor wordt in de querytaal weergegeven als een scalaire waarde van het type string. De werkelijke waarde moet als ondoorzichtig worden beschouwd en er is geen ondersteuning voor een andere bewerking dan het opslaan van de waarde of het gebruik van de onderstaande cursorfuncties.

Cursorfuncties

Kusto biedt drie functies voor het implementeren van de twee bovenstaande scenario's:

  • cursor_current(): gebruik deze functie om de huidige waarde van de databasecursor op te halen. U kunt deze waarde gebruiken als argument voor de twee andere functies.

  • cursor_after(rhs:string):Deze speciale functie kan worden gebruikt voor tabelrecords waarvoor het beleid IngestionTime is ingeschakeld. Er wordt een scalaire waarde van het type bool geretourneerd die aangeeft of de waarde van ingestion_time() de databasecursor van de record na de waarde van de rhs databasecursor komt.

  • cursor_before_or_at(rhs:string): deze speciale functie kan worden gebruikt voor de tabelrecords waarvoor het beleid IngestionTime is ingeschakeld. Het retourneert een scalaire waarde van het type bool die aangeeft of de waarde van ingestion_time() de databasecursor van de record vóór of op de waarde van de rhs databasecursor komt.

De twee speciale functies (cursor_after en cursor_before_or_at) hebben ook een neveneffect: wanneer ze worden gebruikt, verzendt Kusto de huidige waarde van de databasecursor naar de @ExtendedProperties resultatenset van de query. De eigenschapsnaam voor de cursor is Cursoren de waarde ervan is één string.

Bijvoorbeeld:

{"Cursor" : "636040929866477946"}

Beperkingen

Databasecursors kunnen alleen worden gebruikt met tabellen waarvoor het ingestionTime-beleid is ingeschakeld. Elke record in een dergelijke tabel is gekoppeld aan de waarde van de databasecursor die van kracht was toen de record werd opgenomen. Als zodanig kan de functie ingestion_time() worden gebruikt.

Het databasecursorobject heeft geen zinvolle waarde, tenzij voor de database ten minste één tabel is gedefinieerd waarvoor een IngestionTime-beleid is gedefinieerd. Deze waarde wordt gegarandeerd, indien nodig door de opnamegeschiedenis, bijgewerkt in dergelijke tabellen en de query's die worden uitgevoerd, die verwijzen naar dergelijke tabellen. Het kan in andere gevallen wel of niet worden bijgewerkt.

Tijdens het opnameproces worden eerst de gegevens doorgevoerd, zodat deze beschikbaar zijn voor het uitvoeren van query's, en wordt vervolgens alleen een werkelijke cursorwaarde aan elke record toegewezen. Als u een query probeert uit te voeren op gegevens direct na voltooiing van de opname met behulp van een databasecursor, bevatten de resultaten mogelijk nog niet de laatste toegevoegde records, omdat aan deze nog geen cursorwaarde is toegewezen. Bovendien kan het herhaaldelijk ophalen van de huidige waarde van de databasecursor dezelfde waarde retourneren, zelfs als de opname tussendoor is uitgevoerd, omdat alleen een cursordoorvoering de waarde kan bijwerken.

Het uitvoeren van query's op een tabel op basis van databasecursors werkt alleen gegarandeerd (met exactly-once-garanties) als de records rechtstreeks in die tabel worden opgenomen. Als u gebiedsopdrachten gebruikt, zoals het verplaatsen van extents.replace-gebieden/ om gegevens naar de tabel te verplaatsen, of als u de tabel .rename gebruikt, mist het uitvoeren van query's op deze tabel met behulp van databasecursors geen gegevens. Dit komt doordat de opnametijd van de records wordt toegewezen wanneer deze in eerste instantie worden opgenomen en niet verandert tijdens de bewerking voor het verplaatsen van gebieden. Wanneer de gebieden naar de doeltabel worden verplaatst, is het daarom mogelijk dat de cursorwaarde die in deze gebieden aan de records is toegewezen, al is verwerkt (en de volgende query per databasecursor mist de nieuwe records).

Voorbeeld: records precies één keer verwerken

Voor een tabel Employees met schema [Name, Salary]gebruikt u het volgende proces om continu nieuwe records te verwerken wanneer deze in de tabel worden opgenomen:

// [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