Diseña tu esquema

En esta página, se presenta información sobre el diseño de esquemas de Cloud Bigtable. Antes de leer esta página, debes familiarizarte con la descripción general de Cloud Bigtable. Los temas siguientes se tratan en esta página:

  • Conceptos generales: conceptos básicos que debes tener en cuenta cuando diseñas tu base de datos.
  • Prácticas recomendadas: Lineamientos de diseño que se aplican a la mayoría de los casos prácticos, desglosados por componente de tabla
  • Casos prácticos especiales: recomendaciones para algunos casos prácticos específicos y patrones de datos

Conceptos generales

Diseñar un esquema de Cloud Bigtable es muy diferente a diseñar un esquema para una base de datos relacional. En Cloud Bigtable, un esquema es un modelo o modelo de una tabla, incluida la estructura de los siguientes componentes de la tabla:

  • clave(s) de fila
  • Familias de columnas, incluidas las políticas de recolección de elementos no utilizados
  • Columnas

Los siguientes conceptos generales se aplican al diseño de esquemas de Cloud Bigtable:

  • Cloud Bigtable es un almacén de clave-valor, no un almacén relacional. No admite uniones y las transacciones solo se admiten dentro de una fila.
  • Cada tabla tiene solo un índice: la clave de fila. No existen índices secundarios. Cada clave de fila debe ser única.
  • Las filas se ordenan lexicográficamente por clave de fila, desde la mayor string de bytes a la menor. Las claves de filas siguen el orden de bytes big-endian (a veces llamado orden de bytes de red), que es el equivalente binario del orden alfabético.
  • Las familias de columnas no se almacenan en ningún orden específico.
  • Las columnas se agrupan por familia de columnas y se clasifican en orden lexicográfico dentro de la familia de columnas. Por ejemplo, en una familia de columnas llamada SysMonitor con calificadores de columna de ProcessName, User, %CPU, ID, Memory, DiskRead y Priority, Cloud Bigtable almacena las columnas en este orden:
SysMonitor
%CPU DiskRead ID Memoria Prioridad ProcessName Usuario
  • La intersección de una fila y una columna puede contener varias celdas con marcas de tiempo. Cada celda contiene una versión única con marca de tiempo de los datos de esa fila y esa columna.
  • Todas las operaciones son atómicas a nivel de fila. Esto significa que una operación afecta a una fila completa o a ninguna.
  • Lo ideal es que las lecturas y escrituras se distribuyan de manera uniforme en el espacio de filas de la tabla.

  • Las tablas de Cloud Bigtable son dispersas. Una columna no ocupa ningún espacio en una fila que no use la columna.

Prácticas recomendadas

Un buen esquema genera un excelente rendimiento y escalabilidad, mientras que uno malo puede provocar un rendimiento deficiente del sistema. Cada caso práctico es diferente y requiere su propio diseño, pero las prácticas recomendadas siguientes se aplican a la mayoría de los casos prácticos. Se indican las excepciones.

A continuación, se describen las prácticas recomendadas para el diseño de esquemas a partir del nivel de la tabla y de aquí al nivel de las claves de fila:

Todos los elementos de la tabla, en especial las claves de fila, deben estar diseñados para admitir las solicitudes de lectura planificada. Verifica las cuotas y límites de los límites recomendados y los tamaños complejos para todos los elementos de la base de datos.

Tablas

Almacenar conjuntos de datos con esquemas similares en la misma tabla, en lugar de tablas separadas.

En otros sistemas de bases de datos, puedes elegir almacenar datos en varias tablas según el asunto y la cantidad de columnas. Sin embargo, en Cloud Bigtable, por lo general, es mejor almacenar todos tus datos en una sola tabla. Puedes asignar un prefijo de clave de fila único para usar en cada conjunto de datos, de manera que Cloud Bigtable almacene los datos relacionados en un rango contiguo de filas que, luego, puedes consultar por prefijo de clave de fila.

Cloud Bigtable tiene un límite de 1,000 tablas por instancia, pero en la mayoría de los casos, deberías tener muchas menos. La creación de muchas tablas pequeñas es un antipatrón de Cloud Bigtable por algunas razones:

  • El envío de solicitudes a muchas tablas diferentes puede aumentar la sobrecarga de la conexión de backend, lo que aumenta la latencia final.
  • Tener varias tablas de diferentes tamaños puede interrumpir el balanceo de cargas tras bambalinas que hace que Cloud Bigtable funcione.

Es lógico que desees una tabla separada para un caso práctico completamente diferente que requiera un esquema distinto, pero no debes usar tablas separadas para datos similares. Por ejemplo, no debes crear una tabla nueva por un año nuevo o un cliente nuevo.

Familias de columnas

Coloca las columnas relacionadas en la misma familia de columnas. Cuando una fila contiene varios valores relacionados entre sí, se recomienda agrupar las columnas que contienen esos valores en la misma familia de columnas. Agrupa los datos de la forma más sencilla para evitar la necesidad de diseñar filtros complejos y, por lo tanto, obtener solo la información que necesitas, pero no más, en tus solicitudes de lectura más frecuentes.

Crea hasta 100 familias de columnas por tabla. Crear más de 100 familias de columnas puede causar una degradación del rendimiento.

Elige nombres cortos, pero significativos para tus familias de columnas. Los nombres se incluyen en los datos que se transfieren para cada solicitud.

Coloca las columnas que tienen diferentes necesidades de retención de datos en diferentes familias de columnas. Esto es importante si quieres limitar los costos de almacenamiento. Las políticas de recolección de elementos no utilizados se establecen a nivel de la familia de columnas, no a nivel de la columna. Por ejemplo, si solo necesitas mantener la versión más reciente de un dato en particular, no la almacenes en una familia de columnas configurada para almacenar 1,000 versiones de algo más. De lo contrario, pagas para almacenar datos de 999 celdas que no necesitas.

Columnas

Tratar los calificadores de columna como datos. Como tienes que almacenar un calificador de columna para cada columna, puedes ahorrar espacio si asignas un nombre a la columna con un valor. Como ejemplo, considera una tabla que almacena datos sobre amistades, en la que cada fila representa a una persona y todas sus amistades. Cada calificador de columna puede ser el ID de un amigo, y el valor de esa columna en esa fila puede ser el círculo social en el que se encuentra el amigo. En este ejemplo, las filas podrían verse de la siguiente manera:

Jose Fred:club de lectura Gabriel:trabajo Hiroshi:tenis
Sofía Hiroshi:trabajo Seo Yoon:escuela Jakob:club de ajedrez

Compara esto con un esquema para los mismos datos que no usan calificadores de columnas como datos:

Jose#1 Amigo:Fred Círculo: club de lectura
Jose#2 Amigo:Gabriel Círculo:trabajo
Jose#3 Amigo:Hiroshi Círculo:tenis
Sofia#1 Friend:Hiroshi Circle:work
Sofia#2 Amigo:Seo Yoon Círculo:escuela
Sofia# Amigo:Jakob Circle:ajedrez-club

El segundo diseño de esquema hace que la tabla crezca mucho más rápido.

Si no usas calificadores de columnas para almacenar datos y deseas reducir la cantidad de datos que se transfieren para cada solicitud, otorga nombres de columna cortos y significativos. El tamaño máximo es de 16 KB.

Crea tantas columnas como necesites en la tabla. Las tablas de Cloud Bigtable son dispersas y no hay penalización espacial por una columna que no se use en una fila. Puedes tener millones de columnas en una tabla, siempre que ninguna fila supere el límite máximo de 256 MB por fila.

Evita usar demasiadas columnas en una sola fila. Aunque una tabla puede tener millones de columnas, una fila no debería hacerlo. Algunos factores contribuyen a esta práctica recomendada:

  • Cloud Bigtable demora en procesar cada celda de una fila.
  • Cada celda agrega algo de sobrecarga a la cantidad de datos que se almacenan en tu tabla y que se envían por la red. Por ejemplo, si almacenas 1 KB (1,024 bytes) de datos, sería mucho más eficiente almacenarlos en una sola celda que dividirlos en 1,024 celdas y que cada una contenga 1 byte.

Si tu conjunto de datos requiere más columnas de manera lógica que las que Cloud Bigtable puede procesar de manera eficiente, considera almacenar los datos como un protobuf en una sola columna.

Filas

No almacenes más de 100 MB de datos en una sola fila. Las filas que superan este límite pueden reducir el rendimiento de la lectura.

Mantén toda la información de una entidad en una sola fila. En la mayoría de los casos prácticos, evita almacenar datos que necesites leer de forma atómica o de una sola fila en más de una fila para evitar inconsistencias. Por ejemplo, si actualizas dos filas de una tabla, es posible que una fila se actualice correctamente y la otra actualización falle. Asegúrate de que el esquema no requiera más de una fila para actualizarse a la vez para que los datos relacionados sean precisos. Esto garantiza que, si parte de una solicitud de escritura falla o se debe volver a enviar, ese dato no estará incompleto temporalmente.

Excepción: Si mantener una entidad en una sola fila genera filas de gran tamaño de MB, debes dividir los datos en varias filas.

Almacenar entidades relacionadas en filas adyacentes para que las lecturas sean más eficientes.

celdas

No almacenes más de 10 MB de datos en una sola celda. Recuerda que una celda son los datos almacenados para una fila y columna determinadas con una marca de tiempo única, y que varias celdas pueden almacenarse en la intersección de esa fila y columna. La cantidad de celdas retenidas en una columna se rige por la política de recopilación de elementos no utilizados que estableces para la familia de columnas de la columna.

clave(s) de fila

Diseña tu clave de fila basada en las consultas que usarás para recuperar los datos. Las claves de fila bien diseñadas obtienen el mejor rendimiento de Cloud Bigtable. Las consultas más eficientes de Cloud Bigtable recuperan datos mediante uno de los siguientes comandos:

  • Clave de fila
  • Prefijo de la clave de fila
  • Rango de filas definido por las claves de fila de inicio y de finalización

Otros tipos de consultas activan un análisis completo de la tabla, lo que es mucho menos eficiente. Si eliges la clave de fila correcta, te ahorrarás un proceso de migración de datos agotador en el futuro

Usa una clave de fila corta. Una clave de fila debe ser de 4 KB o menos. Las claves de fila largas ocupan más memoria y almacenamiento, y aumentan el tiempo necesario para obtener respuestas del servidor de Cloud Bigtable.

Almacena varios valores delimitados en cada clave de fila. Debido a que la mejor manera de consultar Cloud Bigtable de forma eficiente es por clave de fila, a menudo es útil incluir varios identificadores en tu clave de fila. Es especialmente importante comprender en profundidad cómo usarás tus datos cuando tu clave de fila incluye varios valores.

Los segmentos de claves de fila suelen estar separados por un delimitador, como dos puntos, barras diagonales o símbolos de hash. El primer segmento o conjunto de segmentos contiguos es el prefijo de clave de fila y el último segmento o conjunto de segmentos contiguos es el sufijo de la clave de fila.

Clave de fila de muestra

Los prefijos de clave de fila bien planificados te permiten aprovechar el orden de clasificación de Cloud Bigtable para almacenar datos relacionados en filas contiguas. El almacenamiento de datos relacionados en filas contiguas te permite acceder a datos relacionados como un rango de filas, en lugar de ejecutar análisis ineficientes de las tablas.

Si tus datos incluyen números enteros que deseas almacenar o ordenar de manera numérica, escribe los números enteros con ceros iniciales. Cloud Bigtable almacena datos de forma lexicográfica. Por ejemplo, 3D > 20, pero 20 > 03. Si rellenas 3 con un cero inicial, te aseguras de que los números estén ordenados de forma numérica. Esta táctica es importante para las marcas de tiempo en las que se desean consultas basadas en un rango.

Es importante crear una clave de fila que permita recuperar un rango de filas bien definido. De lo contrario, tu consulta requiere un análisis de tabla, que es mucho más lento que recuperar filas específicas.

Por ejemplo, si tu aplicación realiza un seguimiento de los datos de dispositivos móviles, puedes tener una clave de fila que sea del tipo de dispositivo, el ID del dispositivo y el día en que se registran los datos. Las claves de fila para estos datos podrían verse así:

        phone#4c410523#20200501
        phone#4c410523#20200502
        tablet#a0b81f74#20200501
        tablet#a0b81f74#20200502

Este diseño de clave de fila te permite recuperar datos con una sola solicitud para:

  • Un tipo de dispositivo
  • Una combinación del tipo de dispositivo y el ID del dispositivo

Este diseño de clave de fila no sería óptimo si deseas recuperar todos los datos de un día determinado. Debido a que el día se almacena en el tercer segmento o en el sufijo de la clave de fila, no solo puedes solicitar un rango de filas basadas en el sufijo o un segmento medio de la clave de fila. En su lugar, debes enviar una solicitud de lectura con un filtro que analice toda la tabla en busca del valor de día.

Usa valores de string legibles en tus claves de fila siempre que sea posible. Esta práctica facilita el uso de la herramienta Key Visualizer para solucionar problemas con Cloud Bigtable.

En muchos casos, debes diseñar claves de filas que comienzan con un valor común y terminan con un valor detallado. Por ejemplo, si tu clave de fila incluye un continente, un país y una ciudad, puedes crear claves de fila parecidas a la siguiente para que ordenen de forma automática por valores con cardinalidad baja:

        asia#india#bangalore
        asia#india#mumbai
        asia#japan#okinawa
        asia#japan#sapporo
        southamerica#bolivia#cochabamba
        southamerica#bolivia#lapaz
        southamerica#chile#santiago
        southamerica#chile#temuco

Claves de fila que debes evitar

Algunos tipos de claves de fila pueden dificultar la consulta de tus datos, lo que puede causar un rendimiento bajo. En esta sección, se describen algunos tipos de claves de fila que debes evitar usar en Cloud Bigtable.

Claves de fila que comienzan con una marca de tiempo Esto hará que las escrituras secuenciales se envíen a un solo nodo y cree un hotspot. Si escribes una marca de tiempo en una clave de fila, debes precederla con un valor de cardinalidad alta como un ID de usuario para evitar la generación de hotspots.

Claves de fila que provocan que los datos relacionados no se agrupen. Evita usar claves de fila que hagan que los datos relacionados se almacenen en rangos de filas no contiguos, que son ineficientes que se deben leer juntos.

ID numéricos secuenciales. Imagina que tu sistema asigna un ID numérico a cada uno de los usuarios de tu aplicación. Es posible que te parezca una buena idea usar el ID numérico del usuario como clave de fila en tu tabla. Sin embargo, debido a que es más probable que los usuarios nuevos sean usuarios activos, es posible que este enfoque envíe la mayor parte de tu tráfico a una pequeña cantidad de nodos.

Un enfoque más seguro es usar una versión invertida del ID numérico del usuario, que distribuye el tráfico de manera más uniforme en todos los nodos de tu tabla de Cloud Bigtable.

Identificadores que se actualizan con frecuencia Evita usar una sola clave de fila para identificar un valor que debe actualizarse con mucha frecuencia. Por ejemplo, si almacenas datos de uso de memoria para varios dispositivos una vez por segundo, no uses una clave de fila única para cada dispositivo que esté formado por el ID de dispositivo. y la métrica que se almacena, como 4c410523#memusage, y actualiza la fila repetidamente. Este tipo de operación sobrecarga la tablet que almacena la fila de uso frecuente. También puede hacer que una fila supere su límite de tamaño, ya que los valores anteriores de una columna ocupan espacio hasta que se recopilen elementos no utilizados.

En su lugar, almacena cada lectura nueva en una fila nueva. Con el ejemplo de uso de memoria, cada clave de fila puede contener el ID de dispositivo, el tipo de métrica y una marca de tiempo, por lo que las claves de fila son similares a 4c410523#memusage#1423523569918. Esta estrategia es eficiente porque en Cloud Bigtable, crear una fila nueva no lleva más tiempo que crear una celda nueva. Además, esta estrategia te permite leer rápidamente los datos de un período de fechas específico, mediante el cálculo de las claves de inicio y fin adecuadas.

Para los valores que cambian con mucha frecuencia, como un contador que se actualiza cientos de veces por minuto, la mejor opción es simplemente mantener los datos en la memoria, en la capa de la aplicación, y escribir nuevas filas en Cloud Bigtable periódicamente.

Valores de hash. La codificación hash de una clave de fila quita tu capacidad de aprovechar el orden natural de clasificación de Cloud Bigtable, lo que hace imposible almacenar las filas de una manera óptima para realizar consultas. Por el mismo motivo, la codificación hash en los valores hace que sea difícil usar la herramienta Key Visualizer para solucionar problemas con Cloud Bigtable. Usa valores legibles en lugar de valores con hash.

Valores expresados como bytes sin procesar en lugar de strings legibles. Los bytes sin procesar son adecuados para los valores de columnas, pero, para facilitar la lectura y solucionar problemas, usa valores de string en las claves de fila.

Casos prácticos especiales

Es posible que tengas un conjunto de datos único que requiera una consideración especial cuando se diseña un esquema para almacenarlo en Cloud Bigtable. En esta sección, se describen algunos tipos de datos de Cloud Bigtable, pero no todos, y algunas estrategias sugeridas para almacenarlos de la forma más óptima.

Datos basados en el tiempo

Incluye una marca de tiempo como parte de tu clave de fila si necesitas recuperar datos en función del tiempo que se registró.

Por ejemplo, es posible que tu aplicación necesite registrar datos relacionados con el rendimiento, como el uso de la CPU y la memoria, una vez por segundo para una gran cantidad de máquinas. Tu clave de fila, en el caso de estos datos, podría combinar un identificador de la máquina con una marca de tiempo para los datos (por ejemplo, machine_4223421#1425330757685). Ten en cuenta que las claves de fila se ordenan de manera lexicográfica.

No uses una marca de tiempo sola ni al comienzo de una clave de fila, ya que esto hará que las escrituras secuenciales se envíen a un solo nodo y se creará un hotspot.

Si sueles priorizar la recuperación de tus registros más recientes, puedes usar una marca de tiempo invertida en la clave de fila y quitarla del valor máximo de tu lenguaje de programación para números enteros largos (en Java, java.lang.Long.MAX_VALUE). Con una marca de tiempo invertida, los registros se ordenarán de más reciente a menos reciente.

Para obtener información específica sobre cómo trabajar con datos de series temporales, consulta Diseño de esquemas para datos de series temporales.

Multiusuario

Los prefijos de clave de fila proporcionan una solución escalable para los casos prácticos de “instancias múltiples”, lo que ocurre cuando almacenas datos similares, con el uso del mismo modelo de datos, en nombre de varios clientes. El uso de una tabla para todas las instancias es la forma más eficaz de almacenar y acceder a los datos de varias instancias.

Por ejemplo, supongamos que almacenas y realizas un seguimiento de los historiales de compra en nombre de muchas empresas. Puedes usar tu ID único para cada empresa como prefijo de clave de fila. Todos los datos de una instancia se almacenan en filas contiguas en la misma tabla, y puedes consultar o filtrar con el prefijo de clave de fila. Luego, cuando una empresa ya no es tu cliente y necesitas borrar los datos del historial de compras que almacenabas para la empresa, puedes descartar el rango de filas que usan el prefijo de clave de fila del cliente.

Por ejemplo, si almacenas datos de teléfonos celulares para los clientes altostrat y examplepetstore, puedes crear claves de fila como las siguientes. Luego, si altostrat ya no es tu cliente, descarta todas las filas con el prefijo de clave de fila altostrat.

        altostrat#phone#4c410523#20190501
        altostrat#phone#4c410523#20190502
        altostrat#tablet#a0b41f74#20190501
        examplepetstore#phone#4c410523#20190502
        examplepetstore#tablet#a6b81f79#20190501
        examplepetstore#tablet#a0b81f79#20190502

En cambio, si almacenas datos en nombre de cada empresa en su propia tabla, puedes experimentar problemas de escalabilidad y rendimiento. También es muy probable que, sin darte cuenta, alcances el límite de 1,000 tablas por instancia de Cloud Bigtable. Después de que una instancia alcanza este límite, Cloud Bigtable evita que crees más tablas en la instancia.

Privacidad

A menos que tu caso práctico lo requiera, evita usar información de identificación personal (PII) o datos de usuario en claves de fila o ID de familia de columnas. Las claves de fila y las familias de columnas son datos y metadatos, y las aplicaciones que los utilizan como metadatos, como la encriptación o el registro, pueden exponerlos accidentalmente a los usuarios que no deberían tener acceso a datos privados.

Nombres de dominio

Amplia variedad de nombres de dominio

Si almacenas datos sobre entidades que pueden representarse como nombres de dominio, considera usar un nombre de dominio inverso (por ejemplo, com.company.product) como la clave de fila. El uso de un nombre de dominio inverso es ideal si los datos de cada fila tienden a superponerse con las filas adyacentes. En este caso, en Cloud Bigtable se pueden comprimir tus datos de manera más eficiente.

En cambio, los nombres de dominio estándar que no se revierten pueden hacer que las filas se ordenen de tal manera que los datos relacionados no se agrupen en un solo lugar, lo que puede generar una compresión menos eficiente y lecturas menos eficientes.

Este enfoque funciona mejor cuando tus datos se distribuyen a través de muchos nombres de dominio inversos diferentes.

Para ilustrar este punto, considera los siguientes nombres de dominio, ordenados automáticamente por orden lexicográfico por Cloud Bigtable:

      drive.google.com
      en.wikipedia.org
      maps.google.com

Esto no es recomendable para el caso práctico en el que deseas consultar todas las filas de google.com. Por el contrario, considera las mismas filas en las que se revirtieron los nombres de dominio:

      com.google.drive
      com.google.maps
      org.wikipedia.en

En el segundo ejemplo, las filas relacionadas se ordenan automáticamente de una manera que facilita la recuperación como un rango de filas.

Pocos nombres de dominio

Si esperas almacenar muchos datos solo para uno o un número pequeño de nombres de dominio, considera otros valores para tu clave de fila. De lo contrario, puedes enviar escrituras a un solo nodo en tu clúster, lo que provocará la generación de hotspots o tus filas podrían crecer demasiado.

Consultas cambiantes o inciertos

Si no siempre ejecutas las mismas consultas en tus datos o no estás seguro de cuáles serán tus consultas, una opción es almacenar todos los datos de una fila en una columna en lugar de usar varias columnas. Con este enfoque, se usa un formato que facilita la extracción de los valores individuales más adelante, como el formato binario del búfer de protocolo o json.

La clave de fila aún está diseñada para garantizar que puedas recuperar los datos que necesitas, pero cada fila suele tener solo una columna que contiene todos los datos de la fila en un solo protobuf.

Almacenar datos como un mensaje protobuf en una columna en lugar de distribuir los datos a varias columnas tiene ventajas y desventajas. Entre las ventajas, se incluyen las siguientes:

  • Dado que los datos ocupan menos espacio, le cuesta menos almacenarlos.
  • Para mantener una cierta flexibilidad, no debes comprometerte con las familias de columnas y los calificadores de columnas.
  • Tu aplicación de lectura no necesita "saber" cuál es el esquema de tu tabla.

A continuación, se detallan algunas desventajas:

  • Debes deserializar los mensajes de protobuf después de leerlos desde Cloud Bigtable.
  • Se pierde la opción de consultar los datos en mensajes protobuf con filtros.
  • No puedes usar BigQuery para ejecutar consultas federadas en campos dentro de los mensajes de protobuf después de leerlos en Cloud Bigtable.

¿Qué sigue?