데이터베이스 커서

데이터베이스 커서는 데이터베이스를 여러 번 쿼리할 수 있는 데이터베이스 수준 개체입니다. 쿼리와 병렬로 또는 작업이 발생하는 경우에도 data-appenddata-retention 일관된 결과를 얻을 수 있습니다.

데이터베이스 커서는 다음 두 가지 중요한 시나리오를 해결하도록 설계되었습니다.

  • 쿼리가 "동일한 데이터 집합"을 나타내는 한 동일한 쿼리를 여러 번 반복하고 동일한 결과를 가져올 수 있습니다.

  • "정확히 한 번" 쿼리를 만드는 기능입니다. 이 쿼리는 데이터를 사용할 수 없었기 때문에 이전 쿼리에서 볼 수 없었던 데이터만 "표시"합니다. 예를 들어 쿼리를 사용하면 동일한 레코드를 두 번 처리하거나 실수로 레코드를 건너뛸 걱정 없이 테이블에 새로 도착한 모든 데이터를 반복할 수 있습니다.

데이터베이스 커서는 쿼리 언어로 형식 string의 스칼라 값으로 표시됩니다. 실제 값은 불투명한 것으로 간주되어야 하며, 해당 값을 저장하거나 아래에 설명된 커서 함수를 사용하는 것 이외의 작업에 대한 지원은 없습니다.

커서 함수

Kusto는 위의 두 시나리오를 구현하는 데 도움이 되는 세 가지 함수를 제공합니다.

  • cursor_current(): 이 함수를 사용하여 데이터베이스 커서의 현재 값을 검색합니다. 이 값을 다른 두 함수의 인수로 사용할 수 있습니다.

  • cursor_after(rhs:string): 이 특수 함수는 IngestionTime 정책을 사용하도록 설정된 테이블 레코드에서 사용할 수 있습니다. 레코드의 데이터베이스 커서 값이 데이터베이스 커서 값 뒤에 오는 rhs 지 여부를 나타내는 형식 boolingestion_time() 스칼라 값을 반환합니다.

  • cursor_before_or_at(rhs:string): 이 특수 함수는 IngestionTime 정책을 사용하도록 설정된 테이블 레코드에서 사용할 수 있습니다. 레코드의 데이터베이스 커서 값이 데이터베이스 커서 값 앞이나 앞에 rhs 오는지 여부를 나타내는 형식 boolingestion_time() 스칼라 값을 반환합니다.

두 특수 함수(cursor_aftercursor_before_or_at)도 부작용이 있습니다. 이 함수를 사용하면 Kusto는 데이터베이스 커서의 현재 값을 쿼리의 결과 집합으로 @ExtendedProperties 내보냅니다. 커서의 속성 이름은 이며 Cursor해당 값은 단일 string입니다.

예를 들면 다음과 같습니다.

{"Cursor" : "636040929866477946"}

제한

데이터베이스 커서는 IngestionTime 정책이 사용하도록 설정된 테이블과만 사용할 수 있습니다. 이러한 테이블의 각 레코드는 레코드를 수집할 때 적용된 데이터베이스 커서 값과 연결됩니다. 따라서 ingestion_time() 함수를 사용할 수 있습니다.

데이터베이스에 IngestionTime 정책이 정의된 테이블이 하나 이상 없는 한 데이터베이스 커서 개체는 의미 있는 값을 보유하지 않습니다. 이 값은 수집 기록에서 필요에 따라 이러한 테이블을 참조하는 쿼리가 실행되는 테이블로 업데이트되도록 보장됩니다. 다른 경우에는 업데이트될 수도 있고 업데이트되지 않을 수도 있습니다.

수집 프로세스는 먼저 데이터를 커밋하여 쿼리에 사용할 수 있도록 한 다음 각 레코드에 실제 커서 값을 할당합니다. 데이터베이스 커서를 사용하여 수집 완료 직후 데이터를 쿼리하려고 하면 커서 값이 아직 할당되지 않았기 때문에 결과가 추가된 마지막 레코드를 아직 통합하지 않을 수 있습니다. 또한 현재 데이터베이스 커서 값을 반복적으로 검색하면 커서 커밋만 해당 값을 업데이트할 수 있으므로 그 사이에 수집이 수행된 경우에도 동일한 값이 반환될 수 있습니다.

데이터베이스 커서를 기반으로 테이블을 쿼리하는 것은 레코드가 해당 테이블에 직접 수집되는 경우에만 "작동"(정확히 한 번 보장)되도록 보장됩니다. 데이터를 테이블로 이동하기 위해 extents.replace/익스텐트 이동과 같은 익스텐트 명령을 사용하거나 .rename 테이블을 사용하는 경우 데이터베이스 커서를 사용하여 이 테이블을 쿼리하는 것이 데이터를 놓치지 않도록 보장되지 않습니다. 이는 레코드의 수집 시간이 처음 수집될 때 할당되고 이동 익스텐트 작업 중에 변경되지 않기 때문입니다. 따라서 익스텐스가 대상 테이블로 이동되면 이러한 익스텐트의 레코드에 할당된 커서 값이 이미 처리되었을 수 있습니다(데이터베이스 커서의 다음 쿼리는 새 레코드를 놓칠 수 있습니다).

예: 정확히 한 번 레코드 처리

스키마[Name, Salary]가 있는 테이블 Employees 의 경우 테이블에 수집될 때 새 레코드를 지속적으로 처리하려면 다음 프로세스를 사용합니다.

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