Développer des applications avec GoogleSQL pour Bigtable
Vous pouvez utiliser GoogleSQL pour Bigtable afin d'exécuter des requêtes depuis vos applications pour décharger les fonctions de calcul sur Bigtable. Cela réduit le besoin de traitement côté client. GoogleSQL est un langage de requête structuré conforme à la norme ANSI, implémenté pour Bigtable et d'autres services Google Cloud . Pour en savoir plus sur les autres utilisations de GoogleSQL pour Bigtable, consultez la présentation de GoogleSQL pour Bigtable.
Avant de commencer
Assurez-vous de disposer des éléments suivants :
- Une instance et une table Bigtable.
- La bibliothèque cliente Bigtable pour votre langage. Pour savoir comment installer et utiliser les bibliothèques clientes pour Bigtable, consultez Bibliothèques clientes Bigtable.
- Authentification configurée à l'aide des Identifiants par défaut de l'application (ADC). Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.
Exemple de scénario
Les exemples de ce guide utilisent un exemple de table weather-data auquel vous pouvez accéder depuis votre instance d'essai sans frais dans la consoleGoogle Cloud . Supposons que votre table stocke des informations provenant de différentes stations météo identifiées par un station_id. Chaque station enregistre la température en degrés Fahrenheit dans une colonne nommée temp_f. Au lieu de calculer la température dans votre application, vous pouvez utiliser une requête SQL pour convertir ces températures en degrés Celsius directement dans Bigtable avant de renvoyer les résultats à votre application. Pour en savoir plus sur l'interrogation de la table de données météorologiques, consultez Exemple de requête de données.
Bonnes pratiques
Pour optimiser les performances et l'utilisation des ressources, tenez compte des bonnes pratiques suivantes lorsque vous développez des applications :
- Réutiliser le client : créez un seul
BigtableDataClientpour votre application. Le client gère la gestion des canaux gRPC et est conçu pour une forte simultanéité. Nous vous recommandons de créer ce client une seule fois après le démarrage de votre application, puis de le réutiliser pour chaque requête. - Utilisez des requêtes paramétrées : utilisez
PreparedStatementpour séparer la logique de requête des valeurs de données. Cela permet à Bigtable de mettre en cache le plan d'exécution et d'empêcher l'injection SQL. - Réutilisez les instructions préparées : n'appelez
PreparedStatementqu'une seule fois par chaîne SQL. Stockez et réutilisez l'instruction dans plusieurs requêtes.
Créer le client Bigtable
Pour gérer la connexion entre votre application et Bigtable, créez un BigtableDataClient. L'exemple suivant montre comment partager une seule instance de client dans votre application pour gérer efficacement les connexions :
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);
}
Préparer la requête
Au lieu de placer vos données directement dans une chaîne SQL, nous vous recommandons d'utiliser des requêtes paramétrées. Dans GoogleSQL pour Bigtable, les requêtes paramétrées sont l'équivalent d'une instruction préparée. Cela vous permet de séparer la logique de la requête des valeurs de données.
L'exemple suivant montre comment définir votre requête GoogleSQL à l'aide d'espaces réservés pour les paramètres, tels que @sid. Créez ensuite un PreparedStatement en spécifiant la chaîne SQL et les types de chaque paramètre afin que la requête puisse s'exécuter plus rapidement la prochaine fois :
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);
Exécuter la requête
Indiquez les valeurs des paramètres et exécutez la requête. L'exemple suivant montre comment utiliser PreparedStatement pour lier des valeurs à vos paramètres afin de créer un BoundStatement. Il exécute ensuite la requête et parcourt les résultats pour afficher ResultSet, qui correspond à la température en degrés 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"));
}
}
Vérifier la structure des données
Lorsque vous développez ou explorez du code SQL, nous vous recommandons d'explorer les métadonnées associées à la table pour comprendre la structure des données. Comme Bigtable dispose d'un schéma flexible, si vous utilisez des requêtes SELECT *, les résultats de vos requêtes peuvent changer en fonction des données. Par conséquent, nous vous recommandons de ne pas utiliser les requêtes SELECT * dans les applications de production.
L'exemple suivant examine les métadonnées de l'ensemble de résultats (telles que les noms et les types de colonnes), puis les renvoie au client indépendamment des données. Cela vous permet d'obtenir d'abord les informations sur les colonnes, puis de créer la structure de données dont vous avez besoin pour traiter les données dans l'application.
ResultSetMetadata metadata = resultSet.getMetadata();
System.out.print("Columns: ");
metadata.getColumnsList().forEach(col -> System.out.print(col.getName() + " "));
System.out.println();
Utiliser les familles de colonnes
Bigtable stocke les données dans des familles de colonnes. GoogleSQL renvoie ces familles sous forme de listes de noms et de valeurs appelées maps de qualificateurs et de valeurs de colonnes. Lors de la lecture d'une famille de colonnes, Bigtable renvoie le type SqlType.Map. Lorsque vous lisez une famille de colonnes à partir d'une table avec historique, telle que SELECT column FROM my_table(with_history=>true), Bigtable renvoie un type SqlType.historicalMap(), qui est un mappage des qualificateurs de colonne et d'un tableau des valeurs et des codes temporels des cellules. Pour obtenir d'autres exemples de types SqlType, consultez SqlType.
L'exemple suivant montre comment obtenir un groupe entier de colonnes à la fois, au lieu d'une colonne à la fois. Le code stocke la famille de colonnes dans une carte afin que vous puissiez parcourir tous les noms et valeurs :
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());
}
}
}
Étapes suivantes
- Consultez la documentation de référence sur GoogleSQL pour Bigtable.
- Découvrez comment écrire du code SQL avec l'assistance Gemini.