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.
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 keyBeispiel: 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.