Desarrolla aplicaciones con GoogleSQL para Bigtable
Puedes usar GoogleSQL para Bigtable para ejecutar consultas desde tus aplicaciones y transferir funciones de procesamiento a Bigtable. Esto reduce la necesidad de procesamiento del cliente. GoogleSQL es un lenguaje de consulta estructurado compatible con ANSI que se implementó para Bigtable y otros Google Cloud servicios. Para obtener más información sobre otros usos de GoogleSQL para Bigtable, consulta Descripción general de GoogleSQL para Bigtable.
Antes de comenzar
Asegúrate de tener lo siguiente:
- Una instancia y una tabla de Bigtable
- La biblioteca cliente de Bigtable para tu lenguaje (para obtener más información sobre cómo instalar y usar bibliotecas cliente para Bigtable, consulta Bibliotecas cliente de Bigtable)
- Autenticación configurada a través de las credenciales predeterminadas de la aplicación (ADC) (para obtener más información, consulta Configura la autenticación para un entorno de desarrollo local)
Situación de ejemplo
En los ejemplos de esta guía, se usa una tabla de muestra weather-data a la que puedes acceder
desde tu instancia de prueba gratuita en la
Google Cloud consola. Supongamos que tu tabla almacena información de diferentes estaciones meteorológicas que se identifican con un station_id. Cada estación registra la temperatura en la escala Fahrenheit en una columna llamada temp_f. En lugar de calcular la temperatura en tu aplicación, puedes usar una consulta en SQL para convertir estas temperaturas a la escala Celsius directamente en Bigtable antes de enviar los resultados a tu aplicación. Para
obtener más información sobre cómo consultar la tabla de datos meteorológicos, consulta Consulta datos de muestra
data.
Prácticas recomendadas
Para optimizar el rendimiento y el uso de recursos, considera las siguientes prácticas recomendadas cuando desarrolles aplicaciones:
- Reutiliza el cliente: Crea un solo
BigtableDataClientpara tu aplicación. El cliente controla la administración de canales gRPC y está diseñado para una alta simultaneidad. Te recomendamos que crees este cliente una vez después de que se inicie la aplicación y, luego, lo reutilices para cada consulta. - Usa consultas con parámetros: Usa
PreparedStatementpara separar la lógica de consulta de los valores de datos. Esto permite que Bigtable almacene en caché el plan de ejecución y evita la inyección de SQL. - Reutiliza las instrucciones preparadas: Llama a
PreparedStatementsolo una vez por cadena de SQL. Almacena y reutiliza la instrucción en varias solicitudes.
Crea el cliente de Bigtable
Para controlar la conexión entre tu aplicación y Bigtable, crea un BigtableDataClient. En el siguiente ejemplo, se muestra cómo compartir una sola instancia de cliente en tu aplicación para administrar las conexiones de manera eficiente:
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 consulta
En lugar de colocar los datos directamente en una cadena de SQL, te recomendamos que uses consultas con parámetros. En GoogleSQL para Bigtable, las consultas con parámetros son el equivalente de una instrucción preparada. Esto te permite separar la lógica de consulta de los valores de datos.
En el siguiente ejemplo, se muestra cómo definir tu consulta de GoogleSQL con marcadores de posición de parámetros, como @sid. Luego, crea un PreparedStatement especificando la cadena de SQL y los tipos para cada parámetro de modo que la consulta se pueda ejecutar más rápido la próxima vez:
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);
Ejecuta la consulta
Proporciona valores de parámetros y ejecuta la consulta. En el siguiente ejemplo, se muestra cómo usar PreparedStatement para vincular valores a tus parámetros para crear un BoundStatement. Luego, ejecuta la consulta y recorre los resultados para imprimir el ResultSet, que es la temperatura en grados 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"));
}
}
Verifica la estructura de datos
Cuando desarrolles o explores SQL, te recomendamos que explores los metadatos asociados con la tabla para comprender la estructura de datos. Debido a que Bigtable tiene un esquema flexible, si usas consultas SELECT *, los resultados de la consulta pueden cambiar según los datos. Por lo tanto, te recomendamos que no uses consultas SELECT * en aplicaciones de producción.
En el siguiente ejemplo, se observan los metadatos del conjunto de resultados (como los nombres y tipos de columnas) y, luego, se envían de vuelta al cliente de forma independiente de los datos. Esto te permite obtener primero la información de la columna y, luego, crear la estructura de datos que necesitas para procesar los datos en la aplicación.
ResultSetMetadata metadata = resultSet.getMetadata();
System.out.print("Columns: ");
metadata.getColumnsList().forEach(col -> System.out.print(col.getName() + " "));
System.out.println();
Trabaja con familias de columnas
Bigtable almacena datos en familias de columnas. GoogleSQL
muestra estas familias como listas de nombres y valores que se conocen como
mapas de calificadores
y valores de columnas. Cuando se lee una familia de columnas, Bigtable muestra el tipo SqlType.Map. Cuando se lee una familia de columnas de una tabla con historial, como
SELECT column FROM my_table(with_history=>true), Bigtable
muestra un
SqlType.historicalMap()
tipo, que es un mapa de calificadores de columnas y un array de marcas de tiempo y
valores de celdas. Para obtener más ejemplos de tipos SqlType, consulta
SqlType.
En el siguiente ejemplo, se muestra cómo, en lugar de obtener una columna a la vez, puedes obtener un grupo completo de columnas a la vez. El código almacena la familia de columnas en un mapa para que puedas recorrer todos los nombres y valores:
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());
}
}
}
¿Qué sigue?
- Explora la documentación de referencia de GoogleSQL para Bigtable.
- Aprende a escribir SQL con la ayuda de Gemini.