Interroger la base de données d'état

Cette rubrique contient des informations pour vous aider à comprendre comment interroger la base de données d'état où les données d'état courantes du livre de chaîne de blocs sont stockées.

Qu'est-ce que la base de données d'État?

Les données d'état courantes du livre blockchain sont stockées dans la base de données d'état.

Lorsque vous développez des codes de chaîne Oracle Blockchain Platform, vous pouvez extraire des données de la base de données d'état en exécutant des interrogations enrichies. Oracle Blockchain Platform prend en charge les interrogations enrichies à l'aide de la syntaxe d'interrogation enrichie SQL et des expressions de recherche CouchDB. Voir Syntaxe d'interrogation enrichie SQL et CouchDB Syntaxe d'interrogation enrichie.

Hyperledger Fabric ne prend pas en charge les interrogations SQL enrichies. Si votre réseau Oracle Blockchain Platform contient des participants Hyperledger Fabric, vous devez vous assurer d'effectuer les opérations suivantes :

  • Si vos codes de chaîne contiennent une syntaxe d'interrogation SQL enrichie, ces codes de chaîne ne sont installés que sur les pairs membres qui utilisent Oracle Blockchain Platform.

  • Si un code de chaîne doit être installé sur les pairs Oracle Blockchain Platform et Hyperledger Fabric, utilisez la syntaxe CouchDB dans les codes de chaîne et vérifiez que les pairs Hyperledger Fabric sont configurés pour utiliser CouchDB comme 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 fournit un moyen robuste et performant de valider les interrogations SQL riches.

Pour chaque chaîne de code 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 valeurs nommée value ou valueJson, selon que vous utilisez des données au format JSON.

Nom de colonne Type Description
key TEXT Colonne de clé de la table d'état.
value TEXT Colonne de valeurs de la table d'état.
valueJson TEXT Colonne de valeur de format JSON de la table d'état.

Notez que les colonnes valueJson et value sont mutuellement exclusives. Ainsi, si le code de chaîne affecte une valeur JSON à une clé, la colonne valueJson conserve cette valeur et la colonne de valeur est réglée à NULL. Si le code de chaîne affecte une valeur non JSON à une clé, la colonne valueJson est réglée à 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 de concessionnaire automobile :

key valeur valueJson
abg1234 nul {"docType": "vehiclePart", "serialNumber": "abg1234", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "airbag 2020", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
abg1235 nul {"docType": "vehiclePart", "serialNumber": "abg1235", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "airbag 4050", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
ser1236 nul {"docType": "vehiclePart", "serialNumber": "ser1236", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "seatbelt 10020", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
bra1238 nul {"docType": "vehiclePart", "serialNumber": "bra1238", "assembler": "bobs-bits", "assemblyDate": 1502688979, "name": "brakepad 4200", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
dtrt10001 nul {"docType": "vehicle", "chassisNumber": "dtrt10001", "manufacturer": "Detroit Auto", "model": "a coupe", "assemblyDate": 1502688979, "airbagSerialNumber": "abg1235", "owner": "Sam Dealer", "recall": false, "recallDate": 1502688979

Interrogations enrichies dans la console

Les administrateurs peuvent exécuter et analyser des interrogations enrichies à partir de la console.

  1. Allez à la console et sélectionnez l'onglet Canaux.
  2. Dans le tableau des canaux, localisez le canal dans lequel vous voulez exécuter une interrogation, cliquez sur le bouton Actions supplémentaires, puis sur Analyser les interrogations enrichies. La boîte de dialogue Analyser les interrogations enrichies est affichée.
  3. Pour exécuter une interrogation enrichie sur la base de données d'état, sélectionnez Exécution d'interrogation.
    1. Pour le code de chaîne, sélectionnez le code de chaîne déployé sur le canal à interroger.
    2. Pour Pair, sélectionnez le pair à interroger.
      Seuls les pairs de l'organisation courante qui exécutent le code de chaîne sélectionné sont disponibles.
    3. Pour Interrogation enrichie, entrez l'interrogation enrichie à exécuter et analyser.
      Le format d'interrogation doit respecter la syntaxe d'interrogation enrichie. Pour plus d'informations sur la syntaxe d'interrogation enrichie, voir Syntaxe d'interrogation enrichie prise en charge.
    4. Pour Limite de rangées de résultat, déplacez le curseur vers le nombre maximal de rangées de résultat à extraire. Vous pouvez extraire jusqu'à 50 rangées de résultats.
  4. Pour obtenir le plan d'exécution d'une interrogation, sélectionnez Explication du plan d'interrogation. Un plan d'exécution d'interrogation est la séquence des opérations qui ont été effectuées pour exécuter l'interrogation.
    1. Pour le code de chaîne, sélectionnez le code de chaîne déployé sur le canal à interroger.
    2. Pour Pair, sélectionnez le pair à interroger.
    3. Pour Collecte, sélectionnez la base de données d'état ou la collecte de données privée.
    4. Pour Interrogation enrichie, entrez l'interrogation enrichie.
      Le mot clé explain n'est pas nécessaire pour cette interrogation.
      Par exemple : select * from <state>
  5. Cliquez sur Exécuter. Le champ Résultats affiche la table des résultats d'interrogation ou le plan d'exécution. Pour exporter la table des résultats en tant que fichier .csv, cliquez sur Exporter.
    La taille de la table des résultats est limitée à 1 Mo. Vous devrez peut-être préciser votre interrogation pour éviter de dépasser cette limite.

Syntaxe Rich Query prise en charge

Oracle Blockchain Platform prend en charge deux types de syntaxe d'interrogation enrichie que vous pouvez utiliser pour interroger la base de données d'état : l'interrogation enrichie SQL et l'interrogation enrichie CouchDB.

Syntaxe d'interrogation enrichie SQL

Les extensions JSON de Berkeley DB se présentent sous la forme de fonctions SQL.

Étapes préliminaires

Notez les informations suivantes :

  • Vous pouvez uniquement accéder au code de chaîne de canal (<STATE>) à partir duquel vous exécutez votre interrogation.
  • Seule l'instruction SELECT est prise en charge.
  • Vous ne pouvez pas modifier la table de base de données d'état.
  • Une expression d'interrogation enrichie ne peut avoir 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). Voir Extension JSON1 et SQL As Understanding par SQLite.

Pour plus d'informations sur l'écriture et le test de codes de chaîne, voir Développer des codes de chaîne.

Comment se référer à la base de données d'état dans les interrogations

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 de chaîne.

À la place, vous devez utiliser l'alias <STATE> pour référencer le nom de la table. Par exemple : select key, value from <STATE>.

Notez que l'alias <STATE> n'est pas sensible à la casse. Vous pouvez donc utiliser <state>, <STATE> ou quelque chose comme <StAtE>.

Extraire toutes les clés

Utilisez cette syntaxe :

SELECT key FROM <STATE>

Par exemple, si vous utilisez cette syntaxe pour interroger l'exemple de concessionnaire automobile, vous obtiendrez la liste de clés suivante :

clé

abg1234

abg1235

ser1236

bra1238

dtrt10001

Extraire toutes les clés et valeurs triées alphabétiquement par clé

Utilisez cette syntaxe :

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

Par exemple, si vous utilisez cette syntaxe pour interroger l'exemple de concessionnaire automobile, 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 cette syntaxe :

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 de concessionnaire automobile, 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 cette syntaxe :

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 de concessionnaire automobile, vous obtiendrez la liste de clés suivante :

clé

abg1234

abg1235

ser1236

bra1238

Extraire le modèle et le fabricant pour toutes les voitures appartenant à "Sam Dealer"

Utilisez cette syntaxe :

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 de concessionnaire automobile, vous obtiendrez les résultats suivants :

modèle Fabricant
un coupé Auto Détroit

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'

CouchDB Syntaxe d'interrogation enrichie

Utilisez les informations de cette rubrique si vous migrez vos codes de chaîne contenant la syntaxe CouchDB vers Oracle Blockchain Platform ou si vous devez écrire des codes de chaîne à installer sur des pairs Hyperledger Fabric participant à un réseau Oracle Blockchain Platform.

Si vous écrivez un nouveau code de chaîne, Oracle recommande d'utiliser des interrogations SQL enrichies pour tirer parti des avantages en matière de performance qu'offre Oracle Blockchain Platform avec Berkeley DB.

Pour plus d'informations sur l'écriture et le test de codes de chaîne, voir Développer des codes de chaîne.

Paramètres d'interrogation et syntaxe de sélecteur non pris en charge

Oracle Blockchain Platform ne prend pas en charge le paramètre use_index. S'il est utilisé, Oracle Blockchain Platform ignore ce paramètre et sélectionne automatiquement les index définis sur StateDB en question.

Paramètre Type Description
use_index JSON Indique à une interrogation 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" 
   ]
}

Récupérer le modèle et le fabricant pour toutes les voitures détenues par "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 de tels cas, Oracle Blockchain Platform utilise des index pour améliorer l'accès aux données.

Index par défaut

Lorsqu'un code de 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 qui peut être résolue dans le contexte de la table d'état. Les index personnalisés créés sur la base de données Berkeley reposent sur la syntaxe SQLite, mais ils suivent sinon la même mise en oeuvre 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. Etant donné que 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 prennent en charge les index composés, exprimés en tant que document JSON dans un fichier (notez qu'il y a un index par fichier). Vous devez encapsuler ce fichier avec le code de chaîne dans un dossier nommé "index" dans la structure de répertoires suivante : statedb/relationaldb/indexes. Voir Comment ajouter des index CouchDB lors de l'installation du code de chaîne.

Exemples d'index personnalisés

Les exemples d'index personnalisés de cette section utilisent l'exemple Car Dealer.

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')"]}

Par 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')"]}

Par 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 l'interrogation, 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]}

Par exemple :

{"indexExpressions": ["json_extract(valueJson, '$.owner')"]}

Différences dans la validation des interrogations enrichies

Dans certains cas, la structure Hyperledger Fabric standard avec l'interrogation enrichie CouchDB et l'interrogation enrichie Oracle Berkeley DB se comportent différemment.

Dans Hyperledger Fabric standard avec CouchDB, chaque paire clé-valeur retournée par l'interrogation est ajoutée au jeu de lecture de la transaction et validée au moment de la validation et sans réexécuter l'interrogation. Dans Berkeley DB, la paire clé-valeur retournée n'est pas ajoutée au jeu de lectures, mais le résultat de l'interrogation enrichie est haché dans un arbre Merkle et validé par rapport à la réexécution de l'interrogation au moment de la validation.

Native Hyperledger Fabric ne fournit pas la protection des données pour les interrogations enrichies Cependant, Berkeley DB contient des fonctionnalités qui protègent et valident l'interrogation enrichie en ajoutant la valeur de hachage de l'arbre Merkle dans le jeu de lecture, en réexécutant l'interrogation enrichie et, au stade de la validation, en recalculant la valeur de l'arbre Merkle. Notez que, comme la validation est plus précise dans Oracle Blockchain Platform avec Berkeley DB, les appels de code de chaîne sont parfois marqués pour des lectures fantômes plus fréquentes.