Statusdatenbank abfragen

Dieses Thema enthält Informationen, mit denen Sie verstehen können, wie Sie die Statusdatenbank abfragen, in der die aktuellen Statusdaten des Blockchain-Ledgers gespeichert sind.

Was ist die State Database?

Die aktuellen Statusdaten des Blockchain-Ledgers werden in der Statusdatenbank gespeichert.

Wenn Sie Oracle Blockchain Platform-Kettencodes entwickeln, können Sie Daten aus der Statusdatenbank extrahieren, indem Sie umfangreiche Abfragen ausführen. Oracle Blockchain Platform unterstützt umfangreiche Abfragen, indem die SQL Rich Query-Syntax und die Find-Ausdrücke CouchDB verwendet werden. Siehe SQL Rich Query-Syntax und CouchDB Rich Query-Syntax.

Hyperledger Fabric unterstützt keine SQL-reichen Abfragen. Wenn Ihr Oracle Blockchain Platform-Netzwerk Hyperledger Fabric-Teilnehmer enthält, müssen Sie folgende Schritte ausführen:

  • Wenn Ihre Chaincodes eine SQL Rich Query-Syntax enthalten, werden diese Chaincodes nur auf Member Peers mit Oracle Blockchain Platform installiert.

  • Wenn ein Chaincode auf Oracle Blockchain Platform- und Hyperledger Fabric-Peers installiert werden muss, verwenden Sie die CouchDB-Syntax in den Chaincodes, und bestätigen Sie, dass die Hyperledger Fabric-Peers so eingerichtet sind, dass sie CouchDB als Statusdatenbank-Repository verwenden. Oracle Blockchain Platform kann CouchDB verarbeiten.

Wie funktioniert die Oracle Blockchain Platform mit der Berkeley DB?

Oracle Blockchain Platform verwendet Oracle Berkeley DB als Statusdatenbank. Oracle Blockchain Platform erstellt relationale Tabellen in der Berkeley DB basierend auf der Erweiterung SQLite. Diese Architektur bietet eine robuste und leistungsstarke Möglichkeit, SQL-reiche Abfragen zu validieren.

Für jeden Kanalkettencode erstellt Oracle Blockchain Platform eine Berkeley-DB-Tabelle. Diese Tabelle speichert Statusinformationsdaten und enthält mindestens eine Schlüsselspalte mit dem Namen key sowie eine Wertespalte mit dem Namen value oder valueJson, je nachdem, ob Sie Daten im JSON-Format verwenden.

Spaltenname Typ Beschreibung
key TEXT Schlüsselspalte der Statustabelle.
value TEXT Wertespalte der Statustabelle.
valueJson TEXT JSON-Formatwertspalte der Statustabelle.

Beachten Sie, dass die Spalten valueJson und value sich gegenseitig ausschließen. Wenn der Chaincode also einem Schlüssel einen JSON-Wert zuweist, enthält die Spalte valueJson diesen Wert, und die Wertespalte wird auf Null gesetzt. Wenn der Chaincode einem Schlüssel einen Nicht-JSON-Wert zuweist, wird die Spalte valueJson auf Null gesetzt, und die Wertespalte enthält den Wert.

Beispiel für eine Statusdatenbank

Beispiele für Schlüssel und deren Werte aus der Statusdatenbank des Autohändlers:

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

Rich-Abfragen in der Konsole

Administratoren können umfangreiche Abfragen über die Konsole ausführen und analysieren.

  1. Gehen Sie zur Konsole, und wählen Sie die Registerkarte Kanäle aus.
  2. Suchen Sie in der Kanaltabelle den Kanal, in dem Sie eine Abfrage ausführen möchten. Klicken Sie auf die Schaltfläche Weitere Aktionen für die Kanäle, und klicken Sie dann auf Rich Textabfragen analysieren. Das Dialogfeld Rich Abfragen analysieren wird angezeigt.
  3. Um eine Rich-Abfrage für die Statusdatenbank auszuführen, wählen Sie Abfrageausführung aus.
    1. Wählen Sie unter Chaincode den Chaincode aus, der für den Kanal bereitgestellt wird, den Sie abfragen möchten.
    2. Wählen Sie unter Peer den abzufragenden Peer aus.
      Es sind nur Gleichgestellte in der aktuellen Organisation verfügbar, die den ausgewählten Chaincode ausführen.
    3. Geben Sie unter Rich Query die Rich Query ein, die ausgeführt und analysiert werden soll.
      Das Abfrageformat muss der Rich Query-Syntax folgen. Weitere Informationen zur Rich Query-Syntax finden Sie unter Unterstützte Rich Query-Syntax.
    4. Verschieben Sie unter Ergebniszeilenlimit den Schieberegler auf die maximale Anzahl der abzurufenden Ergebniszeilen. Sie können bis zu 50 Ergebniszeilen abrufen.
  4. Um den Ausführungsplan für eine Abfrage abzurufen, wählen Sie Abfrageplan erläutern aus. Ein Abfrageausführungsplan ist die Abfolge von Vorgängen, die zum Ausführen der Abfrage ausgeführt wurden.
    1. Wählen Sie unter Chaincode den Chaincode aus, der für den Kanal bereitgestellt wird, den Sie abfragen möchten.
    2. Wählen Sie unter Peer den abzufragenden Peer aus.
    3. Wählen Sie unter Sammlung die Statusdatenbank oder die private Datenerfassung aus.
    4. Geben Sie unter Rich Query die Rich Query ein.
      Das Schlüsselwort explain ist für diese Abfrage nicht erforderlich.
      Beispiel: select * from <state>
  5. Klicken Sie auf Ausführen. Im Feld Ergebnisse wird die Abfrageergebnistabelle oder der Ausführungsplan angezeigt. Um die Ergebnistabelle als .csv-Datei zu exportieren, klicken Sie auf Exportieren.
    Die Ergebnistabellengröße ist auf 1 MB begrenzt. Möglicherweise müssen Sie Ihre Abfrage verfeinern, um zu vermeiden, dass dieser Grenzwert überschritten wird.

Unterstützte Rich Query-Syntax

Oracle Blockchain Platform unterstützt zwei Typen von Rich Query-Syntax, mit denen Sie die Statusdatenbank abfragen können: SQL Rich Query und CouchDB Rich Query.

SQL Rich Query-Syntax

Die JSON-Erweiterungen der Berkeley DB sind in Form von SQL-Funktionen ausgeführt.

Bevor Sie beginnen

Beachten Sie die folgenden Informationen:

  • Sie können nur auf den Kanalkettencode (<STATE>) zugreifen, von dem aus Sie die Abfrage ausführen.
  • Nur die SELECT-Anweisung wird unterstützt.
  • Sie können die Statusdatenbanktabelle nicht ändern.
  • Ein Rich Query-Ausdruck kann nur eine SELECT-Anweisung enthalten.
  • Die Beispiele in diesem Thema sind nur einige Möglichkeiten, wie Sie Ihre umfassende Abfrage schreiben können. Sie haben Zugriff auf die übliche vollständige SQL-Syntax, um eine SQL-Datenbank abzufragen.
  • Sie haben Zugriff auf die JSON1-Erweiterung (Erweiterung SQLite). Siehe JSON1 Extension und SQL, wie von SQLite verstanden.

Weitere Informationen zum Schreiben und Testen von Chaincodes finden Sie unter Kettencodes entwickeln.

Statusdatenbank in Abfragen referenzieren

Der Name der Statusdatenbanktabelle wird intern von Oracle Blockchain Platform verwaltet. Daher müssen Sie den physischen Namen der Statusdatenbank nicht kennen, wenn Sie einen Chaincode schreiben.

Stattdessen müssen Sie den Alias <STATE> verwenden, um den Tabellennamen zu referenzieren. Beispiel: select key, value from <STATE>.

Beachten Sie, dass beim Alias <STATE> die Groß-/Kleinschreibung nicht beachtet wird. Sie können also entweder <state>, <STATE> oder etwas wie <StAtE> verwenden.

Alle Schlüssel abrufen

Verwenden Sie diese Syntax:

SELECT key FROM <STATE>

Beispiel: Wenn Sie diese Syntax verwenden, um das Autohändlerbeispiel abzufragen, erhalten Sie die folgende Schlüsselliste:

Schlüssel

abg1234

abg1235

ser1236

bra1238

dtrt10001

Alle nach Schlüssel alphabetisch geordneten Schlüssel und Werte abrufen

Verwenden Sie diese Syntax:

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

Beispiel: Wenn Sie diese Syntax verwenden, um das Autohändlerbeispiel abzufragen, erhalten Sie die folgenden Ergebnisse:

serialNumber Details
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}

Alle Schlüssel und Werte ab "abg" abrufen

Verwenden Sie diese Syntax:

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

Beispiel: Wenn Sie diese Syntax verwenden, um das Autohändlerbeispiel abzufragen, erhalten Sie die folgenden Ergebnisse:

serialNumber Details
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"}

Alle Schlüssel mit Werten abrufen, die ein Fahrzeugteil enthalten, für das "Detroit Auto" verantwortlich ist

Verwenden Sie diese Syntax:

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

Beispiel: Wenn Sie diese Syntax verwenden, um das Autohändlerbeispiel abzufragen, erhalten Sie die folgende Schlüsselliste:

Schlüssel

abg1234

abg1235

ser1236

bra1238

Modell und Hersteller für alle Autos abrufen, die dem "Sam Dealer" gehören

Verwenden Sie diese Syntax:

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'

Beispiel: Wenn Sie diese Syntax verwenden, um das Autohändlerbeispiel abzufragen, erhalten Sie die folgenden Ergebnisse:

Modell Hersteller
ein Coupé Detroit Auto

Wenn der Statuswert JSON-Array ist, können Sie diese Syntax verwenden, um Modell und Hersteller für alle Autos abzurufen, die sich im Besitz von "Sam Dealer" befinden:

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 Rich Query-Syntax

Verwenden Sie die Informationen in diesem Thema, wenn Sie Ihre Chaincodes mit der CouchDB-Syntax zu Oracle Blockchain Platform migrieren oder Chaincodes schreiben müssen, um sie auf Hyperledger Fabric-Peers zu installieren, die an einem Oracle Blockchain Platform-Netzwerk teilnehmen.

Wenn Sie einen neuen Chaincode schreiben, empfiehlt Oracle, SQL-reiche Abfragen zu verwenden, um die Performancevorteile von Oracle Blockchain Platform mit Berkeley DB zu nutzen.

Weitere Informationen zum Schreiben und Testen von Chaincodes finden Sie unter Kettencodes entwickeln.

Nicht unterstützte Abfrageparameter und Selektorsyntax

Oracle Blockchain Platform unterstützt den Parameter use_index nicht. Bei Verwendung ignoriert Oracle Blockchain Platform diesen Parameter und wählt automatisch die in der betreffenden StateDB definierten Indizes aus.

Parameter Typ Beschreibung
use_index json Weist eine Abfrage an, einen bestimmten Index zu verwenden.

Alle Modelle, Hersteller und Besitzer von Autos abrufen und nach Eigentümer bestellen

Verwenden Sie diesen Ausdruck:

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

Modell und Hersteller für alle Autos im Besitz von "Sam Dealer" abrufen

Verwenden Sie diesen Ausdruck:

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

Statusdatenbankindizes

Die Statusdatenbank kann eine große Datenmenge enthalten. In solchen Fällen verwendet Oracle Blockchain Platform Indizes, um den Datenzugriff zu verbessern.

Standardindizes

Wenn ein Chaincode bereitgestellt wird, erstellt Oracle Blockchain Platform zwei Indizes.

  • Schlüsselindex - Wird für die Schlüsselspalte erstellt.

  • Wertindex - Wird für die Wertespalte erstellt.

Benutzerdefinierte Indizes

In einigen Fällen müssen Sie möglicherweise benutzerdefinierte Indizes erstellen. Sie definieren diese Indizes mit einem beliebigen Ausdruck, der im Kontext der Statustabelle aufgelöst werden kann. Benutzerdefinierte Indizes, die für die Berkeley DB erstellt wurden, basieren auf der SQLite-Syntax. Andernfalls folgen sie derselben CouchDB-Implementierung, die von Hyperledger Fabric bereitgestellt wird.

Beachten Sie, dass Sie benutzerdefinierte Indizes verwenden können, um die Performance von WHERE- und ORDER BY-Anweisungen für große Datasets erheblich zu verbessern. Da die Verwendung benutzerdefinierter Indizes Dateneinfügungen verlangsamt, sollten Sie sie sorgfältig verwenden.

Jeder benutzerdefinierte Index ist als ein Array von Ausdrücken definiert, die zusammengesetzte Indizes unterstützen, die als JSON-Dokument in einer Datei ausgedrückt werden (beachten Sie, dass es einen Index pro Datei gibt). Sie müssen diese Datei mit dem Chaincode in einem Ordner namens "Indizes" in der folgenden Verzeichnisstruktur verpacken: statedb/relationaldb/indexes. Siehe So fügen Sie CouchDB-Indizes während der Chaincode-Installation hinzu.

Beispiel für benutzerdefinierte Indizes

Die benutzerdefinierten Indexbeispiele in diesem Abschnitt verwenden das Autohändlerbeispiel.

Beispiel 1 - In diesem Beispiel wird die Verwendung des Ausdrucks json_extract im Kontext von WHERE- und ORDER BY-Ausdrücken indiziert.

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

Beispiel:

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

Beispiel 2 - In diesem Beispiel wird die zusammengesetzte Verwendung der beiden json_extract-Ausdrücke im Kontext von WHERE- und ORDER BY-Ausdrücken indiziert.

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

Beispiel:

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

Beispiel 3 - In diesem Beispiel werden zwei Indizes erstellt: der in Beispiel 1 beschriebene Index und der in Beispiel 2 beschriebene Index. Beachten Sie, dass jede JSON-Struktur in einer separaten Datei enthalten sein muss. Jede Datei beschreibt einen einzelnen Index: einen einfachen Index wie Beispiel 1 oder einen zusammengesetzten Index wie Beispiel 2.

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

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

Im folgenden Beispiel wird Index 2 auf den Ausdruck AND im Abschnitt WHERE der Abfrage angewendet, während Index 1 auf den Ausdruck ORDER BY angewendet wird:

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

JSON-Dokumentformat

Das JSON-Dokument muss das folgende Format aufweisen:

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

Beispiel:

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

Unterschiede bei der Validierung von Rich Queries

In einigen Fällen verhalten sich die Standard-Hyperledger Fabric mit CouchDB Rich Query und die Oracle Berkeley DB Rich Query unterschiedlich.

In der Standard-Hyperledger Fabric mit CouchDB wird jedes von der Abfrage zurückgegebene Schlüssel-Wert-Paar zum Leseset der Transaktion hinzugefügt und zur Validierungszeit validiert, ohne die Abfrage erneut auszuführen. In Berkeley DB wird das zurückgegebene Schlüssel-Wert-Paar nicht zum Leseset hinzugefügt, aber das Ergebnis der Rich-Abfrage wird in einem Merkle-Baum gehasht und anhand der erneuten Ausführung der Abfrage zur Validierungszeit validiert.

Native Hyperledger Fabric bietet keinen Datenschutz für umfangreiche Abfragen. Berkeley DB enthält jedoch Funktionen, mit denen die umfangreiche Abfrage geschützt und validiert wird, indem der Merkle-Baum-Hashwert zur Lesegruppe hinzugefügt, die Rich-Abfrage erneut ausgeführt und der Merkle-Baumwert in der Validierungsphase neu berechnet wird. Da die Validierung in Oracle Blockchain Platform mit Berkeley DB genauer ist, werden Chaincode-Aufrufe manchmal für häufigere Phantomlesevorgänge gekennzeichnet.