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 estatal?

Los datos de estado actuales del libro mayor de blockchain se almacenan en la base de datos de estado.

Al desarrollar códigos de cadenas 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 de SQL y Sintaxis de consulta enriquecida de CouchDB.

Hyperledger Fabric no soporta consultas enriquecidas con SQL. Si la red de Oracle Blockchain Platform contiene participantes de Hyperledger Fabric, debe asegurarse de hacer lo siguiente:

  • Si los códigos de cadenas contienen sintaxis de consulta enriquecida con SQL, esos códigos de cadenas solo se instalan en pares de miembros que utilizan Oracle Blockchain Platform.

  • Si es necesario instalar un código de cadena en los pares de Oracle Blockchain Platform y 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 de estado. Oracle Blockchain Platform crea tablas relacionales en Berkeley DB 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 base de datos 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, en función de si está utilizando datos de formato JSON.

Nombre de columna Tipo Descripción
key TEXT Columna de claves de la tabla de estado.
value TEXT Columna de valor de la tabla de estado.
valueJson TEXT Columna de valor de formato JSON de la tabla de estado.

Tenga en cuenta que las columnas valueJson y value se excluyen mutuamente. 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 es 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 Car Dealer:

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": "vehicle", "chassisNumber": "dtrt10001", "manufacturer": "Detroit Auto", "model": "a coupe", "assemblyDate": 1502688979, "airbagSerialNumber": "abg1235", "owner": "Sam Dealer", "recall": false, "recallDate": 1502688979

Consultas enriquecidas en la consola

Los administradores pueden ejecutar y analizar consultas enriquecidas desde la consola.

  1. Vaya a la consola y seleccione el separador Canales.
  2. En la tabla de canales, busque el canal en el que desea ejecutar una consulta, haga clic en el botón Más acciones de los canales y, a continuación, haga clic en Analizar consultas enriquecidas. Se muestra el cuadro de diálogo Analizar consultas enriquecidas.
  3. Para ejecutar una consulta enriquecida en la base de datos de estado, seleccione Ejecución de consulta.
    1. En Código de cadena, seleccione el código de cadena que se despliega en el canal que desea consultar.
    2. En Peer, seleccione el peer que desea consultar.
      Solo están disponibles los pares de la organización actual que ejecutan el código de cadena seleccionado.
    3. En Consulta enriquecida, introduzca la consulta enriquecida que desea ejecutar y analizar.
      El formato de consulta debe seguir la sintaxis de consulta enriquecida. Para obtener más información sobre la sintaxis de consulta enriquecida, consulte Sintaxis de consulta enriquecida soportada.
    4. En Límite de filas de resultados, mueva el control deslizante al número máximo de filas de resultados que desea recuperar. Puede recuperar hasta 50 filas de resultados.
  4. Para obtener el plan de ejecución de una consulta, seleccione Explicación del Plan de Consulta. Un plan de ejecución de consulta es la secuencia de operaciones que se ha realizado para ejecutar la consulta.
    1. En Código de cadena, seleccione el código de cadena que se despliega en el canal que desea consultar.
    2. En Peer, seleccione el peer que desea consultar.
    3. En Recopilación, seleccione la base de datos de estado o la recopilación de datos privada.
    4. En Consulta enriquecida, introduzca la consulta enriquecida.
      La palabra clave explain no es necesaria para esta consulta.
      Por ejemplo: select * from <state>
  5. Haga clic en Ejecutar El campo Resultados muestra la tabla de resultados de la consulta o el plan de ejecución. Para exportar la tabla de resultados como un archivo .csv, haga clic en Exportar.
    El tamaño de la tabla de resultados está limitado a 1 MB. Puede que tenga que acotar la consulta para evitar exceder este límite.

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: la consulta enriquecida con SQL y la consulta enriquecida con CouchDB.

Sintaxis de Consulta Enriquecida SQL

Las extensiones JSON de Berkeley DB se presentan en forma de funciones SQL.

Antes de empezar

Tenga en cuenta la siguiente información:

  • Solo puede acceder al código de cadenas 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 de escribir la 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 Extensión JSON1 y SQL como comprendido por SQLite.

Si necesita más información sobre la escritura y la prueba de códigos de cadenas, consulte Desarrollo de códigos de cadenas.

Cómo hacer referencia a la base de datos de estado en consultas

El nombre de la tabla de la base de datos de estado lo gestiona internamente Oracle Blockchain Platform, por lo que no es necesario conocer 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 la tabla. Por ejemplo: select key, value from <STATE>.

Tenga en cuenta que el alias <STATE> no es sensible a mayúsculas/minúsculas, por lo que puede utilizar <state>, <STATE> o algo parecido a <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

Recuperación de todas las claves y valores ordenados alfabéticamente por clave

Utilice esta sintaxis:

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

Por ejemplo, si utiliza esta sintaxis para consultar el ejemplo del concesionario de automóviles, obtendrá los siguientes resultados:

serialNumber Detalles
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}

Recuperación de todas las claves y valores a partir de "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 Detalles
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"}

Recuperación de todas las claves con valores que contienen una pieza de 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 coches 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'

CouchDB Sintaxis de consulta enriquecida

Utilice la información de este tema si va a migrar los códigos de cadenas que contienen la sintaxis CouchDB a Oracle Blockchain Platform o si necesita escribir códigos de cadenas para instalarlos en pares de Hyperledger Fabric que participan en una red de Oracle Blockchain Platform.

Si está escribiendo un nuevo código de cadena, Oracle recomienda utilizar consultas enriquecidas con 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 cadenas, consulte Desarrollo de códigos de cadenas.

Sintaxis de Selector y Parámetros de Consulta no Soportados

Oracle Blockchain Platform no soporta 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: se crea 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 la base de datos de Berkeley se basan en la sintaxis SQLite, pero, de lo contrario, siguen la misma implementación CouchDB proporcionada por Hyperledger Fabric.

Tenga en cuenta que puede utilizar índices personalizados para mejorar drásticamente el rendimiento de las sentencias WHERE y ORDER BY en juegos de datos grandes. Debido a que el uso de índices personalizados ralentiza las inserciones de datos, debe utilizarlos 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 (tenga en cuenta que hay un índice por archivo). Debe empaquetar este archivo con el código de cadenas en una carpeta denominada "indexes" en la siguiente estructura de directorios: statedb/relationaldb/indexes. Consulte How to add CouchDB indexes during chaincode installation.

Índices personalizados de ejemplo

Los ejemplos de índices personalizados de esta sección utilizan el ejemplo Car Dealer.

Ejemplo 1: este ejemplo 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: en este ejemplo, se crean dos índices: el índice descrito en el ejemplo 1 y el índice descrito en el ejemplo 2. Tenga en cuenta que 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 de 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, el Hyperledger Fabric estándar con consulta enriquecida CouchDB y la consulta enriquecida Oracle Berkeley DB se comportan de forma diferente.

En el estándar Hyperledger Fabric 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 codifica en un árbol de Merkle y se valida con respecto a la nueva ejecución de la consulta en el momento de la validación.

Hyperledger Fabric nativo 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 Merkle en el juego de lectura, volviendo a ejecutar la consulta enriquecida y, en la etapa de validación, volviendo a calcular el valor del árbol Merkle. Tenga en cuenta que, dado que la validación es más precisa en Oracle Blockchain Platform con Berkeley DB, las llamadas de código de cadena a veces se marcan para lecturas fantasma más frecuentes.