Statusdatenbank abfragen

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

Was ist die State Database?

Die aktuellen Zustandsdaten des Blockchain-Ledgers werden in der Zustandsdatenbank 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 mit der SQL-Rich Query-Syntax und den Suchausdrü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 folgende Schritte ausführen:

  • 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 Syntax CouchDB in den Chaincodes, und bestätigen Sie, dass die Hyperledger Fabric-Peers so eingerichtet sind, dass CouchDB als Statusdatenbank-Repository 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 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 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 Spalte "Wert" der Statustabelle.
valueJson TEXT JSON-Formatwertspalte der Statustabelle.

Beachten Sie, dass die Spalten valueJson und value sich gegenseitig ausschließen. Wenn also 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

Dies sind Beispiele für Schlüssel und deren Werte aus der Statusdatenbank des Beispiels "Autohändler":

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": "brekepad 4200", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
dtrt10001 null (Nulldatentyp) {"docType": "Fahrzeug", "chassisNumber": "dtrt10001", "Hersteller": "Detroit Auto", "Modell": "ein Coupé", "assemblyDate": 1502688979, "airbagSerialNumber": "abg1235", "Eigentümer": "Sam-Händler", "Rückruf": falsch, "recallDate": 1502688979

Umfangreiche Abfragen in der Konsole

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

  1. Navigieren 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 auf Richling-Abfragen analysieren. Das Dialogfeld Rich Text-Abfragen analysieren wird angezeigt.
  3. Um eine umfassende 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 Peer aus, den Sie abfragen möchten.
      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 Maximale Zeilenanzahl für Ergebnisse 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 Reihenfolge der Vorgänge, 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 Peer aus, den Sie abfragen möchten.
    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 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 dieses Limit ü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 Berkeley DB JSON-Erweiterungen sind in 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 umfangreiche Abfrage schreiben können. Sie haben Zugriff auf die übliche vollständige SQL-Syntax, um eine SQL-Datenbank abzufragen.
  • Sie haben Zugriff auf die Erweiterung JSON1 (Erweiterung SQLite). Siehe Erweiterung JSON1 und SQL wie von SQLite verstanden.

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

So referenzieren Sie die Statusdatenbank in Abfragen

Der Name der Statusdatenbanktabelle wird intern von Oracle Blockchain Platform verwaltet, sodass Sie beim Schreiben eines Chaincodes nicht den physischen Namen der Statusdatenbank kennen müssen.

Stattdessen müssen Sie den Alias <STATE> verwenden, um auf den Tabellennamen zu verweisen. 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 <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 der Schlüssel:

Schlüssel

abg1234

abg1235

ser1236

bra1238

dtrt10001

Alle alphabetisch nach Schlüssel 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 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": "brekepad 4200", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
dtrt10001 {"docType": "Fahrzeug", "chassisNumber": "dtrt10001", "Hersteller": "Detroit Auto", "Modell": "ein Coupé", "assemblyDate": 1502688979, "airbagSerialNumber": "abg1235", "Eigentümer": "Sam-Händler", "Rückruf": falsch, "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 enthalten, das Eigentum von "Detroit Auto" 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 zum Abfragen des Beispiels "Autohändler" verwenden, erhalten Sie die folgende Liste der Schlüssel:

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 "JSON-Array" lautet, können Sie mit dieser Syntax Modell und Hersteller für alle Autos abrufen, die "Sam Dealer" gehören:

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 der CouchDB-Syntax in 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 Chaincodes 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 er wählt automatisch die Indizes aus, die in der betreffenden StateDB definiert sind.

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

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

Verwenden Sie diesen Ausdruck:

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

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

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 in der Schlüsselspalte erstellt.

  • Wertindex – Wird in der 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 Berkeley DB erstellt wurden, basieren auf der SQLite-Syntax, folgen aber ansonsten 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 drastisch zu verbessern. Da die Verwendung benutzerdefinierter Indizes das Einfügen von Daten verlangsamt, sollten Sie diese sorgfältig verwenden.

Jeder benutzerdefinierte Index wird als ein Array von Ausdrücken definiert, die zusammengesetzte Indizes unterstützen, die in einer Datei als JSON-Dokument ausgedrückt werden (beachten Sie, dass pro Datei ein Index vorhanden ist). Sie müssen diese Datei mit dem Chaincode in einem Ordner namens "indexes" in der folgenden Verzeichnisstruktur verpacken: statedb/relationaldb/indexes. Lesen Sie dazu How to add CouchDB indexes during chaincode installation.

Beispiel für benutzerdefinierte Indizes

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

Beispiel 1 – In diesem Beispiel wird die Verwendung des Ausdrucks json_extract im Kontext der Ausdrücke WHERE und ORDER BY 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 der WHERE- und ORDER BY-Ausdrücke 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 Hyperledger Fabric-Standardabfrage mit CouchDB Rich Query und die Rich Query von Oracle Berkeley DB unterschiedlich.

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

Native Hyperledger Fabric bietet keinen Datenschutz für umfangreiche Abfragen. Berkeley DB enthält jedoch Funktionen, mit denen die Rich Query geschützt und validiert wird, indem der Merkle-Baum-Hashwert in die Lesegruppe aufgenommen, die Rich Query 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 Chaincodeaufrufe manchmal für häufigere Phantomlesevorgänge gekennzeichnet.