DP-900: cómo usar índices y consultas secundarias en Azure Table Storage
Te enseñaré cómo utilizar las claves de partición y fila (PartitionKey y RowKey) en Azure Table Storage para modelar datos eficientes y realizar consultas rápidas. Esta competencia es útil en el examen DP-900 porque evalúa tu comprensión de soluciones NoSQL sencillas en Azure y es práctica para escenarios reales de aplicaciones con registro de eventos o catálogos ligeros. Al final de este artículo tendrás ejemplos concretos, patrones comunes y trampas a evitar que te ayudarán a tomar decisiones de modelado informadas.
Qué necesitas saber
Azure Table Storage es un servicio NoSQL clave-valor orientado a columnas, optimizado para grandes volúmenes de entidades simples. Cada entidad tiene un PartitionKey y un RowKey que, en conjunto, forman la clave primaria única. La combinación determina cómo se distribuyen y leen los datos: las consultas que usan PartitionKey (o PartitionKey + RowKey) son mucho más rápidas y económicas que los escaneos totales.
Conceptualmente, piensa en la PartitionKey como el identificador de la partición física y en la RowKey como el orden o identificador único dentro de esa partición. Las consultas que filtran por PartitionKey suelen ser O(1) respecto al número de particiones consultadas — es decir, el servicio se dirige directamente a la partición — mientras que una query sin PartitionKey exige un scan por múltiples particiones y puede implicar lectura de muchos más datos, mayor latencia y costes más elevados.
Ejemplo conceptual: imagina un sistema de telemetría que guarda lecturas por dispositivo y día. Puedes usar PartitionKey = DeviceId y RowKey = Timestamp (o al revés, dependiendo de los patrones de consulta). Así, obtener lecturas de un dispositivo es una operación eficiente porque lees solo la partición de ese dispositivo, en lugar de escanear millones de registros. En escenarios con 1 millón a 100 millones de entidades, esta diferencia es crítica.
Cómo funciona en la práctica
Principales comportamientos a saber:
- PartitionKey agrupa entidades; todas las entidades en la misma partición están físicamente próximas y soportan transacciones por lotes dentro de la misma partición.
- RowKey ordena entidades dentro de la partición y, junto con la PartitionKey, identifica de forma única cada entidad.
- Consultar por PartitionKey es muy eficiente; sin PartitionKey, el servicio realiza un escaneo (scan) que es lento y puede consumir muchas más RU (request units) y ancho de banda.
Ejemplo de entidad (formato conceptual JSON):
{
"PartitionKey": "DeviceA",
"RowKey": "2026-10-21T09:00:00Z",
"Temperature": 21.5,
"Humidity": 60
}
En la práctica, y para cargas de producción, conviene medir: por ejemplo, leer 10 registros en una partición dedicada puede tardar decenas de milisegundos, mientras que un scan sobre millones de registros puede tardar segundos y costar mucho más. Al modelar, piensa siempre en latencia, coste y capacidad de escritura/lectura por segundo.
Paso a paso: modelar para consultas eficientes
Sigue estos pasos cuando planifiques tus esquemas en Table Storage.
- Identifica patrones de consulta: ¿qué preguntas hace la aplicación con más frecuencia? Ej.: obtener lecturas por dispositivo, por intervalo de tiempo, por ubicación. Haz una lista con las tres consultas principales y prioriza el modelado para esas operaciones.
- Elige PartitionKey para agrupar entidades que serán frecuentemente leídas en conjunto. Ej.: DeviceId o LocationId si lees por ubicación. Si esperas lectura por día, puedes usar LocationId|YYYYMMDD como PartitionKey para distribuir por días.
- Elige RowKey para ordenar / identificar singularmente dentro de la partición. Ej.: Timestamp invertido (para lecturas más recientes primero) usando una fórmula como MaxTicks - ticks, o un identificador compuesto DeviceId|SequenceNumber.
- Aprovecha operaciones por lotes cuando necesites escribir/actualizar múltiples entidades en la misma partición: las operaciones en lote solo están soportadas dentro de la misma PartitionKey y cada lote soporta hasta 100 operaciones, lo que reduce el overhead de red y mejora la consistencia transaccional.
- Evita particiones demasiado grandes: si un PartitionKey recibe un volumen de escritura/lecturas muy elevado (hot partition), considera repartir por sub‑claves (ej.: DeviceId + hour o añadir un salt de 0‑9) para distribuir la carga. Por ejemplo, en lugar de 50k writes/s en una partición, puedes tener 10 particiones con ~5k writes/s cada una.
Ejemplo: patrón para obtener las últimas lecturas de un dispositivo (RowKey con Timestamp invertido):
// Pseudocódigo conceptual de consulta
partition = "DeviceA"
// RowKeys fueron escritas como (MaxTimestamp - Timestamp) para ordenar descendente
query = TableQuery.where(PartitionKey == partition).take(10)
results = table.execute(query)
Errores comunes
Algunas trampas típicas al trabajar con Azure Table Storage:
- No planear los patrones de consulta: elegir PartitionKey/RowKey sin pensar en las queries conduce a scans caros y lentos. Reevalúa el esquema cuando los requisitos cambien.
- Particiones demasiado calientes: usar un único PartitionKey para todos los registros (por ejemplo, "All") causa cuellos de botella de escritura y reduce el rendimiento. Si empiezas a ver throttling o latencia elevada, es señal para shardear.
- Esperar capacidades de SQL: Table Storage no soporta joins, transacciones multi‑partición ni consultas complejas. Si necesitas eso, considera Cosmos DB, Azure SQL o un diseño de pipeline ETL para agregación.
Cómo practicar
Para interiorizar estos conceptos, haz los laboratorios de Azure y ejercita escenarios reales. Consulta el Practice Assessment OFICIAL de Microsoft (es gratuito) para verificar tus conocimientos generales del examen DP-900. Lee también la study guide oficial de Microsoft para DP-900 (gratuita) — ambos presentan los temas medidos sin proporcionar preguntas de examen reales.
Practica en el portal de Azure creando una Storage Account con Table Storage o usa el SDK (C#, Python, JavaScript) para insertar y consultar entidades. Prueba variaciones: escribe 1000 entidades en una sola partición y luego escribe las mismas 1000 distribuidas en 10 particiones; mide latencia y costes. Experimenta operaciones por lotes (hasta 100 registros) y observa ganancias de rendimiento en comparación con inserciones individuales.
En resumen
- PartitionKey y RowKey son cruciales para el rendimiento: se usan para agrupar e identificar entidades de forma eficiente.
- Define PartitionKey basándote en tus patrones de consulta; evita particiones "calientes" y escaneos globales.
- Las operaciones por lote se soportan solo dentro de la misma partición (hasta 100 operaciones) — aprovéchalas para eficiencia y consistencia.
- Azure Table Storage es un NoSQL simple: no esperes capacidades relacionales avanzadas; modela los datos para las queries que importan y valida con tests de carga reales.