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 no qual os dados de estado atuais do razão de blockchain são armazenados.
O que é o banco de dados estadual?
Os dados de estado atuais do razão blockchain são armazenados no banco de dados de estado.
Quando você desenvolve códigos de cadeia do Oracle Blockchain Platform, 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 avançada SQL e as expressões de localização CouchDB. Consulte Sintaxe de Consulta Rich SQL e Sintaxe de Consulta Rich CouchDB.
O Hyperledger Fabric não oferece suporte a consultas ricas em SQL. Se sua rede do Oracle Blockchain Platform contiver participantes do Hyperledger Fabric, você precisará se certificar de fazer o seguinte:
-
Se seus chaincodes contiverem sintaxe de consulta rica em SQL, esses chaincodes serão instalados apenas em pares de membros usando o Oracle Blockchain Platform.
-
Se um chaincode precisar ser instalado nos pares do Oracle Blockchain Platform e Hyperledger Fabric, use a sintaxe CouchDB nos chaincodes e confirme se os pares do Hyperledger Fabric estão configurados para usar CouchDB como seu repositório de banco de dados de estado. O Oracle Blockchain Platform pode processar o 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 ricas em SQL.
Para cada chaincode de canal, o Oracle Blockchain Platform cria uma tabela de banco de dados Berkeley. Essa 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 de você estar usando dados no formato JSON.
| Nome da Coluna | Tipo | Descrição |
|---|---|---|
key |
TEXT | Coluna de chaves da tabela de estados. |
value |
TEXT | Coluna de valor da tabela de estados. |
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 designar 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 de 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": "frekepad 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 avançada SQL e consulta avançada CouchDB.
Sintaxe de Consulta SQL Rich
As extensões Berkeley DB JSON 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 de consulta rich pode ter somente uma instrução SELECT.
- Os exemplos neste tópico são apenas algumas maneiras de escrever sua consulta avançada. 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 Entendido pelo SQLite.
Se precisar de mais informações sobre como gravar e testar chaincodes, consulte Desenvolver Chaincodes.
Como Fazer Referência ao 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 quando grava 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 de Concessionária de carros, 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 keyPor exemplo, se você usar essa sintaxe para consultar a amostra de Concessionária de carros, 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": "frekepad 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 Iniciando 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 de Concessionária de carros, 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 uma Peça de 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 de Concessionária de carros, obterá a seguinte lista de chaves:
chave
abg1234
abg1235
ser1236
bra1238
Recuperar Modelo e Fabricante para todos os Carros de Propriedade de "Concessionária Sam"
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 de Concessionária de carros, obterá os seguintes resultados:
| modelo | fabricante |
|---|---|
| um cupê | Detroit Auto |
Se o valor de estado for um array JSON, você poderá usar essa sintaxe para recuperar o modelo e o fabricante de todos os carros de propriedade de "Concessionária de Sam":
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 Consulta Avançada
Use as informações neste tópico se você 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 participam 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 que o Oracle Blockchain Platform com o Berkeley DB oferece.
Se precisar de mais informações sobre como gravar e testar chaincodes, consulte Desenvolver Chaincodes.
Parâmetros de Consulta e Sintaxe de 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 ele 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. |
Recuperar Todos os Modelos, Fabricantes e Proprietários de Carros e Ordená-los por Proprietário
De acordo com esta expressão:
{
"fields": ["model", "manufacturer", "owner"],
"sort": [
"owner"
]
}Recuperar Modelo e Fabricante para Todos os Carros Pertencentes ao "Concessionário Sam"
Com 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 no BD Berkeley dependem da sintaxe SQLite, mas de outra forma eles seguem a mesma implementação CouchDB fornecida pelo Hyperledger Fabric.
Você pode usar índices personalizados para melhorar significativamente o desempenho das instruções WHERE e ORDER BY em grandes conjuntos de dados. Como o uso de índices personalizados diminui a velocidade das inserções de dados, use-os com critério.
Cada índice personalizado é definido como um array de expressões, que suportam índices compostos, expressos como um documento JSON dentro de um arquivo. Há um índice por arquivo. Você deve empacotar esse arquivo com o chaincode em uma pasta chamada indexes na seguinte estrutura de diretórios: statedb/relationaldb/indexes. Para obter mais informações, consulte Como adicionar índices CouchDB durante a instalação de chaincode.
Exemplo de Índices Personalizados
Os exemplos de índice personalizado nesta seção usam a amostra de Concessionária de carros.
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 o índice descrito no Exemplo 1 e o índice descrito no Exemplo 2. Cada estrutura JSON deve 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 Rich Queries
Em alguns casos, o Hyperledger Fabric padrão com a consulta avançada CouchDB e a consulta avançada Oracle Berkeley DB se comportam de maneira diferente.
No Hyperledger Fabric padrão com CouchDB, cada par de chaves e valores retornado pela consulta é adicionado ao conjunto de leitura da transação e validado no momento da validação e sem reexecutar a consulta. No Berkeley DB, o par de chave e valor retornado não é adicionado ao conjunto de leitura, mas o resultado da consulta rich é 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 uma funcionalidade que protege e valida a consulta avançada adicionando o valor de hash da árvore Merkle ao conjunto de leitura, reexecutando a consulta avançada 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, as chamadas de chaincode às vezes são sinalizadas para leituras fantasmas mais frequentes.