Statusdatenbank abfragen

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

Was ist die State Database?

Die aktuellen Zustandsdaten 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 Rich Querys mit der SQL Rich Query-Syntax und den Find-Ausdrücken CouchDB. 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 Folgendes sicherstellen:

  • Wenn Ihre Chaincodes SQL-reiche Abfragesyntax enthalten, werden diese Chaincodes nur auf Member-Peers installiert, die Oracle Blockchain Platform verwenden.

  • 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 CouchDB als Repository für die Statusdatenbank verwendet wird. Oracle Blockchain Platform kann CouchDB verarbeiten.

Wie funktioniert Oracle Blockchain Platform mit Berkeley DB?

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

Für jeden Kanal-Chaincode erstellt Oracle Blockchain Platform eine Berkeley-DB-Tabelle. Diese Tabelle speichert Statusinformationsdaten und enthält mindestens eine Schlüsselspalte mit dem Namen key und 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 Wertspalte im JSON-Format der Statustabelle.

Beachten Sie, dass die Spalten valueJson und value gegenseitig ausschließen. Wenn der Chaincode 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 Car Dealer-Beispiels:

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": "bremspad 4200", "eigentümer": "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 Abfragen analysieren. Das Dialogfeld Rich Abfragen analysieren wird angezeigt.
  3. Um eine Rich Query 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 abzufragenden Kanal bereitgestellt wird.
    2. Wählen Sie unter Peer den abzufragenden Peer aus.
      Nur Peers in der aktuellen Organisation, die den ausgewählten Chaincode ausführen, sind verfügbar.
    3. Geben Sie unter Rich Query die Rich Query ein, die ausgeführt und analysiert werden soll.
      Das Abfrageformat muss der Rich Query-Syntax entsprechen. 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 von Ergebniszeilen, die abgerufen werden sollen. 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 der Vorgänge, die zur Ausführung der Abfrage ausgeführt wurden.
    1. Wählen Sie unter Chaincode den Chaincode aus, der für den abzufragenden Kanal bereitgestellt wird.
    2. Wählen Sie unter Peer den abzufragenden Peer aus.
    3. Wählen Sie unter Collection die Statusdatenbank oder die private Datenerfassung aus.
    4. Geben Sie unter Rich Query die Rich Query ein.
      Das Schlüsselwort explain wird für diese Abfrage nicht benötigt.
      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 Größe der Ergebnistabelle ist auf 1 MB begrenzt. Möglicherweise müssen Sie Ihre Abfrage verfeinern, um ein Überschreiten dieses Limits zu vermeiden.

Unterstützte Rich Query-Syntax

Oracle Blockchain Platform unterstützt zwei Arten von umfangreichen Abfragesyntaxen, mit denen Sie die Statusdatenbank abfragen können: SQL-reiche Abfrage und CouchDB-reiche Abfrage.

SQL Rich Query-Syntax

Die Berkeley DB JSON-Erweiterungen haben die Form von SQL-Funktionen.

Bevor Sie beginnen

Beachten Sie die folgenden Informationen:

  • Sie können nur auf den Channel Chaincode (<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 Rich Query schreiben können. Sie haben Zugriff auf die übliche vollständige SQL-Syntax zum Abfragen einer SQL-Datenbank.
  • Sie haben Zugriff auf die Erweiterung JSON1 (Erweiterung SQLite). Siehe JSON1 Extension und SQL As Understanding by SQLite.

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

So verweisen Sie auf die Statusdatenbank in Abfragen

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

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

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

Alle Schlüssel abrufen

Verwenden Sie diese Syntax:

SELECT key FROM <STATE>

Beispiel: Wenn Sie diese Syntax zum Abfragen des Beispiels "Autohändler" verwenden, erhalten Sie die folgende Liste von Schlüsseln:

Schlüssel

abg1234

abg1235

ser1236

bra1238

dtrt10001

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

Verwenden Sie diese Syntax:

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

Beispiel: Wenn Sie diese Syntax zum Abfragen des Beispiels "Autohändler" verwenden, 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": "bremspad 4200", "eigentümer": "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 zum Abfragen des Beispiels "Autohändler" verwenden, 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 von "Detroit Auto" enthalten

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 zum Abfragen des Beispiels "Autohändler" verwenden, erhalten Sie die folgende Liste von Schlüsseln:

Schlüssel

abg1234

abg1235

ser1236

bra1238

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

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 zum Abfragen des Beispiels "Autohändler" verwenden, erhalten Sie die folgenden Ergebnisse:

Modell Hersteller
ein Coupé Detroit Auto

Wenn der Statuswert ein JSON-Array ist, können Sie mit dieser Syntax Modell und Hersteller für alle Fahrzeuge abrufen, die Eigentum von "Sam Dealer" sind:

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 Chaincodes mit 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, dass Sie SQL-reiche Abfragen verwenden, um die Performancevorteile zu nutzen, die Oracle Blockchain Platform mit Berkeley DB bietet.

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

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 Indizes aus, die für die betreffende StateDB definiert sind.

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

Ausdruck verwenden:

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

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

Ausdruck verwenden:

{ 
  "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, folgen jedoch ansonsten derselben CouchDB-Implementierung, die von Hyperledger Fabric bereitgestellt wird.

Mit benutzerdefinierten Indizes können Sie die Performance von WHERE- und ORDER BY-Anweisungen für große Datasets erheblich verbessern. Da die Verwendung von benutzerdefinierten Indizes das Einfügen von Daten verlangsamt, sollten Sie diese vorsichtig 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. Es gibt einen Index pro Datei. Sie müssen diese Datei mit dem Chaincode in einem Ordner namens indexes in der folgenden Verzeichnisstruktur verpacken: statedb/relationaldb/indexes. Weitere Informationen finden Sie unter How to add CouchDB indexes during chaincode installation.

Benutzerdefinierte Indizes – Beispiel

Die benutzerdefinierten Indexbeispiele in diesem Abschnitt verwenden das Beispiel "Händler".

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 wird sowohl der in Beispiel 1 beschriebene Index als auch der in Beispiel 2 beschriebene Index erstellt. Jede JSON-Struktur muss in einer separaten Datei enthalten sein. 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 AND-Ausdruck im WHERE-Teil der Abfrage angewendet, während Index 1 auf den ORDER BY-Ausdruck 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 einer umfangreichen Abfrage von CouchDB und die umfassende Abfrage von Oracle Berkeley DB anders.

In der Standard-Hyperledger Fabric mit CouchDB wird jedes von der Abfrage zurückgegebene Schlüssel- und Wertpaar zum Read-Set der Transaktion hinzugefügt und zur Validierungszeit und ohne erneute Ausführung der Abfrage validiert. In Berkeley DB wird das zurückgegebene Schlüssel-Wert-Paar nicht zum Read-Set hinzugefügt. Das Ergebnis der Rich-Abfrage wird jedoch 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 Rich-Abfrage geschützt und validiert wird, indem der Hashwert des Merkle-Baums zum Read-Set 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 Phantom-Lesevorgänge gekennzeichnet.