Sviluppa applicazioni con GoogleSQL per Bigtable
Puoi utilizzare GoogleSQL per Bigtable per eseguire query dalle tue applicazioni per trasferire le funzioni di calcolo su Bigtable. In questo modo si riduce la necessità di elaborazione lato client. GoogleSQL è un linguaggio di query strutturato conforme allo standard ANSI implementato per Bigtable e altri servizi. Google Cloud Per ulteriori informazioni su altri utilizzi di GoogleSQL per Bigtable, consulta la panoramica di GoogleSQL per Bigtable.
Prima di iniziare
Assicurati di disporre di quanto segue:
- Un'istanza e una tabella Bigtable.
- La libreria client di Bigtable per il tuo linguaggio. Per ulteriori informazioni su come installare e utilizzare le librerie client per Bigtable, consulta Librerie client di Bigtable.
- Autenticazione configurata tramite le Credenziali predefinite dell'applicazione (ADC). Per saperne di più, consulta Configura l'autenticazione per un ambiente di sviluppo locale.
Scenario di esempio
Gli esempi in questa guida utilizzano una tabella weather-data di esempio a cui puoi accedere
dall'istanza della prova senza costi nella
consoleGoogle Cloud . Supponiamo che la tabella memorizzi informazioni provenienti da diverse stazioni
meteo identificate da un station_id. Ogni stazione registra la
temperatura in gradi Fahrenheit in una colonna denominata temp_f. Anziché
calcolare la temperatura nella tua applicazione, puoi utilizzare una query SQL per
convertire queste temperature in gradi Celsius direttamente in
Bigtable prima di inviare i risultati alla tua applicazione. Per
maggiori informazioni sull'esecuzione di query sulla tabella dei dati meteo, consulta Query di esempio
sui dati.
Best practice
Per ottimizzare il rendimento e l'utilizzo delle risorse, tieni presente le seguenti best practice quando sviluppi applicazioni:
- Riutilizza il client: crea un singolo
BigtableDataClientper la tua applicazione. Il client gestisce la gestione dei canali gRPC ed è progettato per un'elevata concorrenza. Ti consigliamo di creare questo client una sola volta dopo l'avvio dell'applicazione e di riutilizzarlo per ogni query. - Utilizza query con parametri:utilizza
PreparedStatementper separare la logica della query dai valori dei dati. In questo modo, Bigtable può memorizzare nella cache il piano di esecuzione e impedire l'SQL injection. - Riutilizza le istruzioni preparate:chiama
PreparedStatementuna sola volta per stringa SQL. Memorizzare e riutilizzare l'affermazione in più richieste.
Crea il client Bigtable
Per gestire la connessione tra l'applicazione e Bigtable,
crea un BigtableDataClient. Il seguente esempio mostra come condividere una singola istanza client nell'applicazione per gestire le connessioni in modo efficiente:
BigtableDataSettings settings = BigtableDataSettings.newBuilder()
.setProject(PROJECT_ID)
.setInstance(INSTANCE_ID)
.build();
// The client is thread-safe and should be reused.
try (BigtableDataClient dataClient = BigtableDataClient.create(settings)) {
System.out.println("Connected to: " + INSTANCE_ID);
}
Prepara la query
Anziché inserire i dati direttamente in una stringa SQL, ti consigliamo di utilizzare query con parametri. In GoogleSQL per Bigtable, le query con parametri sono l'equivalente di un'istruzione preparata. In questo modo puoi separare la logica della query dai valori dei dati.
Il seguente esempio mostra come definire la query GoogleSQL
utilizzando segnaposto dei parametri, ad esempio @sid. Poi crea un PreparedStatement
specificando la stringa SQL e i tipi per ogni parametro in modo che la query
possa essere eseguita più velocemente la volta successiva:
Map<String, SqlType<?>> paramTypes = new HashMap<>();
paramTypes.put("sid", SqlType.string());
String sql = "SELECT " +
"ROUND((CAST(CAST(weather['temp_f'] AS STRING) AS INT64) - 32) * 5 / 9, 2) AS temp_celsius " +
"FROM " + TABLE_NAME + " WHERE station_id = @sid LIMIT 1";
// Create and reuse the PreparedStatement.
PreparedStatement preparedStatement = dataClient.prepareStatement(sql, paramTypes);
Esegui la query
Fornisci i valori dei parametri ed esegui la query. Il seguente esempio mostra come
utilizzare PreparedStatement per associare valori ai parametri per creare un
BoundStatement. Dopodiché esegue la query e scorre i risultati per stampare
ResultSet, ovvero la temperatura in gradi Celsius:
BoundStatement boundStatement = preparedStatement.bind()
.setStringParam("sid", stationId)
.build();
try (ResultSet resultSet = dataClient.executeQuery(boundStatement)) {
while (resultSet.next()) {
System.out.println("Temp: " + resultSet.getDouble("temp_celsius"));
}
}
Controllare la struttura dei dati
Quando sviluppi o esplori SQL, ti consigliamo di esaminare i metadati
associati alla tabella per comprendere la struttura dei dati. Poiché
Bigtable ha uno schema flessibile, se utilizzi query SELECT *,
i risultati della query possono variare in base ai dati. Pertanto, ti consigliamo di non utilizzare query SELECT * nelle applicazioni di produzione.
Il seguente esempio esamina i metadati del set di risultati (ad esempio i nomi e i tipi delle colonne) e li invia di nuovo al client indipendentemente dai dati. In questo modo puoi ottenere prima le informazioni sulle colonne e poi creare la struttura dei dati necessaria per elaborare i dati nell'applicazione.
ResultSetMetadata metadata = resultSet.getMetadata();
System.out.print("Columns: ");
metadata.getColumnsList().forEach(col -> System.out.print(col.getName() + " "));
System.out.println();
Lavorare con le famiglie di colonne
Bigtable archivia i dati nelle famiglie di colonne. GoogleSQL
restituisce queste famiglie come elenchi di nomi e valori noti come
mappe di qualificatori di colonne
e valori. Quando legge una famiglia di colonne, Bigtable restituisce il tipo SqlType.Map. Quando leggi una famiglia di colonne da una tabella con cronologia, ad esempio SELECT column FROM my_table(with_history=>true), Bigtable restituisce un tipo SqlType.historicalMap(), che è una mappa dei qualificatori di colonna e un array di timestamp e valori delle celle. Per altri esempi di tipi di SqlType, vedi
SqlType.
L'esempio seguente mostra come, anziché ottenere una colonna alla volta, puoi ottenere un intero gruppo di colonne contemporaneamente. Il codice memorizza la famiglia di colonne in una mappa in modo da poter scorrere tutti i nomi e i valori:
Map<String, SqlType<?>> paramTypes = new HashMap<>();
paramTypes.put("keyPrefix", SqlType.bytes());
String sql = String.format("SELECT weather FROM %s WHERE STARTS_WITH(_key, @keyPrefix)", TABLE_NAME);
PreparedStatement preparedStatement = dataClient.prepareStatement(sql, paramTypes);
BoundStatement boundStatement = preparedStatement.bind()
.setBytesParam("keyPrefix", ByteString.copyFromUtf8(key))
.build();
try (ResultSet resultSet = dataClient.executeQuery(boundStatement)) {
while (resultSet.next()) {
SqlType.Map<ByteString, ByteString> mapType = SqlType.mapOf(SqlType.bytes(), SqlType.bytes());
Map<ByteString, ByteString> weatherValues = resultSet.getMap("weather", mapType);
for (Map.Entry<ByteString, ByteString> entry : weatherValues.entrySet()) {
System.out.printf("%s = %s\n",
entry.getKey().toStringUtf8(),
entry.getValue().toStringUtf8());
}
}
}
Passaggi successivi
- Esplora la documentazione di riferimento di GoogleSQL per Bigtable.
- Scopri come scrivere SQL con l'assistenza di Gemini.