Interroger la base de données d'état
Cette rubrique contient des informations qui vous aideront à comprendre comment interroger la base de données d'état dans laquelle les données d'état actuelles du registre de chaîne de blocs sont stockées.
Qu'est-ce que la base de données d'État ?
Les données d'état actuelles du registre de chaîne de blocs sont stockées dans la base de données d'état.
Lorsque vous développez des codes chaîne Oracle Blockchain Platform, vous pouvez extraire des données de la base de données d'état en exécutant des requêtes enrichies. Oracle Blockchain Platform prend en charge les requêtes enrichies à l'aide de la syntaxe de requête enrichie SQL et des expressions de recherche CouchDB. Reportez-vous à Syntaxe de requête enrichie SQL et à CouchDBSyntaxe de requête enrichie.
Hyperledger Fabric ne prend pas en charge les requêtes enrichies SQL. Si votre réseau Oracle Blockchain Platform contient des participants Hyperledger Fabric, vous devez effectuer les opérations suivantes :
-
Si vos codes chaîne contiennent une syntaxe de requête SQL enrichie, ces codes chaîne sont installés uniquement sur les homologues membres à l'aide d'Oracle Blockchain Platform.
-
Si un code chaîne doit être installé sur des homologues Oracle Blockchain Platform et Hyperledger Fabric, utilisez la syntaxe CouchDB dans les codes chaîne et confirmez que les homologues Hyperledger Fabric sont configurés pour utiliser CouchDB en tant que référentiel de base de données d'état. Oracle Blockchain Platform peut traiter CouchDB.
Comment Oracle Blockchain Platform fonctionne-t-il avec Berkeley DB ?
Oracle Blockchain Platform utilise Oracle Berkeley DB comme base de données d'état. Oracle Blockchain Platform crée des tables relationnelles dans la base de données Berkeley en fonction de l'extension SQLite. Cette architecture offre un moyen robuste et performant de valider les requêtes SQL riches.
Pour chaque code chaîne de canal, Oracle Blockchain Platform crée une table de base de données Berkeley. Cette table stocke les données d'informations d'état et contient au moins une colonne de clé nommée key
et une colonne de valeur nommée value
ou valueJson
, selon que vous utilisez des données au format JSON ou non.
Nom de la colonne | Type | Description |
---|---|---|
key |
TEXT | Colonne de clé de la table d'état. |
value |
TEXT | Colonne de valeur de la table d'état. |
valueJson |
TEXT | Colonne de valeur de format JSON de la table d'état. |
Les colonnes valueJson
et value
sont mutuellement exclusives. Par conséquent, si le code chaîne affecte une valeur JSON à une clé, la colonne valueJson
contiendra cette valeur et la colonne de valeur sera définie sur NULL. Si le code chaîne affecte une valeur non JSON à une clé, la colonne valueJson
est définie sur NULL et la colonne de valeur contient la valeur.
Exemple de base de données d'état
Voici des exemples de clés et leurs valeurs provenant de la base de données d'état de l'exemple Car Dealer :
clé | value | valueJson |
---|---|---|
abg1234 | NULL | {"docType": "vehiclePart", "serialNumber": "abg1234", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "airbag 2020", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979} |
abg1235 | NULL | {"docType": "vehiclePart", "serialNumber": "abg1235", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "airbag 4050", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979} |
ser1236 | NULL | {"docType": "vehiclePart", "serialNumber": "ser1236", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "seatbelt 10020", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979} |
bra1238 | NULL | {"docType": "vehiclePart", "serialNumber": "bra1238", "assembler": "bobs-bits", "assemblyDate": 1502688979, "name": "brakepad 4200", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979} |
dtrt10001 | NULL | {"docType": "vehicle", "chassisNumber": "dtrt10001", "manufacturer": "Detroit Auto", "model": "a coupe", "assemblyDate": 1502688979, "airbagSerialNumber": "abg1235", "owner": "Sam Dealer", "recall": false, "recallDate": 1502688979 |
Requêtes enrichies dans la console
Les administrateurs peuvent exécuter et analyser des requêtes enrichies à partir de la console.
Syntaxe de requête enrichie prise en charge
Oracle Blockchain Platform prend en charge deux types de syntaxe de requête enrichie que vous pouvez utiliser pour interroger la base de données d'état : la requête enrichie SQL et la requête enrichie CouchDB.
Syntaxe de requête enrichie SQL
Les extensions JSON de Berkeley DB se présentent sous la forme de fonctions SQL.
Avant de commencer
Notez les informations suivantes :
- Vous pouvez uniquement accéder au code chaîne de canal (<STATE>) à partir duquel vous exécutez votre requête.
- Seule l'instruction SELECT est prise en charge.
- Vous ne pouvez pas modifier la table de base de données d'état.
- Une expression de requête enrichie ne peut comporter qu'une seule instruction SELECT.
- Les exemples de cette rubrique ne sont que quelques façons d'écrire votre requête enrichie. Vous avez accès à la syntaxe SQL complète habituelle pour interroger une base de données SQL.
- Vous avez accès à l'extension JSON1 (extension SQLite). Reportez-vous à Extension JSON1 et à SQL tel que compris par SQLite.
Si vous avez besoin d'informations supplémentaires sur l'écriture et le test de codes chaîne, reportez-vous à Développement de codes chaîne.
Référence à la base de données d'état dans les requêtes
Le nom de la table de base de données d'état est géré en interne par Oracle Blockchain Platform. Vous n'avez donc pas besoin de connaître le nom physique de la base de données d'état lorsque vous écrivez un code chaîne.
A la place, vous devez utiliser l'alias <STATE>
pour faire référence au nom de la table. Par exemple : select key, value from <STATE>
.
L'alias <STATE>
n'est pas sensible à la casse. Vous pouvez donc utiliser <state>
, <STATE>
ou un élément tel que <StAtE>
.
Extraire toutes les clés
Utilisez la syntaxe suivante :
SELECT key FROM <STATE>
Par exemple, si vous utilisez cette syntaxe pour interroger l'exemple Car Dealer, vous obtiendrez la liste de clés suivante :
clé
abg1234
abg1235
ser1236
bra1238
dtrt10001
Extraire toutes les clés et valeurs triées par ordre alphabétique par clé
Utilisez la syntaxe suivante :
SELECT key AS serialNumber, valueJson AS details FROM <state> ORDER BY key
Par exemple, si vous utilisez cette syntaxe pour interroger l'exemple Car Dealer, vous obtiendrez les résultats suivants :
serialNumber | détails |
---|---|
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} |
Extraire toutes les clés et valeurs commençant par "abg"
Utilisez la syntaxe suivante :
SELECT key AS serialNumber, valueJson AS details FROM <state> WHERE key LIKE 'abg%'SELECT key, value FROM <STATE>
Par exemple, si vous utilisez cette syntaxe pour interroger l'exemple Car Dealer, vous obtiendrez les résultats suivants :
serialNumber | détails |
---|---|
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"} |
Extraire toutes les clés avec des valeurs contenant une pièce de véhicule détenue par "Detroit Auto"
Utilisez la syntaxe suivante :
SELECT key FROM <state> WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto'
Par exemple, si vous utilisez cette syntaxe pour interroger l'exemple Car Dealer, vous obtiendrez la liste de clés suivante :
clé
abg1234
abg1235
ser1236
bra1238
Extraire le modèle et le fabricant de toutes les voitures appartenant à "Sam Dealer"
Utilisez la syntaxe suivante :
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'
Par exemple, si vous utilisez cette syntaxe pour interroger l'exemple Car Dealer, vous obtiendrez les résultats suivants :
modèle | fabricant |
---|---|
un coupé | Détroit Auto |
Si la valeur d'état est un tableau JSON, vous pouvez utiliser cette syntaxe pour extraire le modèle et le fabricant de toutes les voitures appartenant à "Sam Dealer" :
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'
CouchDBSyntaxe de requête enrichie
Utilisez les informations de cette rubrique si vous migrez vos codes chaîne contenant la syntaxe CouchDB vers Oracle Blockchain Platform ou si vous devez écrire des codes chaîne à installer sur des homologues Hyperledger Fabric participant à un réseau Oracle Blockchain Platform.
Si vous écrivez un nouveau code chaîne, Oracle vous recommande d'utiliser des requêtes enrichies SQL pour tirer parti des avantages d'Oracle Blockchain Platform avec Berkeley DB en matière de performances.
Si vous avez besoin d'informations supplémentaires sur l'écriture et le test de codes chaîne, reportez-vous à Développement de codes chaîne.
Paramètres de requête et syntaxe de sélecteur non pris en charge
Oracle Blockchain Platform ne prend pas en charge le paramètre use_index
. Si elle est utilisée, Oracle Blockchain Platform ignore ce paramètre et sélectionne automatiquement les index définis sur le fichier StateDB en question.
Paramètre | Type | Description |
---|---|---|
use_index | JSON | Demande à une requête d'utiliser un index spécifique. |
Extraire tous les modèles, fabricants et propriétaires de voitures, et les commander par propriétaire
Utilisez cette expression :
{
"fields": ["model", "manufacturer", "owner"],
"sort": [
"owner"
]
}
Extraire le modèle et le fabricant pour toutes les voitures appartenant à "Sam Dealer"
Utilisez cette expression :
{
"fields": ["model", "manufacturer"],
"selector": {
"docType" : "vehicle",
"owner" : "Sam Dealer"
}
}
Index de base de données d'état
La base de données d'état peut contenir une grande quantité de données. Dans ce cas, Oracle Blockchain Platform utilise des index pour améliorer l'accès aux données.
Index par défaut
Lorsqu'un code chaîne est déployé, Oracle Blockchain Platform crée deux index.
-
Index de clé : créé sur la colonne de clé.
-
Index de valeur - Créé sur la colonne de valeur.
Index personnalisés
Dans certains cas, vous devrez peut-être créer des index personnalisés. Vous définissez ces index à l'aide de n'importe quelle expression pouvant être résolue dans le contexte de la table d'état. Les index personnalisés créés par rapport à la base de données Berkeley reposent sur la syntaxe SQLite, mais ils suivent sinon la même implémentation CouchDB fournie par Hyperledger Fabric.
Notez que vous pouvez utiliser des index personnalisés pour améliorer considérablement les performances des instructions WHERE et ORDER BY sur les jeux de données volumineux. Comme l'utilisation d'index personnalisés ralentit les insertions de données, vous devez les utiliser judicieusement.
Chaque index personnalisé est défini comme un tableau d'expressions, qui prend en charge les index composés, exprimés sous la forme d'un document JSON dans un fichier (notez qu'il y a un index par fichier). Vous devez packager ce fichier avec le code chaîne dans un dossier nommé "indexes" dans la structure de répertoires suivante : statedb/relationaldb/indexes
. Reportez-vous à Ajout d'index CouchDB lors de l'installation du code chaîne.
Exemples d'index personnalisés
Les exemples d'index personnalisés de cette section utilisent l'exemple Concessionnaire automobile.
Exemple 1 : cet exemple indexe l'utilisation de l'expression json_extract
dans le contexte des expressions WHERE et ORDER BY.
{"indexExpressions": ["json_extract(valueJson, '$.owner')"]}
Exemple :
SELECT … FROM … ORDER BY json_extract(valueJson, '$.owner')
Exemple 2 - Cet exemple indexe l'utilisation composée des deux expressions json_extract
dans le contexte des expressions WHERE et ORDER BY.
{"indexExpressions": ["json_extract(valueJson, '$.docType')", "json_extract(valueJson, '$.owner')"]}
Exemple :
SELECT … FROM … WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto'
Exemple 3 - Cet exemple crée deux index : l'index décrit dans l'Exemple 1 et l'index décrit dans l'Exemple 2. Notez que chaque structure JSON doit être incluse dans un fichier distinct. Chaque fichier décrit un index unique : un index simple comme l'exemple 1 ou un index composé comme l'exemple 2.
Index 1 : {"indexExpressions": ["json_extract(valueJson, '$.owner')"]}
Index 2 : {"indexExpressions": ["json_extract(valueJson, '$owner')", "json_extract(valueJson, '$.docType')"]}
Dans l'exemple suivant, l'index 2 est appliqué à l'expression AND
dans la partie WHERE
de la requête, tandis que l'index 1 est appliqué à l'expression ORDER BY
:
SELECT … FROM … WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto' ORDER BY json_extract(valueJson, '$.owner')
Format de document JSON
Le document JSON doit avoir le format suivant :
{"indexExpressions": [expr1, ..., exprN]}
Exemple :
{"indexExpressions": ["json_extract(valueJson, '$.owner')"]}
Différences dans la validation des requêtes enrichies
Dans certains cas, Hyperledger Fabric standard avec requête enrichie CouchDB et la requête enrichie Oracle Berkeley DB se comportent différemment.
Dans Hyperledger Fabric standard avec CouchDB, chaque paire clé/valeur renvoyée par la requête est ajoutée au jeu de lecture de la transaction et validée au moment de la validation et sans réexécution de la requête. Dans Berkeley DB, la paire clé/valeur renvoyée n'est pas ajoutée au jeu de lecture, mais le résultat de la requête enrichie est haché dans un arbre Merkle et validé par rapport à la réexécution de la requête au moment de la validation.
Hyperledger Fabric natif ne fournit pas de protection des données pour les requêtes enrichies. Toutefois, Berkeley DB contient une fonctionnalité qui protège et valide la requête enrichie en ajoutant la valeur de hachage de l'arbre Merkle dans l'ensemble de lecture, en réexécutant la requête enrichie et en recalculant la valeur de l'arbre Merkle à l'étape de validation. Etant donné que la validation est plus précise dans Oracle Blockchain Platform avec Berkeley DB, les appels de code chaîne sont parfois signalés pour des lectures fantômes plus fréquentes.