Consulta de la base de datos de estado
Este tema contiene información que le ayudará a comprender cómo consultar la base de datos de estado donde se almacenan los datos de estado actuales del libro mayor de blockchain.
¿Qué es la base de datos de estado?
Los datos de estado actuales del libro mayor de blockchain se almacenan en la base de datos de estado.
Al desarrollar códigos de cadena de Oracle Blockchain Platform, puede extraer datos de la base de datos de estado ejecutando consultas enriquecidas. Oracle Blockchain Platform soporta consultas enriquecidas mediante la sintaxis de consulta enriquecida SQL y las expresiones de búsqueda CouchDB. Consulte Sintaxis de consulta enriquecida SQL y Sintaxis de consulta enriquecida CouchDB.
Hyperledger Fabric no admite consultas enriquecidas de SQL. Si la red de Oracle Blockchain Platform contiene participantes de Hyperledger Fabric, debe asegurarse de hacer lo siguiente:
-
Si los códigos de cadena contienen sintaxis de consulta enriquecida de SQL, dichos códigos de cadena se instalan solo en pares de miembros mediante Oracle Blockchain Platform.
-
Si es necesario instalar un código de cadena en pares de Oracle Blockchain Platform e Hyperledger Fabric, utilice la sintaxis CouchDB en los códigos de cadena y confirme que los pares de Hyperledger Fabric estén configurados para utilizar CouchDB como repositorio de base de datos de estado. Oracle Blockchain Platform puede procesar CouchDB.
¿Cómo funciona Oracle Blockchain Platform con Berkeley DB?
Oracle Blockchain Platform utiliza Oracle Berkeley DB como base de datos estatal. Oracle Blockchain Platform crea tablas relacionales en la base de datos Berkeley basadas en la extensión SQLite. Esta arquitectura proporciona una forma sólida y eficaz de validar consultas enriquecidas con SQL.
Para cada código de cadena de canal, Oracle Blockchain Platform crea una tabla de BD de Berkeley. Esta tabla almacena datos de información de estado y contiene al menos una columna de clave denominada key y una columna de valor denominada value o valueJson, según si está utilizando datos de formato JSON.
| Nombre de columna | Tipo | Descripción |
|---|---|---|
key |
TEXT | Columna de clave de la tabla de estado. |
value |
TEXT | Columna de valor de la tabla de estados. |
valueJson |
TEXT | Columna de valor de formato JSON de la tabla de estado. |
Tenga en cuenta que las columnas valueJson y value son mutuamente excluyentes. Por lo tanto, si el código de cadena asigna un valor JSON a una clave, la columna valueJson contendrá ese valor y la columna de valor se definirá como nula. Si el código de cadena asigna un valor que no sea JSON a una clave, la columna valueJson se definirá como nula y la columna de valor contendrá el valor.
Ejemplo de una base de datos de estado
Estos son ejemplos de claves y sus valores de la base de datos de estado de ejemplo del concesionario de automóviles:
| clave | 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": "vehículo", "chassisNumber": "dtrt10001", "fabricante": "Detroit Auto", "modelo": "un cupé", "assemblyDate": 1502688979, "airbagSerialNumber": "abg1235", "propietario": "Sam Dealer", "recall": false, "recallDate": 1502688979 |
Consultas enriquecidas en la consola
Los administradores pueden ejecutar y analizar consultas enriquecidas desde la consola.
Sintaxis de consulta enriquecida soportada
Oracle Blockchain Platform soporta dos tipos de sintaxis de consulta enriquecida que puede utilizar para consultar la base de datos de estado: consulta enriquecida SQL y consulta enriquecida CouchDB.
Sintaxis de consulta enriquecida de SQL
Las extensiones JSON de Berkeley DB están en forma de funciones SQL.
Antes de empezar
Tenga en cuenta la siguiente información:
- Solo puede acceder al código de cadena de canal (<STATE>) desde el que está ejecutando la consulta.
- Solo está soportada la sentencia SELECT.
- No puede modificar la tabla de la base de datos de estado.
- Una expresión de consulta enriquecida solo puede tener una sentencia SELECT.
- Los ejemplos de este tema son solo algunas formas en las que puede escribir su consulta enriquecida. Tiene acceso a la sintaxis SQL completa habitual para consultar una base de datos SQL.
- Tiene acceso a la extensión JSON1 (extensión SQLite). Consulte JSON1 Extension y SQL como entendido por SQLite.
Si necesita más información sobre la escritura y la prueba de códigos de cadena, consulte Desarrollo de códigos de cadena.
Cómo consultar la base de datos de estado en consultas
Oracle Blockchain Platform gestiona internamente el nombre de la tabla de la base de datos de estado, por lo que no es necesario que conozca el nombre físico de la base de datos de estado al escribir un código de cadena.
En su lugar, debe utilizar el alias <STATE> para hacer referencia al nombre de tabla. Por ejemplo: select key, value from <STATE>.
Tenga en cuenta que el alias <STATE> no distingue entre mayúsculas y minúsculas, por lo que puede utilizar <state>, <STATE> o algo así como <StAtE>.
Recuperar todas las claves
Utilice esta sintaxis:
SELECT key FROM <STATE>Por ejemplo, si utiliza esta sintaxis para consultar el ejemplo del concesionario de automóviles, obtendrá la siguiente lista de claves:
clave
abg1234
abg1235
ser1236
bra1238
dtrt10001
Recuperar todas las claves y valores ordenados alfabéticamente por clave
Utilice esta sintaxis:
SELECT key AS serialNumber, valueJson AS details FROM <state> ORDER BY keyPor ejemplo, si utiliza esta sintaxis para consultar el ejemplo del concesionario de automóviles, obtendrá los siguientes resultados:
| 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": "vehículo", "chassisNumber": "dtrt10001", "fabricante": "Detroit Auto", "modelo": "un cupé", "assemblyDate": 1502688979, "airbagSerialNumber": "abg1235", "propietario": "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} |
Recuperar todas las claves y valores que empiecen por "abg"
Utilice esta sintaxis:
SELECT key AS serialNumber, valueJson AS details FROM <state> WHERE key LIKE 'abg%'SELECT key, value FROM <STATE>Por ejemplo, si utiliza esta sintaxis para consultar el ejemplo del concesionario de automóviles, obtendrá los siguientes resultados:
| 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"} |
Recuperar todas las claves con valores que contienen una parte del vehículo propiedad de "Detroit Auto"
Utilice esta sintaxis:
SELECT key FROM <state> WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto'
Por ejemplo, si utiliza esta sintaxis para consultar el ejemplo del concesionario de automóviles, obtendrá la siguiente lista de claves:
clave
abg1234
abg1235
ser1236
bra1238
Recuperar modelo y fabricante para todos los coches propiedad de "Sam Dealer"
Utilice esta sintaxis:
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'
Por ejemplo, si utiliza esta sintaxis para consultar el ejemplo del concesionario de automóviles, obtendrá los siguientes resultados:
| modelo | fabricante |
|---|---|
| un cupé | Detroit Auto |
Si el valor de estado es una matriz JSON, puede utilizar esta sintaxis para recuperar el modelo y el fabricante de todos los automóviles propiedad de "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'
Sintaxis de consulta enriquecida CouchDB
Utilice la información de este tema si está migrando los códigos de cadena que contienen la sintaxis CouchDB a Oracle Blockchain Platform, o si necesita escribir códigos de cadena para instalar en peers de Hyperledger Fabric que participen en una red de Oracle Blockchain Platform.
Si está escribiendo un nuevo código de cadenas, Oracle recomienda que utilice consultas enriquecidas de SQL para aprovechar las ventajas de rendimiento que proporciona Oracle Blockchain Platform con Berkeley DB.
Si necesita más información sobre la escritura y la prueba de códigos de cadena, consulte Desarrollo de códigos de cadena.
Parámetros de Consulta y Sintaxis de Selector No Soportados
Oracle Blockchain Platform no admite el parámetro use_index. Si se utiliza, Oracle Blockchain Platform ignora este parámetro y seleccionará automáticamente los índices definidos en el StateDB en cuestión.
| parámetro | Tipo | Descripción |
|---|---|---|
| use_index | json | Indica a una consulta que utilice un índice específico. |
Recuperar todos los modelos, fabricantes y propietarios de automóviles, y pedirlos por propietario
Utilice esta expresión:
{
"fields": ["model", "manufacturer", "owner"],
"sort": [
"owner"
]
}Recuperar modelo y fabricante para todos los coches propiedad de "Sam Dealer"
Utilice esta expresión:
{
"fields": ["model", "manufacturer"],
"selector": {
"docType" : "vehicle",
"owner" : "Sam Dealer"
}
}Índices de base de datos de estado
La base de datos de estado puede contener una gran cantidad de datos. En estos casos, Oracle Blockchain Platform utiliza índices para mejorar el acceso a los datos.
Índices por defecto
Cuando se despliega un código de cadena, Oracle Blockchain Platform crea dos índices.
-
Índice de claves: creado en la columna de claves.
-
Índice de valores: creado en la columna de valores.
Índices personalizados
En algunos casos, puede que necesite crear índices personalizados. Estos índices se definen mediante cualquier expresión que se pueda resolver en el contexto de la tabla de estados. Los índices personalizados creados en Berkeley DB se basan en la sintaxis SQLite, pero de lo contrario siguen la misma implementación CouchDB proporcionada por Hyperledger Fabric.
Puede utilizar índices personalizados para mejorar drásticamente el rendimiento de las sentencias WHERE y ORDER BY en juegos de datos de gran tamaño. Debido a que el uso de índices personalizados ralentiza las inserciones de datos, úselos con prudencia.
Cada índice personalizado se define como una matriz de expresiones, que soportan índices compuestos, expresados como un documento JSON dentro de un archivo. Hay un índice por archivo. Debe empaquetar este archivo con el código de cadena en una carpeta denominada indexes en la siguiente estructura de directorios: statedb/relationaldb/indexes. Para obtener más información, consulte Cómo agregar índices CouchDB durante la instalación del código de cadenas.
Índices personalizados de ejemplo
Los ejemplos de índices personalizados de esta sección utilizan el ejemplo Car Dealer.
Ejemplo 1: en este ejemplo se indexa el uso de la expresión json_extract en el contexto de las expresiones WHERE y ORDER BY.
{"indexExpressions": ["json_extract(valueJson, '$.owner')"]}
Por ejemplo:
SELECT … FROM … ORDER BY json_extract(valueJson, '$.owner')
Ejemplo 2: en este ejemplo se indexa el uso compuesto de las dos expresiones json_extract en el contexto de las expresiones WHERE y ORDER BY.
{"indexExpressions": ["json_extract(valueJson, '$.docType')", "json_extract(valueJson, '$.owner')"]}
Por ejemplo:
SELECT … FROM … WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto'
Ejemplo 3: este ejemplo crea tanto el índice descrito en el Ejemplo 1 como el índice descrito en el Ejemplo 2. Cada estructura JSON se debe incluir en un archivo independiente. Cada archivo describe un único índice: un índice simple como el ejemplo 1 o un índice compuesto como el ejemplo 2.
Índice 1: {"indexExpressions": ["json_extract(valueJson, '$.owner')"]}
Índice 2: {"indexExpressions": ["json_extract(valueJson, '$owner')", "json_extract(valueJson, '$.docType')"]}
En el siguiente ejemplo, el índice 2 se aplica a la expresión AND en la parte WHERE de la consulta, mientras que el índice 1 se aplica a la expresión ORDER BY:
SELECT … FROM … WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto' ORDER BY json_extract(valueJson, '$.owner')
Formato de documento JSON
El documento JSON debe tener el siguiente formato:
{"indexExpressions": [expr1, ..., exprN]}
Por ejemplo:
{"indexExpressions": ["json_extract(valueJson, '$.owner')"]}
Diferencias en la validación de consultas enriquecidas
En algunos casos, la consulta enriquecida estándar de Hyperledger Fabric con CouchDB y la consulta enriquecida de Oracle Berkeley DB se comportan de manera diferente.
En el Hyperledger Fabric estándar con CouchDB, cada par de clave y valor devuelto por la consulta se agrega al juego de lectura de la transacción y se valida en el momento de la validación y sin volver a ejecutar la consulta. En la base de datos de Berkeley, el par de clave y valor devuelto no se agrega al juego de lectura, pero el resultado de la consulta enriquecida se aplica hash en un árbol Merkle y se valida con la reejecución de la consulta en el momento de la validación.
Native Hyperledger Fabric no proporciona protección de datos para consultas enriquecidas. Sin embargo, Berkeley DB contiene una funcionalidad que protege y valida la consulta enriquecida agregando el valor hash del árbol de Merkle al conjunto de lectura, volviendo a ejecutar la consulta enriquecida y, en la etapa de validación, volviendo a calcular el valor del árbol de Merkle. Tenga en cuenta que, debido a que la validación es más precisa en Oracle Blockchain Platform con Berkeley DB, las llamadas al código de cadena a veces se marcan para lecturas fantasma más frecuentes.