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.
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.