Blog de Amazon Web Services (AWS)
Uso de claves de ordenamiento para organizar los datos en Amazon DynamoDB
Por AM Grobelny , Senior Technical Evangelist en AWS
Es fácil empezar a llenar una tabla de Amazon DynamoDB con datos. Sin embargo, sin tener en cuenta la organización de los datos, esto puede limitar las opciones de consulta de datos más adelante.
La organización de datos y la planificación de la consulta de datos son pasos críticos al diseñar una tabla. Sin una organización de datos adecuada, las únicas opciones para consultar datos son la o . Estos métodos de consulta son limitados o costosos en términos de y desempeño de una tabla.
En esta publicación, exploro ejemplos reales de optimización de tablas para la consulta de datos con claves de ordenamiento. Las claves de ordenamiento (sort key) no solo se utilizan para agrupar y organizar datos, sino también para proporcionar medios adicionales para consultar elementos en una tabla.
Una breve introducción a claves de partición
Para comprender mejor cómo organizar los datos, es importante comprender cómo se almacenan los datos en DynamoDB. Cada elemento de una tabla de DynamoDB requiere que cree una para la tabla, tal como se describe en la documentación de DynamoDB. Una clave primaria puede ser una clave de partición o una combinación de clave de partición y clave de ordenación. La clave primaria debe ser única en toda la tabla.
Cuando se utiliza solo una clave de partición como clave primaria, una elección subóptima para una clave de partición puede afectar al desempeño general de la tabla. Por ejemplo, la consulta frecuente de la misma clave primaria puede provocar excepciones que superan la capacidad de lectura (RCU) configurada para la tabla.
Para obtener más información sobre las claves de partición y sus prácticas recomendadas, consulte la publicación Eligiendo la clave de partición correcta de DynamoDB en el blog de la base de datos de AWS.
Uso de claves de ordenamiento para ampliar las opciones de consulta de datos
En algunos casos, se puede proporcionar solo una clave de partición como clave primaria al crear una tabla. En estos casos, se limita a la consulta de datos mediante la clave de partición como único criterio de consulta o retornar todos los elementos de una tabla con la operación de escaneo. Crear una tabla de esta manera es sencillo y, en algunos casos, lo único que necesitas es simple.
Sin embargo, a medida que el conjunto de datos crece, los escaneos de tablas pueden convertirse en una carga costosa en términos de precio y desempeño. Los escaneos de tablas pueden agotar rápidamente su capacidad de lectura y, por lo tanto, aumentar su factura. Para obtener más información sobre las unidades de capacidad de lectura y escritura y cómo afectan estas unidades a la factura de DynamoDB, consulte Precios de Amazon DynamoDB y Capacidad de desempeño para lecturas y escrituras en la documentación de DynamoDB. Además, no siempre puedes consultar elementos únicamente con la clave de partición. Considera los ejemplos de consulta de pedidos de clientes antes de una fecha específica y consulta de todos los productos que coinciden con una categoría. Al agregar una clave de ordenamiento (sort key) a una tabla se abren más opciones de consulta de datos más allá de los escaneos y las claves de partición.
Tenga en cuenta que las claves de ordenamiento no solo sirven para determinar el orden de los elementos devueltos por una consulta. Como muestra esta publicación, las claves de ordenamiento no están vinculadas directamente a los elementos de ordenamiento para su consulta, sino que amplían las opciones de consulta de datos.
Al combinar una clave de partición y una clave de ordenamiento se crea una , y esa clave compuesta pasa a ser la clave primaria de los elementos individuales de una tabla. Con una clave compuesta. se obtiene la posibilidad de utilizar . En una consulta, puede utilizar KeyConditionExpression
para escribir sentencias condicionales mediante operadores de comparación que se en función de una clave y limitan los elementos devueltos. En otras palabras, puede utilizar operadores especiales para incluir, excluir y hacer coincidir elementos según sus valores clave de ordenamiento.
Examinemos un ejemplo rápido de consultas con una clave de ordenamiento y consultas por tiempo. Supongamos que la clave de ordenamiento de una tabla concreta es un marcador de tiempo Unix (Epoch time). En este caso, puede emitir una consulta con una condición clave que devuelva todos los elementos antes de un momento específico utilizando el operador de comparación menor que ( <). Más adelante cubriré este ejemplo de consulta con rangos de tiempo.
Trabajando con rangos
Se utilizan rangos con claves de ordenamiento para crear consultas. Los siguientes operadores están disponibles con la consulta KeyConditionExpressions
:
- =
- <
- >
- <=
- >=
- between
- begins_with
El operador between
acepta dos valores para determinar un rango y begins_with
comprueba si una cadena empieza por una sub-cadena. Puede utilizar la mayoría de estos operadores en valores numéricos, pero el operador begins_with
permite algunas formas interesantes de consultar datos.
Por ejemplo, considere cómo agrupar ubicaciones. En los Estados Unidos, las ubicaciones suelen estar agrupadas por ciudad, estado y país. Supongamos que creamos una clave de ordenamiento que almacena la ubicación de un artículo en una cadena con la plantilla de ciudad-estado-país
.
El orden de la ciudad-estado-país
comienza con la parte más específica de los datos de ubicación. Como resultado, sus consultas con el operador begins_with
se limitan a la ciudad. Si cambio el orden de la cadena de ubicación a ciudad-estado-país
, el operador begins_with
proporciona tres niveles de consulta:
begins_with(USA)
– Devuelve todos los artículos ubicados en Estados Unidos
begins_with(USA-TX)
– Devuelve solo artículos ubicados en Texas.begins_with(USA-TX-Houston)
– Devuelve solo los artículos ubicados en Houston.
Al agrupar ubicaciones de esta forma, solo estás limitado por tu ingenio.
Cómo utilizar las claves de ordenamiento para la organización y consulta de datos
Al aplicar el conocimiento de las claves de ordenamiento a ejemplos de la vida real se destacan técnicas y patrones repetibles que puede utilizar para la organización y consulta de datos en las tablas que cree en el futuro.
Consideremos primero las bitácoras de eventos (event logs), como monitoreo de eventos de sistema, los eventos capturados por subscripciones (publisher/subscriber), y similares. Algunos ejemplos de fuentes de datos pueden ser secuencias de clics, bitácoras del sistema (system event), o API de sistemas de productividad empresarial(ERP) y plataformas de software como servicio (SaaS) tales como Salesforce.
Ejemplo 1: Trabajo con bitácoras de eventos (event logs)
Empiezo con un ejemplo sencillo e implemento el concepto de consulta con marcadores de tiempo que mencioné anteriormente al discutir los marcadores de tiempo (Epoch) Supongamos que se está recopilando datos de telemetría de varios dispositivos. Cada dispositivo tiene un ID de dispositivo, un ID de evento para cada evento único y un marcador de tiempo estableciendo el momento exacto de la captura. Los registros suelen tener datos de tiempo asociados a los eventos capturados en el registro. Normalmente, se consultan registros consultando un rango de tiempo específico.
Vaya a la consola de DynamoDB y cree una nueva tabla. Para organizar los bitácora de eventos, proporcione una clave de partición exclusiva del servicio creando un log de datos, como se muestra en la siguiente captura de pantalla. Por ejemplo, la clave de partición podría ser un hostname
o un valor para DeviceID
. Para la clave de ordenamiento, proporcione el valor del timestamp
del evento individual.
A continuación, puede emitir consultas utilizando el operador between
dos marcas de tiempo, > o <. Como se muestra en la siguiente captura de pantalla, se almacenan tres registros para un dispositivo con el deviceID
de 123
. Las fechas almacenadas como marca de hora Unix equivalen al 29 de agosto de 2018, a las 12:00 p.m. UTC; el 4 de septiembre de 2018, a las 1:00 h UTC; y el 9 de julio de 2011, a las 13:00 h UTC. Para convertir las marcas de tiempo a formatos legibles por humanos, consulte el sitio web Epoch Unix Time Stamp Converter.
Emitida una consulta para cualquier registro con marcas de tiempo antes del 4 de septiembre de 2018, a las 12:00 a.m. UTC mediante el operador < y la marca de hora de Unix para esa hora: 1536019200
.
Ejemplo 2: Trabajar con mensajes de chat
Este ejemplo se basa en el concepto de utilizar una cadena de plantilla para la clave de ordenamiento. Recuerde el ejemplo de datos de ubicación que he comentado anteriormente. Para este nuevo caso, considere que los datos provienen de una aplicación de chat. Como referencia, supongamos que los usuarios tienen un nombre de usuario y las salas de chat tienen identificadores únicos y que desea almacenar cada mensaje de chat. Quiero poder consultar mensajes por usuario y también por usuario y plazo.
chatroomID
puede servir como clave de partición. Si tiene una sala de chat ocupada, puede agregar un sufijo numérico creciente a chatroomID
, como seattle-1
o seattle-2
para distribuir el acceso a los datos entre las particiones. Esta práctica puede ayudarlo a evitar problemas relacionados con la creación de una partición activa (hot partition). Para obtener más información sobre las particiones activas y la selección de la mejor clave de partición para una tabla, consulte Elegir la clave de partición correcta de DynamoDB en el blog de la base de datos de AWS.
La clave de ordenamiento (sort key) compuesta debe seguir este formato: user_name#datetime
. Para el valor datetime
, el uso de una representación de cadena como yyyy-MM-dd:HH:mm:ss
proporciona la mayor cantidad de opciones de consulta.
En este ejemplo, los mensajes se almacenan para dos usuarios en varias ocasiones, como se muestra en la siguiente captura de pantalla.
La construcción de la clave de ordenamiento compuesta ofrece algunas opciones para realizar consultas con el operador begins_with
. Puede consultar mensajes filtrados por sala y usuario.
La parte de fecha de la cadena de plantilla chatMessageIdentifier
se organiza de la menos específica a la más específica. Puede consultar mensajes en una sala de chat por usuario y devolver todos los mensajes de un año (amsg#2018)
, o de un año y un mes específico (amsg#2018-08)
, por ejemplo.
Las consultas vienen con ventajas y limitaciones. Por ejemplo, no puedes consultar datos en función del tiempo aquí porque elegimos iniciar la cadena de plantilla con user_name
. Si el tiempo es un factor de consulta más importante para ti, puedes ordenar tu cadena de plantilla de forma diferente o añadir un índice secundario, con una clave de ordenamiento adicional que invierte la cadena de plantilla original: datetime#user_name
Ejemplo 3: Documentos de seguimiento
Por último, consideremos un caso de uso más avanzado en el que la clave de ordenamiento es un valor arbitrario y puede cambiar para ayudar a consultar diferentes conjuntos de datos sobre el mismo objeto. Utilizo el ejemplo real de un sistema de seguimiento de documentos. Los sistemas de seguimiento de documentos a menudo conservan datos sobre quién tiene permisos para un documento, en qué versión se encuentra el documento, dónde se almacena el documento y metadatos sobre el documento. Configuré la clave de partición para que sea un ID único vinculado al documento y utilicé la clave de ordenamiento para representar cada una de estas variables en el sistema de seguimiento de documentos.
Con esta clave de ordenamiento genérica pero sensible al contexto, puedo permitir que se almacenen y consulten metadatos arbitrarios añadiendo un valor clave de ordenamiento metadata
. O puedo usar el campo para almacenar identificadores de acceso para estipular quién puede acceder a este documento con el valor clave de ordenamiento permissions
. En lugar de predefinir el esquema de base de datos, puedo permitir que mi aplicación proporcione el contexto de qué tipo de datos estoy almacenando sobre los documentos. Con esta flexibilidad, mi aplicación puede proporcionar la definición de los datos en lugar de la base de datos.
Como puedes ver en la captura de pantalla anterior, la estructura de los datos difiere para cada elemento y almacena la información relevante para cada valor de clave de ordenamiento (sort key) arbitraria. Para consultar uno de estos elementos, se emite una consulta utilizando el operador = con el tipo de información de documento que necesito. Por ejemplo, para recuperar los metadatos del documento, utilizo el operador = y metadata
de valor para mi consulta.
Basándonos en este ejemplo de seguimiento de documentos, cubramos un caso de uso avanzado de la clave de ordenamiento. Puedo usar la misma clave de ordenamiento de documentInfo
para implementar el control de versiones de documentos. Una vez más, usando el operador begins_with
con una plantilla de cadena tipo string, creo elementos en la tabla para cada versión de un documento. El valor de la clave de ordenamiento se adhiere a la siguiente plantilla: v_#
donde #
es el ID de versión o el número de versión del documento. El valor de la clave de ordenamiento v_0
está reservado para almacenar la versión más reciente del documento y siempre es una fila duplicada de cualquier versión del documento que se añadió por última vez. En este ejemplo, v_0
almacena los mismos datos que v_2
, porque v_2
es el último documento.
Con este patrón, puede consultar para recuperar un historial completo de documentos con begins_with(v_)
, como se muestra en la siguiente captura de pantalla.
Resumen
Las claves de ordenamiento (sort key) pueden añadir más potencia a las capacidades de consulta de DynamoDB. Sin embargo, debes usar un poco de análisis y planificación. Recuerda emplear plantillas de cadenas tipo string que aprovechen el operador begins_with
y ordenar la cadena por datos menos específicos a la más específica. La clave de ordenamiento también pueden almacenar valores de cadena únicos y arbitrarios, como metadata
y permissions
para ayudar en posteriores consultas.
No dudes en utilizar los datos de DynamoDB en conjunto con otros servicios cuando tengas necesidades más exhaustivas de consultas, búsquedas y análisis de datos. Por ejemplo, puedes utilizar Amazon DynamoDB Streams para cargar datos de streaming en Amazon Elasticsearch Service. Algunas de las ventajas de DynamoDB radican en su función de escalado automático y su sencilla interfaz para almacenar datos. Otros incluyen sus tiempos de respuesta rápidos para aplicaciones exigentes con características como Amazon DynamoDB Accelerator (DAX) y su arquitecturas serverless. Consultar y recuperar datos no tiene por qué ser un problema si analiza y planifica los patrones de acceso de antemano, de acuerdo a sus necesidades.
Este artículo fue traducido del Blog de AWS en Inglés.
Sobre el autor
AM Grobelny es un evangelista técnico senior y se centra en permitir que todo tipo de desarrolladores de software tengan éxito en AWS.
Sobre los revisores
Carlos Robles es Arquitecto de Soluciones especializado en base de datos en AWS.
Camilo Leon es Arquitecto de Soluciones Senior especializado en base de datos en AWS.