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