Eseguire una query sul database di stato

Questo argomento contiene informazioni che consentono di comprendere come eseguire query sul database di stato in cui sono memorizzati i dati di stato correnti del libro contabile blockchain.

Cos'è il database di stato?

I dati di stato correnti del libro contabile blockchain vengono memorizzati nel database di stato.

Quando sviluppi i codici concatenati di Oracle Blockchain Platform, puoi estrarre i dati dal database di stato eseguendo query avanzate. Oracle Blockchain Platform supporta query avanzate utilizzando la sintassi SQL Rich Query e le espressioni di ricerca CouchDB. Vedere Sintassi query Rich SQL e CouchDB Sintassi query Rich.

Hyperledger Fabric non supporta query rich SQL. Se la tua rete Oracle Blockchain Platform contiene partecipanti a Hyperledger Fabric, devi assicurarti di effettuare le operazioni riportate di seguito.

  • Se i codici concatenati contengono la sintassi Rich Query SQL, tali codici concatenati vengono installati solo sui peer dei membri che utilizzano Oracle Blockchain Platform.

  • Se è necessario installare un codice concatenato sui peer di Oracle Blockchain Platform e Hyperledger Fabric, utilizzare la sintassi CouchDB nei codici concatenati e confermare che i peer di Hyperledger Fabric sono impostati per utilizzare CouchDB come repository del database di stato. Oracle Blockchain Platform può elaborare CouchDB.

Come funziona Oracle Blockchain Platform con il DB Berkeley?

Oracle Blockchain Platform utilizza Oracle Berkeley DB come database di stato. Oracle Blockchain Platform crea tabelle relazionali nel DB Berkeley in base all'estensione SQLite. Questa architettura offre un modo efficace ed efficace per convalidare le query SQL Rich.

Per ogni codice concatenato di canale, Oracle Blockchain Platform crea una tabella DB Berkeley. Questa tabella memorizza i dati relativi alle informazioni sullo stato e contiene almeno una colonna chiave denominata key e una colonna di valori denominata value o valueJson, a seconda che si stiano utilizzando dati in formato JSON.

Nome della colonna Type Descrizione
key TEXT Colonna chiave della tabella di stato.
value TEXT Colonna dei valori della tabella degli stati.
valueJson TEXT Colonna dei valori di formato JSON della tabella di stato.

Le colonne valueJson e value si escludono a vicenda. Pertanto, se il codice concatenato assegna un valore JSON a una chiave, la colonna valueJson conterrà tale valore e la colonna del valore verrà impostata su null. Se il codice concatenato assegna un valore non JSON a una chiave, la colonna valueJson verrà impostata su null e la colonna dei valori conterrà il valore.

Esempio di database di stato

Questi sono esempi di chiavi e dei loro valori dal database di stato del campione Car Dealer:

chiave value valueJson
abg1234 nullo {"docType": "vehiclePart", "serialNumber": "abg1234", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "airbag 2020", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
abg1235 nullo {"docType": "vehiclePart", "serialNumber": "abg1235", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "airbag 4050", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
ser1236 nullo {"docType": "vehiclePart", "serialNumber": "ser1236", "assembler": "panama-parts", "assemblyDate": 1502688979, "name": "seatbelt 10020", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
bra1238 nullo {"docType": "vehiclePart", "serialNumber": "bra1238", "assembler": "bobs-bits", "assemblyDate": 1502688979, "name": "brakepad 4200", "owner": "Detroit Auto", "recall": false, "recallDate": 1502688979}
dtrt10001 nullo {"docType": "vehicle", "chassisNumber": "dtrt10001", "manufacturer": "Detroit Auto", "model": "a coupe", "assemblyDate": 1502688979, "airbagSerialNumber": "abg1235", "owner": "Sam Dealer", "recall": false, "recallDate": 1502688979

Rich Query nella console

Gli amministratori possono eseguire e analizzare query avanzate dalla console.

  1. Andare alla console e selezionare la scheda Canali.
  2. Nella tabella dei canali, individuare il canale in cui si desidera eseguire una query, fare clic sul pulsante Altre azioni dei canali, quindi fare clic su Analizza query avanzate. Viene visualizzata la finestra di dialogo Analizza rich query.
  3. Per eseguire una query RTF sul database di stato, selezionare Esecuzione query.
    1. Per Codice di catena, selezionare il codice di catena distribuito nel canale su cui si desidera eseguire la query.
    2. Per Peer, selezionare il peer su cui eseguire la query.
      Sono disponibili solo i peer dell'organizzazione corrente che eseguono il codice concatenato selezionato.
    3. Per Rich Query, immettere la Rich Query da eseguire e analizzare.
      Il formato della query deve seguire la sintassi Rich Query. Per ulteriori informazioni sulla sintassi Rich Query, vedere Sintassi Rich Query supportata.
    4. Per Limite righe risultato, spostare il dispositivo di scorrimento sul numero massimo di righe dei risultati da recuperare. È possibile recuperare fino a 50 righe di risultati.
  4. Per ottenere il piano di esecuzione per una query, selezionare Spiegazione del piano della query. Un piano di esecuzione query è la sequenza di operazioni eseguite per eseguire la query.
    1. Per Codice di catena, selezionare il codice di catena distribuito nel canale su cui si desidera eseguire la query.
    2. Per Peer, selezionare il peer su cui eseguire la query.
    3. Per Raccolta, selezionare il database di stato o la raccolta di dati privati.
    4. Per Rich Query, immettere la Rich Query.
      La parola chiave explain non è necessaria per questa interrogazione.
      Ad esempio: select * from <state>
  5. Fare clic su Esegui . Il campo Risultati mostra la tabella dei risultati della query o il piano di esecuzione. Per esportare la tabella dei risultati come file .csv, fare clic su Esporta.
    La dimensione della tabella dei risultati è limitata a 1 MB. Potrebbe essere necessario perfezionare la query per evitare di superare questo limite.

Sintassi Rich Query supportata

Oracle Blockchain Platform supporta due tipi di sintassi Rich Query che è possibile utilizzare per eseguire query sul database di stato: SQL Rich Query e CouchDB Rich Query.

Sintassi query Rich SQL

Le estensioni Berkeley DB JSON sono sotto forma di funzioni SQL.

Operazioni preliminari

Tenere presenti le informazioni riportate di seguito.

  • È possibile accedere solo al codice concatenato canale (<STATE>) dal quale si sta eseguendo la query.
  • È supportata solo l'istruzione SELECT.
  • Impossibile modificare la tabella del database di stato.
  • Un'espressione di query RTF può avere una sola istruzione SELECT.
  • Gli esempi in questo argomento sono solo alcuni modi in cui è possibile scrivere la query avanzata. È possibile accedere alla normale sintassi SQL completa per eseguire una query su un database SQL.
  • È possibile accedere all'estensione JSON1 (estensione SQLite). Vedere JSON1 Extension e SQL As Understand by SQLite.

Per ulteriori informazioni sulla scrittura e il test dei codici concatenati, vedere Sviluppa codici concatenati.

Come fare riferimento al database di stato nelle query

Il nome della tabella del database di stato viene gestito internamente da Oracle Blockchain Platform, pertanto non è necessario conoscere il nome fisico del database di stato quando si scrive un codice concatenato.

In alternativa, è necessario utilizzare l'alias <STATE> per fare riferimento al nome della tabella. Ad esempio: select key, value from <STATE>.

Tenere presente che l'alias <STATE> non distingue tra maiuscole e minuscole, pertanto è possibile utilizzare <state>, <STATE> o <StAtE>.

Recupera tutte le chiavi

Utilizzare questa sintassi:

SELECT key FROM <STATE>

Ad esempio, se si utilizza questa sintassi per eseguire una query sull'esempio Rivenditore auto, verrà visualizzato il seguente elenco di chiavi:

chiave

abg1234

abg1235

ser1236

bra1238

dtrt10001

Recupera tutte le chiavi e tutti i valori ordinati alfabeticamente per chiave

Utilizzare questa sintassi:

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

Ad esempio, se si utilizza questa sintassi per eseguire una query sull'esempio Rivenditore auto, si otterranno i seguenti risultati:

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

Recupera tutte le chiavi e tutti i valori che iniziano con "abg"

Utilizzare questa sintassi:

SELECT key AS serialNumber, valueJson AS details FROM <state> WHERE key LIKE 'abg%'SELECT key, value FROM <STATE>

Ad esempio, se si utilizza questa sintassi per eseguire una query sull'esempio Rivenditore auto, si otterranno i seguenti risultati:

serialNumber Dettagli
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"}

Recupero di tutte le chiavi con valori contenenti una parte del veicolo di proprietà di "Detroit Auto"

Utilizzare questa sintassi:

SELECT key FROM <state> WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto'

Ad esempio, se si utilizza questa sintassi per eseguire una query sull'esempio Rivenditore auto, verrà visualizzato il seguente elenco di chiavi:

chiave

abg1234

abg1235

ser1236

bra1238

Recupera modello e produttore per tutte le auto di proprietà di "Sam Dealer"

Utilizzare questa sintassi:

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'

Ad esempio, se si utilizza questa sintassi per eseguire una query sull'esempio Rivenditore auto, si otterranno i seguenti risultati:

modello Produttore
un coupé Detroit Auto

Se il valore di stato è un array JSON, è possibile utilizzare questa sintassi per recuperare il modello e il produttore per tutte le auto di proprietà di "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 Sintassi Rich Query

Utilizzare le informazioni contenute in questo argomento se si sta eseguendo la migrazione dei codici concatenati contenenti la sintassi CouchDB in Oracle Blockchain Platform o se è necessario scrivere codici concatenati da installare sui peer Hyperledger Fabric che partecipano a una rete Oracle Blockchain Platform.

Se stai scrivendo un nuovo codice concatenato, Oracle consiglia di utilizzare query SQL avanzate per sfruttare i vantaggi delle prestazioni offerti da Oracle Blockchain Platform con Berkeley DB.

Per ulteriori informazioni sulla scrittura e il test dei codici concatenati, vedere Sviluppa codici concatenati.

Parametri query e sintassi selettore non supportati

Oracle Blockchain Platform non supporta il parametro use_index. Se utilizzato, Oracle Blockchain Platform ignora questo parametro e selezionerà automaticamente gli indici definiti nel file StateDB in questione.

Parametro Type Descrizione
use_index json Indica a una query di utilizzare un indice specifico.

Recuperare tutti i modelli, i produttori e i proprietari di auto e ordinarli per proprietario

Utilizzare questa espressione:

{ 
  "fields": ["model", "manufacturer", "owner"], 
  "sort": [   
    "owner" 
   ]
}

Recupera modello e produttore per tutte le auto di proprietà di "Sam Dealer"

Utilizzare questa espressione:

{ 
  "fields": ["model", "manufacturer"], 
  "selector": {   
    "docType"  : "vehicle",
     "owner" : "Sam Dealer" 
  }
}

Indici del database di stato

Il database di stato può contenere una grande quantità di dati. In questi casi Oracle Blockchain Platform utilizza gli indici per migliorare l'accesso ai dati.

Indici predefiniti

Quando viene distribuito un codice concatenato, Oracle Blockchain Platform crea due indici.

  • Indice chiave: creato nella colonna chiave.

  • Indice dei valori: creato nella colonna dei valori.

Indici personalizzati

In alcuni casi, potrebbe essere necessario creare indici personalizzati. È possibile definire questi indici utilizzando qualsiasi espressione risolvibile nel contesto della tabella di stato. Gli indici personalizzati creati rispetto al DB Berkeley si basano sulla sintassi SQLite, ma in caso contrario seguono la stessa implementazione CouchDB fornita da Hyperledger Fabric.

Tenere presente che è possibile utilizzare indici personalizzati per migliorare notevolmente le prestazioni delle istruzioni WHERE e ORDER BY nei set di dati di grandi dimensioni. Poiché l'utilizzo di indici personalizzati rallenta l'inserimento dei dati, è consigliabile utilizzarli con discrezione.

Ogni indice personalizzato viene definito come un array di espressioni che supportano indici composti, espressi come documento JSON all'interno di un file (si noti che esiste un indice per file). È necessario creare un package di questo file con il codice concatenato in una cartella denominata "indexes" nella struttura di directory seguente: statedb/relationaldb/indexes. Vedere Come aggiungere gli indici CouchDB durante l'installazione del codice concatenato.

Indici personalizzati di esempio

Gli esempi di indici personalizzati in questa sezione utilizzano il campione Car Dealer.

Esempio 1: questo esempio indicizza l'uso dell'espressione json_extract nel contesto delle espressioni WHERE e ORDER BY.

{"indexExpressions": ["json_extract(valueJson, '$.owner')"]}

Ad esempio:

SELECT … FROM … ORDER BY json_extract(valueJson, '$.owner')

Esempio 2: in questo esempio viene indicizzato l'uso composto delle due espressioni json_extract nel contesto delle espressioni WHERE e ORDER BY.

{"indexExpressions": ["json_extract(valueJson, '$.docType')", "json_extract(valueJson, '$.owner')"]}

Ad esempio:

SELECT … FROM … WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto'

Esempio 3: in questo esempio vengono creati due indici: l'indice descritto nell'esempio 1 e l'indice descritto nell'esempio 2. Tenere presente che ogni struttura JSON deve essere inclusa in un file separato. Ogni file descrive un singolo indice: un indice semplice come l'esempio 1 o un indice composto come l'esempio 2.

Indice 1: {"indexExpressions": ["json_extract(valueJson, '$.owner')"]}

Indice 2: {"indexExpressions": ["json_extract(valueJson, '$owner')", "json_extract(valueJson, '$.docType')"]}

Nell'esempio seguente, l'indice 2 viene applicato all'espressione AND nella parte WHERE della query, mentre l'indice 1 viene applicato all'espressione ORDER BY:

SELECT … FROM … WHERE json_extract(valueJson, '$.docType') = 'vehiclePart' AND json_extract(valueJson, '$.owner') = 'Detroit Auto' ORDER BY json_extract(valueJson, '$.owner')

Formato documento JSON

Il documento JSON deve essere nel seguente formato:

{"indexExpressions": [expr1, ..., exprN]}

Ad esempio:

{"indexExpressions": ["json_extract(valueJson, '$.owner')"]}

Differenze nella convalida delle query complesse

In alcuni casi, la funzione Rich Query Hyperledger Fabric standard con CouchDB e Rich Query Oracle Berkeley DB si comporta in modo diverso.

In Hyperledger Fabric standard con CouchDB, ogni coppia di chiave e valore restituita dalla query viene aggiunta al set di lettura della transazione e convalidata al momento della convalida senza rieseguire la query. Nel database Berkeley, la coppia di chiave e valore restituita non viene aggiunta al set di lettura, ma il risultato della query RTF viene sottoposto a hashing in un albero Merkle e convalidato in base alla riesecuzione della query al momento della convalida.

Hyperledger Fabric nativo non fornisce la protezione dei dati per query rich. Tuttavia, Berkeley DB contiene funzionalità che proteggono e convalidano la query avanzata aggiungendo il valore hash dell'albero Merkle nel set di lettura, rieseguendo la query avanzata e nella fase di convalida ricalcolando il valore dell'albero Merkle. Poiché la convalida è più accurata in Oracle Blockchain Platform con il database Berkeley, i richiami del codice concatenato vengono talvolta contrassegnati per letture fantasma più frequenti.