Consultar o Banco de Dados de Estado
Este tópico contém informações para ajudá-lo a entender como consultar o banco de dados de estado onde os dados de estado atuais do razão blockchain são armazenados.
O que é o Banco de Dados de Estado?
Os dados de estado atuais do razão blockchain são armazenados no banco de dados de estado.
Ao desenvolver códigos de cadeia do Oracle Blockchain Platform, você pode extrair dados do banco de dados de estado executando consultas avançadas. O Oracle Blockchain Platform suporta consultas avançadas usando a sintaxe de consulta rica em SQL e as expressões de localização CouchDB. Consulte Sintaxe de Consulta Rich em SQL e CouchDB Sintaxe de Consulta Rich.
O Hyperledger Fabric não suporta consultas avançadas de SQL. Se a sua rede do Oracle Blockchain Platform contiver participantes do Hyperledger Fabric, você precisará fazer o seguinte:
-
Se seus chaincodes contiverem sintaxe de consulta rica em SQL, esses chaincodes serão instalados somente em pares de membros usando o Oracle Blockchain Platform.
-
Se um chaincode precisar ser instalado nos pares do Oracle Blockchain Platform e do Hyperledger Fabric, use a sintaxe CouchDB nos chaincodes e confirme se os pares do Hyperledger Fabric estão configurados para usar CouchDB como repositório de banco de dados de estado. O Oracle Blockchain Platform pode processar CouchDB.
Como o Oracle Blockchain Platform Funciona com o BD Berkeley?
O Oracle Blockchain Platform usa o Oracle Berkeley DB como banco de dados de estado. O Oracle Blockchain Platform cria tabelas relacionais no BD Berkeley com base na extensão SQLite. Essa arquitetura fornece uma maneira robusta e eficiente de validar consultas avançadas de SQL.
Para cada chaincode de canal, o Oracle Blockchain Platform cria uma tabela de BD Berkeley. Esta tabela armazena dados de informações de estado e contém pelo menos uma coluna de chave chamada key
e uma coluna de valor chamada value
ou valueJson
, dependendo se você está usando dados no formato JSON.
Nome da Coluna | Tipo | Descrição |
---|---|---|
key |
TEXT | Coluna-chave da tabela de estado. |
value |
TEXT | Coluna de valor da tabela de estado. |
valueJson |
TEXT | Coluna de valor de formato JSON da tabela de estado. |
Observe que as colunas valueJson
e value
são mutuamente exclusivas. Portanto, se o chaincode atribuir um valor JSON a uma chave, a coluna valueJson
conterá esse valor, e a coluna de valor será definida como nula. Se o chaincode designar um valor não JSON a uma chave, a coluna valueJson
será definida como nula e a coluna de valor conterá o valor.
Exemplo de um banco de dados de estado
Estes são exemplos de chaves e seus valores do banco de dados de estado da amostra do Concessionário de Carros:
chave | valor | 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": "veículo", "chassisNumber": "dtrt10001", "fabricante": "Detroit Auto", "modelo": "um cupê", "assemblyDate": 1502688979, "airbagSerialNumber": "abg1235", "proprietário": "Sam Dealer", "recall": false, "recallDate": 1502688979 |
Consultas Avançadas na Console
Os administradores podem executar e analisar consultas avançadas na console.
Sintaxe de Rich Query Suportada
O Oracle Blockchain Platform suporta dois tipos de sintaxe de consulta avançada que você pode usar para consultar o banco de dados de estado: consulta rica em SQL e consulta rica em CouchDB.
Sintaxe da SQL Rich Query
As extensões JSON de BD Berkeley estão na forma de funções SQL.
Antes de Começar
Observe as seguintes informações:
- Você só pode acessar o chaincode do canal (<STATE>) do qual está executando sua consulta.
- Somente a instrução SELECT é suportada.
- Não é possível modificar a tabela do banco de dados de estado.
- Uma expressão rich query pode ter somente uma instrução SELECT.
- Os exemplos deste tópico são apenas algumas maneiras de criar sua consulta rich. Você tem acesso à sintaxe SQL completa usual para consultar um banco de dados SQL.
- Você tem acesso à extensão JSON1 (extensão SQLite). Consulte JSON1 Extension e SQL Conforme Compreendido por SQLite.
Se você precisar de mais informações sobre como escrever e testar códigos de cadeia, consulte Desenvolver códigos de cadeia.
Como consultar o banco de dados de estado em consultas
O nome da tabela do banco de dados de estado é gerenciado internamente pelo Oracle Blockchain Platform, portanto, você não precisa saber o nome físico do banco de dados de estado ao escrever um chaincode.
Em vez disso, você deve usar o alias <STATE>
para fazer referência ao nome da tabela. Por exemplo: select key, value from <STATE>
.
Observe que o alias <STATE>
não faz distinção entre maiúsculas e minúsculas; portanto, você pode usar <state>
, <STATE>
ou algo como <StAtE>
.
Recuperar Todas as Chaves
Use esta sintaxe:
SELECT key FROM <STATE>
Por exemplo, se você usar essa sintaxe para consultar a amostra Concessionária de Veículos, obterá a seguinte lista de chaves:
chave
abg1234
abg1235
ser1236
bra1238
dtrt10001
Recuperar Todas as Chaves e Valores Ordenados Alfabeticamente por Chave
Use esta sintaxe:
SELECT key AS serialNumber, valueJson AS details FROM <state> ORDER BY key
Por exemplo, se você usar essa sintaxe para consultar a amostra Concessionária de Veículos, obterá os seguintes resultados:
serialNumber | detalhes |
---|---|
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": "veículo", "chassisNumber": "dtrt10001", "fabricante": "Detroit Auto", "modelo": "um cupê", "assemblyDate": 1502688979, "airbagSerialNumber": "abg1235", "proprietário": "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 as Chaves e Valores Começando com "abg"
Use esta sintaxe:
SELECT key AS serialNumber, valueJson AS details FROM <state> WHERE key LIKE 'abg%'SELECT key, value FROM <STATE>
Por exemplo, se você usar essa sintaxe para consultar a amostra Concessionária de Veículos, obterá os seguintes resultados:
serialNumber | detalhes |
---|---|
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 as Chaves com Valores Contendo um Veículo de Propriedade de "Detroit Auto"
Use esta sintaxe:
SELECT key FROM <state> WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto'
Por exemplo, se você usar essa sintaxe para consultar a amostra Concessionária de Veículos, obterá a seguinte lista de chaves:
chave
abg1234
abg1235
ser1236
bra1238
Recuperar Modelo e Fabricante para todos os Carros de Propriedade de "Sam Dealer"
Use esta sintaxe:
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 exemplo, se você usar essa sintaxe para consultar a amostra Concessionária de Veículos, obterá os seguintes resultados:
modelo | fabricante |
---|---|
um cupê | Detroit Auto |
Se o valor de estado for array JSON, você poderá usar essa sintaxe para recuperar o modelo e o fabricante de todos os carros pertencentes ao "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 Sintaxe de Rich Query
Use as informações deste tópico se estiver migrando seus chaincodes contendo a sintaxe CouchDB para o Oracle Blockchain Platform ou se precisar gravar chaincodes para instalar em pares do Hyperledger Fabric que participem de uma rede do Oracle Blockchain Platform.
Se você estiver escrevendo um novo chaincode, a Oracle recomenda que você use consultas ricas em SQL para aproveitar os benefícios de desempenho oferecidos pelo Oracle Blockchain Platform com o BD Berkeley.
Se você precisar de mais informações sobre como escrever e testar códigos de cadeia, consulte Desenvolver códigos de cadeia.
Parâmetros de Consulta e Sintaxe do Seletor Não Suportados
O Oracle Blockchain Platform não suporta o parâmetro use_index
. Se usado, o Oracle Blockchain Platform ignorará esse parâmetro e selecionará automaticamente os índices definidos no StateDB em questão.
Parâmetro | Tipo | Descrição |
---|---|---|
use_index | json | Instrui uma consulta a usar um índice específico. |
Recupere Todos os Modelos, Fabricantes e Proprietários de Carros e Ordene-os por Proprietário
Use esta expressão:
{
"fields": ["model", "manufacturer", "owner"],
"sort": [
"owner"
]
}
Recuperar Modelo e Fabricante para Todos os Carros de Propriedade de "Sam Dealer"
Use esta expressão:
{
"fields": ["model", "manufacturer"],
"selector": {
"docType" : "vehicle",
"owner" : "Sam Dealer"
}
}
Índices do Banco de Dados de Estado
O banco de dados de estado pode conter uma grande quantidade de dados. Nesses casos, o Oracle Blockchain Platform usa índices para melhorar o acesso aos dados.
Índices Padrão
Quando um chaincode é implantado, o Oracle Blockchain Platform cria dois índices.
-
Índice de chave — Criado na coluna de chave.
-
Índice de valor — Criado na coluna de valor.
Índices Personalizados
Em alguns casos, talvez você precise criar índices personalizados. Você define esses índices usando qualquer expressão que possa ser resolvida no contexto da tabela de estados. Os índices personalizados criados com base no BD Berkeley dependem da sintaxe SQLite, mas eles seguem a mesma implementação CouchDB fornecida pelo Hyperledger Fabric.
Observe que você pode usar índices personalizados para melhorar drasticamente o desempenho das instruções WHERE e ORDER BY em grandes conjuntos de dados. Como o uso de índices personalizados retarda as inserções de dados, você deve usá-los criteriosamente.
Cada índice personalizado é definido como uma matriz de expressões, que suportam índices compostos, expressos como um documento JSON dentro de um arquivo (observe que há um índice por arquivo). Você deve empacotar esse arquivo com o chaincode em uma pasta chamada "indexes" na seguinte estrutura de diretório: statedb/relationaldb/indexes
. Consulte Como adicionar índices CouchDB durante a instalação de chaincode.
Exemplo de Índices Personalizados
Os exemplos de índice personalizados nesta seção usam a amostra Concessionária de automóveis.
Exemplo 1 — Este exemplo indexa o uso da expressão json_extract
no contexto das expressões WHERE e ORDER BY.
{"indexExpressions": ["json_extract(valueJson, '$.owner')"]}
Por exemplo:
SELECT … FROM … ORDER BY json_extract(valueJson, '$.owner')
Exemplo 2 — Este exemplo indexa o uso composto das duas expressões json_extract
no contexto das expressões WHERE e ORDER BY.
{"indexExpressions": ["json_extract(valueJson, '$.docType')", "json_extract(valueJson, '$.owner')"]}
Por exemplo:
SELECT … FROM … WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto'
Exemplo 3 — Este exemplo cria dois índices: o índice descrito no Exemplo 1 e o índice descrito no Exemplo 2. Observe que cada estrutura JSON precisa ser incluída em um arquivo separado. Cada arquivo descreve um único índice: um índice simples como o Exemplo 1 ou um índice composto como o Exemplo 2.
Índice 1: {"indexExpressions": ["json_extract(valueJson, '$.owner')"]}
Índice 2: {"indexExpressions": ["json_extract(valueJson, '$owner')", "json_extract(valueJson, '$.docType')"]}
No exemplo a seguir, o Índice 2 é aplicado à expressão AND
na parte WHERE
da consulta, enquanto o Índice 1 é aplicado à expressão 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
O documento JSON deve estar no seguinte formato:
{"indexExpressions": [expr1, ..., exprN]}
Por exemplo:
{"indexExpressions": ["json_extract(valueJson, '$.owner')"]}
Diferenças na Validação de Consultas Avançadas
Em alguns casos, o Hyperledger Fabric padrão com consulta rica em CouchDB e a consulta rica em Oracle Berkeley DB se comportam de maneira diferente.
No Hyperledger Fabric padrão com CouchDB, cada par de chave e valor retornado pela consulta é adicionado ao conjunto de leitura da transação e é validado no momento da validação e sem executar a consulta novamente. No BD Berkeley, o par de chave e valor retornado não é adicionado ao conjunto de leitura, mas o resultado da consulta rica é hash em uma árvore Merkle e validado em relação à reexecução da consulta no momento da validação.
O Hyperledger Fabric nativo não fornece proteção de dados para consultas avançadas. No entanto, o Berkeley DB contém funcionalidade que protege e valida a consulta rica adicionando o valor de hash da árvore Merkle ao conjunto de leitura, reexecutando a consulta rica e, no estágio de validação, recalculando o valor da árvore Merkle. Observe que, como a validação é mais precisa no Oracle Blockchain Platform com o BD Berkeley, às vezes as chamadas de chaincode são sinalizadas para leituras fantasmas mais frequentes.