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 dans laquelle les données d'état actuelles du registre blockchain sont stockées.
Qu'est-ce que la base de données d'État ?
Les données d'état actuelles du registre blockchain 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 à Syntaxe de requête enrichie CouchDB.
Hyperledger Fabric ne prend pas en charge les requêtes SQL riches. 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 chaîne contiennent une syntaxe de requête enrichie SQL, ils 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 vérifiez que les homologues 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 offre un moyen fiable 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.
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. |
Notez que 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 de 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 coupé", "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 : requête enrichie SQL et requête enrichie CouchDB.
Syntaxe de requête enrichie SQL
Les extensions JSON de Berkeley DB sont sous 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-unes des façons dont vous pouvez é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 à JSON1 Extension et à SQL comme compris par SQLite.
Si vous avez besoin d'informations supplémentaires sur l'écriture et le test des 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, de sorte que vous n'avez 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 <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 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 par ordre alphabétique de 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 de concessionnaire automobile, vous obtiendrez les résultats suivants :
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" : "brakepad 4200", "owner" : "Detroit Auto", "recall" : false, "recallDate" : 1502688979} |
dtrt10001 | {"docType" : "vehicle", "chassisNumber" : "dtrt10001", "manufacturer" : "Detroit Auto", "model" : "a coupé", "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 de concessionnaire automobile, vous obtiendrez les résultats suivants :
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", "assembleur" : "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 appartenant à "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 de concessionnaire automobile, vous obtiendrez la liste de clés suivante :
clé
abg1234
abg1235
ser1236
bra1238
Récupérer le modèle et le fabricant pour 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 de concessionnaire automobile, vous obtiendrez les résultats suivants :
modèle | fabricant |
---|---|
un coupé | Auto de Detroit |
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 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 SQL riches pour tirer parti des avantages en performances d'Oracle Blockchain Platform avec Berkeley DB.
Si vous avez besoin d'informations supplémentaires sur l'écriture et le test des 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 | Indique à 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 pour 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 des 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 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 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')"]}
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 être au format suivant :
{"indexExpressions": [expr1, ..., exprN]}
Exemple :
{"indexExpressions": ["json_extract(valueJson, '$.owner')"]}
Différences dans la validation des requêtes enrichies
Dans certains cas, la norme Hyperledger Fabric 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 à l'ensemble de lecture de la transaction et est validée au moment de la validation et sans réexécuter la requête. Dans la base de données Berkeley, la paire clé/valeur renvoyée n'est pas ajoutée à l'ensemble de lecture, mais le résultat de la requête enrichie est haché dans une arborescence 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. Cependant, Berkeley DB contient une fonctionnalité qui protège et valide la requête enrichie en ajoutant la valeur de hachage de l'arborescence Merkle dans l'ensemble de lecture, en réexécutant la requête enrichie et en recalculant la valeur de l'arborescence Merkle à l'étape de validation. Etant donné que la validation est plus précise dans Oracle Blockchain Platform avec la base de données Berkeley, les appels de code chaîne sont parfois signalés pour des lectures fantômes plus fréquentes.