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 em que 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 avançada SQL e as expressões de localização CouchDB. Consulte Sintaxe de Consulta Avançada SQL e Sintaxe de Consulta Avançada CouchDB.
O Hyperledger Fabric não suporta consultas ricas em SQL. Se sua rede do Oracle Blockchain Platform contiver participantes do Hyperledger Fabric, certifique-se de fazer o seguinte:
-
Se seus chaincodes contiverem sintaxe de consulta rica em SQL, esses chaincodes serão instalados apenas nos pares de membros usando o Oracle Blockchain Platform.
-
Se um chaincode precisar ser instalado nos pares Oracle Blockchain Platform e Hyperledger Fabric, use a sintaxe CouchDB nos chaincodes e confirme se os pares Hyperledger Fabric estão configurados para usar CouchDB como seu repositório de banco de dados de estado. O Oracle Blockchain Platform pode processar CouchDB.
Como o Oracle Blockchain Platform Funciona com o Berkeley DB?
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 se você está usando dados de 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 do 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 da amostra da Concessionária de Veículos:
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": "vehicle", "chassisNumber": "dtrt10001", "manufacturer": "Detroit Auto", "model": "a coupe", "assemblyDate": 1502688979, "airbagSerialNumber": "abg1235", "owner": "Sam Dealer", "recall": false, "recallDate": 1502688979 |
Consultas Avançadas na Console
Os administradores podem executar e analisar consultas avançadas no 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 Consulta Avançada SQL
As extensões Berkeley DB JSON sã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.
- Só há suporte para a instrução SELECT.
- Não é possível modificar a tabela do banco de dados de estado.
- Uma expressão de consulta rica pode ter apenas 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 As Understood by SQLite.
Se precisar de mais informações sobre como gravar e testar chaincodes, consulte Desenvolver Chaincodes.
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 gravar um chaincode.
Em vez disso, use 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": "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} |
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 que Contêm 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 Concessionária de Veículos, obterá a seguinte lista de chaves:
chave
abg1234
abg1235
ser1236
bra1238
Recuperar Modelo e Fabricante de todos os Carros de Propriedade da "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 Concessionária de Veículos, obterá os seguintes resultados:
modelo | fabricante |
---|---|
um cupê | Detroit Auto |
Se o valor do estado for array JSON, você poderá usar essa sintaxe para recuperar o modelo e o fabricante de todos os carros de propriedade 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 Sintaxe de Rich Query
Use as informações deste 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 fornece.
Se precisar de mais informações sobre como gravar e testar chaincodes, consulte Desenvolver Chaincodes.
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 escolherá 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
Use esta expressão:
{
"fields": ["model", "manufacturer", "owner"],
"sort": [
"owner"
]
}
Recuperar Modelo e Fabricante para Todos os Carros de Propriedade da "Concessionária Sam"
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 estado. Os índices personalizados criados com o Berkeley DB dependem da sintaxe SQLite, mas 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 com critério.
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órios: statedb/relationaldb/indexes
. Consulte Como adicionar índices CouchDB durante a instalação do 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 avançada CouchDB e a consulta avançada do 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 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 rica é hashado 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 Berkeley DB, as chamadas de chaincode às vezes são sinalizadas para leituras fantasmas mais frequentes.