상태 데이터베이스 질의

이 항목에는 블록체인 원장의 현재 상태 데이터가 저장되는 상태 데이터베이스를 쿼리하는 방법을 이해하는 데 도움이 되는 정보가 포함되어 있습니다.

상태 데이터베이스란?

블록체인 원장의 현재 상태 데이터는 상태 데이터베이스에 저장됩니다.

Oracle Blockchain Platform 체인코드를 개발할 때 다양한 쿼리를 실행하여 상태 데이터베이스에서 데이터를 추출할 수 있습니다. Oracle Blockchain Platform은 SQL 서식 있는 쿼리 구문 및 CouchDB 찾기 표현식을 사용하여 다양한 쿼리를 지원합니다. SQL 서식 있는 질의 구문CouchDB 서식 있는 질의 구문을 참조하십시오.

Hyperledger Fabric은 SQL 리치 쿼리를 지원하지 않습니다. Oracle Blockchain Platform 네트워크에 Hyperledger Fabric 참가자가 포함되어 있는 경우 다음을 수행해야 합니다.

  • 체인코드에 SQL 서식 있는 질의 구문이 포함된 경우 해당 체인코드는 Oracle Blockchain Platform을 사용하는 멤버 피어에만 설치됩니다.

  • 체인코드를 Oracle Blockchain Platform 및 Hyperledger Fabric 피어에 설치해야 하는 경우 체인코드에서 CouchDB 구문을 사용하고 CouchDB을 상태 데이터베이스 저장소로 사용하도록 Hyperledger Fabric 피어가 설정되었는지 확인합니다. Oracle Blockchain Platform은 CouchDB를 처리할 수 있습니다.

Oracle Blockchain Platform은 Berkeley DB에서 어떻게 작동합니까?

Oracle Blockchain Platform은 Oracle Berkeley DB를 상태 데이터베이스로 사용합니다. Oracle Blockchain Platform은 SQLite 확장자를 기반으로 Berkeley DB에 관계형 테이블을 생성합니다. 이 아키텍처는 SQL 리치 쿼리를 검증할 수 있는 강력하고 성능이 뛰어난 방법을 제공합니다.

각 채널 체인 코드에 대해 Oracle Blockchain Platform은 Berkeley DB 테이블을 생성합니다. 이 테이블은 상태 정보 데이터를 저장하며, JSON 형식 데이터를 사용 중인지 여부에 따라 key라는 키 열과 value 또는 valueJson라는 값 열을 포함합니다.

열 이름 유형 설명
key TEXT 상태 테이블의 키 열입니다.
value TEXT 상태 테이블의 값 열입니다.
valueJson TEXT 상태 테이블의 JSON 형식 값 열입니다.

valueJsonvalue 열은 상호 배타적입니다. 따라서 체인코드가 키에 JSON 값을 지정하는 경우 valueJson 열은 해당 값을 보유하며 값 열은 널로 설정됩니다. 체인코드가 키에 비JSON 값을 지정하는 경우 valueJson 열이 널로 설정되고 값 열이 값을 보유합니다.

상태 데이터베이스의 예

다음은 자동차 딜러 샘플의 상태 데이터베이스의 키 및 해당 값의 예입니다.

value valueJson
abg1234 {"docType": "vehiclePart", "serialNumber": "abg1234", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "airbag 2020", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
abg1235 {"docType": "vehiclePart", "serialNumber": "abg1235", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "airbag 4050", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
ser1236 {"docType": "vehiclePart", "serialNumber": "ser1236", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "seatbelt 10020", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
bra1238 {"docType": "vehiclePart", "serialNumber": "bra1238", "assembler": "bobs-bits", "assemblyDate": 1502688979, "name": "brakepad 4200", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
dtrt10001 {"docType": "vehicle", "chassisNumber": "dtrt10001", "manufacturer": "Detroit Auto", "model": "a coupe", "assemblyDate": 1502688979, "airbagSerialNumber": "abg1235", "owner": "Sam Dealer", "recall": false, "recallDate": 1502688979

콘솔의 서식 있는 질의

관리자는 콘솔에서 다양한 쿼리를 실행하고 분석할 수 있습니다.

  1. 콘솔로 이동하여 Channels(채널) 탭을 선택합니다.
  2. 채널 테이블에서 쿼리를 실행할 채널을 찾고 채널 작업 더 보기 단추를 누른 다음 서식 있는 쿼리 분석을 누릅니다. 서식 있는 질의 분석 대화상자가 표시됩니다.
  3. 상태 데이터베이스에 대해 서식 있는 질의를 실행하려면 질의 실행을 선택합니다.
    1. 체인 코드의 경우 질의할 채널에 배치된 체인 코드를 선택합니다.
    2. 피어에서 질의할 피어를 선택합니다.
      선택한 체인코드를 실행 중인 현재 조직의 피어만 사용할 수 있습니다.
    3. 서식 있는 질의에 대해 실행 및 분석할 서식 있는 질의를 입력합니다.
      질의 형식은 서식 있는 질의 구문을 따라야 합니다. 서식 있는 조회 구문에 대한 자세한 내용은 지원되는 서식 있는 조회 구문을 참조하십시오.
    4. 결과 행 제한의 경우 슬라이더를 인출할 최대 결과 행 수로 이동합니다. 최대 50개 행의 결과를 인출할 수 있습니다.
  4. 질의에 대한 실행 계획을 가져오려면 질의 계획 설명을 선택합니다. 쿼리 실행 계획은 쿼리를 실행하기 위해 수행된 작업 순서입니다.
    1. 체인 코드의 경우 질의할 채널에 배치된 체인 코드를 선택합니다.
    2. 피어에서 질의할 피어를 선택합니다.
    3. 모음에 대해 상태 데이터베이스 또는 개인 데이터 수집을 선택합니다.
    4. 서식 있는 질의에 서식 있는 질의를 입력합니다.
      이 질의에는 explain 키워드가 필요하지 않습니다.
      예: select * from <state>
  5. 실행을 누릅니다. 결과 필드에는 질의 결과 테이블 또는 실행 계획이 표시됩니다. 결과 테이블을 .csv 파일로 익스포트하려면 익스포트를 누릅니다.
    결과 테이블 크기는 1MB로 제한됩니다. 이 제한을 초과하지 않도록 질의를 세분화해야 할 수도 있습니다.

지원되는 Rich Query 구문

Oracle Blockchain Platform은 상태 데이터베이스를 쿼리하는 데 사용할 수 있는 두 가지 유형의 서식 있는 쿼리 구문인 SQL 서식 있는 쿼리와 CouchDB 서식 있는 쿼리를 지원합니다.

SQL 서식 있는 질의 구문

Berkeley DB JSON 확장은 SQL 함수의 형태입니다.

시작하기 전에

다음 정보에 유의하십시오.

  • 질의를 실행 중인 채널 체인 코드(<STATE>)에만 액세스할 수 있습니다.
  • SELECT 문만 지원됩니다.
  • 상태 데이터베이스 테이블을 수정할 수 없습니다.
  • 서식 있는 질의 표현식은 하나의 SELECT 문만 가질 수 있습니다.
  • 이 항목의 예는 리치 쿼리를 작성할 수 있는 몇 가지 방법일 뿐입니다. SQL 데이터베이스를 쿼리하기 위해 일반적인 전체 SQL 구문에 액세스할 수 있습니다.
  • JSON1 확장(SQLite 확장)에 액세스할 수 있습니다. JSON1 확장SQL As Understood by SQLite을 참조하십시오.

체인코드 작성 및 테스트에 대한 자세한 내용은 체인코드 개발을 참조하십시오.

질의에서 상태 데이터베이스를 참조하는 방법

상태 데이터베이스 테이블 이름은 Oracle Blockchain Platform에서 내부적으로 관리되므로 체인코드를 작성할 때 상태 데이터베이스의 물리적 이름을 알 필요가 없습니다.

대신 <STATE> 별칭을 사용하여 테이블 이름을 참조해야 합니다. 예: select key, value from <STATE>.

<STATE> 별칭은 대소문자를 구분하지 않으므로 <state>, <STATE> 또는 <StAtE>와 같은 별칭을 사용할 수 있습니다.

모든 키 검색

다음 구문을 사용합니다.

SELECT key FROM <STATE>

예를 들어, 이 구문을 사용하여 자동차 딜러 샘플을 쿼리하면 다음 키 목록이 표시됩니다.

abg1234

abg1235

ser1236

bra1238

dtrt10001

키별로 알파벳순으로 정렬된 모든 키 및 값 검색

다음 구문을 사용합니다.

SELECT key AS serialNumber, valueJson AS details FROM  <state> ORDER BY key

예를 들어, 이 구문을 사용하여 자동차 딜러 샘플을 쿼리하면 다음과 같은 결과가 나타납니다.

serialNumber 세부정보
abg1234 {"docType": "vehiclePart", "serialNumber": "abg1234", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "airbag 2020", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
abg1235 {"docType": "vehiclePart", "serialNumber": "abg1235", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "airbag 4050", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
bra1238 {"docType": "vehiclePart", "serialNumber": "bra1238", "assembler": "bobs-bits", "assemblyDate": 1502688979, "name": "brakepad 4200", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
dtrt10001 {"docType": "vehicle", "chassisNumber": "dtrt10001", "manufacturer": "Detroit Auto", "model": "a coupe", "assemblyDate": 1502688979, "airbagSerialNumber": "abg1235", "owner": "Sam Dealer", "recall": false, "recallDate": 1502688979
ser1236 {"docType": "vehiclePart", "serialNumber": "ser1236", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "seatbelt 10020", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}

"abg"로 시작하는 모든 키 및 값 검색

다음 구문을 사용합니다.

SELECT key AS serialNumber, valueJson AS details FROM <state> WHERE key LIKE 'abg%'SELECT key, value FROM <STATE>

예를 들어, 이 구문을 사용하여 자동차 딜러 샘플을 쿼리하면 다음과 같은 결과가 나타납니다.

serialNumber 세부정보
abg1234 {"docType": "vehiclePart", "serialNumber": "abg1234", "assembler": "panama-parts", "assemblyDate": "1502688979", "name": "airbag 2020", "owner": "Detroit Auto", "recall": "false", "recallDate": "1502688979"}
abg1235 {"docType": "vehiclePart", "serialNumber": "abg1235", "assembler": "panama-parts", "assemblyDate": "1502688979", "name": "airbag 4050", "owner": "Detroit Auto", "recall": "false", "recallDate": "1502688979"}

"Detroit Auto"가 소유한 차량 부품이 포함된 값이 있는 모든 키 검색

다음 구문을 사용합니다.

SELECT key FROM <state> WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto'

예를 들어, 이 구문을 사용하여 자동차 딜러 샘플을 쿼리하면 다음 키 목록이 표시됩니다.

abg1234

abg1235

ser1236

bra1238

"Sam Dealer"가 소유한 모든 자동차에 대한 모델 및 제조업체 검색

다음 구문을 사용합니다.

SELECT json_extract(valueJson, '$.model') AS model, json_extract(valueJson, '$.manufacturer') AS manufacturer FROM <state> WHERE json_extract(valueJson, '$.docType') = 'vehicle' AND json_extract(valueJson, '$.owner') = 'Sam Dealer'

예를 들어, 이 구문을 사용하여 자동차 딜러 샘플을 쿼리하면 다음과 같은 결과가 나타납니다.

모델 제조업체
쿠페 자동 디트로이트

상태 값이 JSON 배열인 경우 이 구문을 사용하여 "Sam Dealer"가 소유한 모든 차량에 대한 모델 및 제조업체를 검색할 수 있습니다.

SELECT json_extract(j.value, '$.model') AS model, json_extract(j.value, '$.manufacturer') AS manufacturer FROM <state> s, json_each(json_extract(s.valueJson,'$')) j WHERE json_valid(j.value) AND json_extract(j.value, '$.owner') = 'Sam Dealer'

CouchDB 서식 있는 질의 구문

CouchDB 구문이 포함된 체인코드를 Oracle Blockchain Platform으로 마이그레이션하거나, Oracle Blockchain Platform 네트워크에 참여하는 Hyperledger Fabric 피어에 설치할 체인코드를 작성해야 하는 경우 이 항목의 정보를 사용합니다.

새 체인코드를 작성하는 경우 Oracle은 Oracle Blockchain Platform과 Berkeley DB가 제공하는 성능 이점을 활용하기 위해 SQL 리치 쿼리를 사용할 것을 권장합니다.

체인코드 작성 및 테스트에 대한 자세한 내용은 체인코드 개발을 참조하십시오.

지원되지 않는 질의 매개변수 및 선택기 구문

Oracle Blockchain Platformuse_index 매개변수를 지원하지 않습니다. 사용할 경우 Oracle Blockchain Platform은 이 매개변수를 무시하고 해당 StateDB에 정의된 인덱스를 자동으로 선택합니다.

매개변수 유형 설명
use_index json 특정 인덱스를 사용하도록 질의합니다.

자동차의 모든 모델, 제조업체 및 소유자 검색 및 소유자별 주문

다음 식을 사용합니다.

{ 
  "fields": ["model", "manufacturer", "owner"], 
  "sort": [   
    "owner" 
   ]
}

"Sam Dealer"가 소유한 모든 차량에 대한 모델 및 제조업체 검색

다음 식을 사용합니다.

{ 
  "fields": ["model", "manufacturer"], 
  "selector": {   
    "docType"  : "vehicle",
     "owner" : "Sam Dealer" 
  }
}

상태 데이터베이스 인덱스

상태 데이터베이스는 많은 양의 데이터를 포함할 수 있습니다. 이 경우 Oracle Blockchain Platform은 인덱스를 사용하여 데이터 액세스를 개선합니다.

기본 인덱스

체인코드가 배포되면 Oracle Blockchain Platform은 두 개의 인덱스를 생성합니다.

  • 키 인덱스 - 키 열에 생성됩니다.

  • 값 인덱스 - 값 열에 생성됩니다.

사용자 지정 인덱스

경우에 따라 사용자정의 인덱스를 생성해야 할 수도 있습니다. 이러한 인덱스는 상태 테이블의 컨텍스트에서 분석할 수 있는 표현식을 사용하여 정의합니다. Berkeley DB에 대해 생성된 사용자정의 인덱스는 SQLite 구문을 사용하지만, 그렇지 않으면 Hyperledger Fabric에서 제공하는 동일한 CouchDB 구현을 따릅니다.

커스텀 인덱스를 사용하여 대형 데이터 집합에 대한 WHERE 및 ORDER BY 문의 성능을 크게 향상시킬 수 있습니다. 사용자 지정 인덱스를 사용하면 데이터 삽입 속도가 느려지므로 신중하게 사용해야 합니다.

각 사용자 지정 인덱스는 하나의 파일 안에 JSON 문서로 표현되는 복합 인덱스를 지원하는 표현식 배열로 정의됩니다(파일당 하나의 인덱스가 있음). statedb/relationaldb/indexes 디렉토리 구조에서 "indexes"라는 폴더의 체인 코드를 사용하여 이 파일을 패키지화해야 합니다. 체인코드 설치 중 CouchDB 인덱스를 추가하는 방법을 참조하십시오.

사용자 정의 색인 예

이 섹션의 사용자 지정 색인 예에서는 자동차 딜러 샘플을 사용합니다.

예 1 - 이 예제는 WHERE 및 ORDER BY 표현식의 컨텍스트에서 json_extract 표현식 사용을 인덱스화합니다.

{"indexExpressions": ["json_extract(valueJson, '$.owner')"]}

예:

SELECT … FROM … ORDER BY json_extract(valueJson, '$.owner')

예 2 - 이 예제는 WHERE 및 ORDER BY 표현식 컨텍스트에서 두 개의 json_extract 표현식의 복합 사용을 인덱스화합니다.

{"indexExpressions": ["json_extract(valueJson, '$.docType')", "json_extract(valueJson, '$.owner')"]}

예:

SELECT … FROM … WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto'

예 3 - 이 예에서는 두 개의 인덱스를 생성합니다. 즉, 예제 1에 설명된 인덱스와 예제 2에 설명된 인덱스입니다. 각 JSON 구조는 별도의 파일에 포함되어야 합니다. 각 파일은 단일 인덱스(예제 1과 같은 단순 인덱스 또는 예제 2와 같은 복합 인덱스)를 설명합니다.

인덱스 1: {"indexExpressions": ["json_extract(valueJson, '$.owner')"]}

인덱스 2: {"indexExpressions": ["json_extract(valueJson, '$owner')", "json_extract(valueJson, '$.docType')"]}

다음 예에서는 인덱스 2가 질의의 WHERE 부분에 있는 AND 표현식에 적용되고 인덱스 1이 ORDER BY 표현식에 적용됩니다.

SELECT … FROM … WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto' ORDER BY json_extract(valueJson, '$.owner')

JSON 문서 형식

JSON 문서는 다음 형식이어야 합니다.

{"indexExpressions": [expr1, ..., exprN]}

예:

{"indexExpressions": ["json_extract(valueJson, '$.owner')"]}

서식 있는 질의 검증의 차이점

경우에 따라 CouchDB 리치 쿼리와 Oracle Berkeley DB 리치 쿼리가 있는 표준 Hyperledger Fabric이 다르게 동작합니다.

CouchDB가 있는 표준 Hyperledger Fabric에서는 쿼리에서 반환된 각 키와 값 쌍이 트랜잭션의 읽기 세트에 추가되고 검증 시 쿼리를 다시 실행하지 않고 검증됩니다. Berkeley DB에서 반환된 키와 값 쌍은 읽기 세트에 추가되지 않지만 서식 있는 쿼리의 결과는 Merkle 트리에서 해시되고 검증 시 쿼리의 재실행에 대해 검증됩니다.

Native Hyperledger Fabric은 풍부한 쿼리에 대한 데이터 보호를 제공하지 않습니다. 그러나 Berkeley DB에는 읽기 세트에 Merkle 트리 해시 값을 추가하고 서식 있는 질의를 재실행하며 검증 단계에서 Merkle 트리 값을 재계산하는 방식으로 서식 있는 질의를 보호하고 검증하는 기능이 포함되어 있습니다. Berkeley DB를 사용하는 Oracle Blockchain Platform에서는 검증이 더 정확하기 때문에 체인코드 호출이 더 자주 팬텀 읽기를 위해 플래그 지정되는 경우도 있습니다.