Sobrecarga de claves en DynamoDB
Viniendo de SQL, una columna significa una cosa para siempre: orders.created_at es siempre una
fecha, users.email es siempre un correo electrónico. La sobrecarga de claves descarta eso. tu
asigne nombres genéricos a la partición y (pk, sk) y deje que cada elemento escriba
darles un significado diferente. Una tabla, muchas entidades, una forma.
¿Qué es la sobrecarga de claves en DynamoDB?
La sobrecarga de claves consiste en almacenar muchos tipos de entidades en una tabla con nombres de claves genéricos como pk/sk, codificando el tipo en el valor (USER#u_3001, INVOICE#2026-0014). El nombre del atributo permanece neutral para que los usuarios, las facturas y los eventos compartan una partición; el valor lleva el tipo, y un prefijo de clave de clasificación permite que un Query divida cada entidad a través de begins_with.
- Nombres de claves genéricas, valores escritos. Nombra tus claves
pk/sky pon la entidad escriba el valor:pk = "TENANT#acme",sk = "USER#u_3001". El nombre es tonto; el valor lleva el tipo. - Es lo que hace que el diseño de una sola tabla funcione. Sin sobrecargar, una tabla compartida
Es sólo un cajón de basura. Con él, cada entidad se encuentra en una partición que puedes
Query. begins_withes el pago. Un prefijo de tipo en la clave de clasificación permiteQueryextraiga una entidad completa, o una porción de ella, sinScany sin filtro.- El costo: legibilidad. Un volcado sin formato
pk/skno te dice nada. Necesitas un visor que decodifica los prefijos, o estarás entrecerrando los ojos ante las cadenas.
Por qué los nombres genéricos ganan a los reales
DynamoDB le brinda como máximo dos atributos clave por tabla, y un Query solo puede apuntar a un
clave de partición única. Entonces, si nombras tu clave userId, solo los elementos del usuario pueden vivir en
esa tabla limpiamente: todo lo demás tiene que fingir un userId o moverse a su propia tabla.
La sobrecarga evita eso. Un nombre neutral como pk no se compromete con ninguna entidad,
para que un usuario, una factura y un evento de auditoría puedan compartir el mismo atributo clave y
la misma tabla. El valor, no el nombre del atributo, dice cuál es el artículo.
Este es el movimiento que convierte el diseño de tabla única de teoría en algo que realmente puedas query. La tabla compartida es el contenedor; la sobrecarga es lo que permite que en su interior coexistan distintas entidades.
Un ejemplo de múltiples inquilinos
Supongamos que ejecuta un producto de facturación SaaS. Cada inquilino tiene miembros, facturas y una auditoría. sendero. En lugar de tres tablas, colóquelas todas en una y sobrecargue las claves:
| pk | sk | attributes |
|---|---|---|
| TENANT#acme | META | name="Acme Inc", plan="team" |
| TENANT#acme | USER#u_3001 | email, role="admin" |
| TENANT#acme | USER#u_3002 | email, role="member" |
| TENANT#acme | INVOICE#2026-0014 | amount_cents, status="paid" |
| TENANT#acme | INVOICE#2026-0015 | amount_cents, status="open" |
| TENANT#acme | EVENT#2026-06-23T09:12Z | actor="u_3001", action="invite" |
Cada fila comparte pk = "TENANT#acme", por lo que forman una — todas
Ubicados en el mismo lugar, todos accesibles en una sola partición de lectura.
El prefijo de clave de clasificación hace el verdadero trabajo. Agrupa entidades y las ordena.
Query la colección sobrecargada
Debido a que el tipo reside en el prefijo de clave de clasificación, begins_with divide la partición en
entidad sin scanfinar nada:
Query pk = "TENANT#acme" -- the entire tenant, every type
Query pk = "TENANT#acme" AND begins_with(sk, "USER#") -- just members
Query pk = "TENANT#acme" AND begins_with(sk, "INVOICE#") -- just invoices
Solo pagas por los elementos que cumplen la condición, no por toda la partición: lo
contrario de un Scan filtrado, donde pagas por leer filas
que luego tiras. AWS llama a esto una condición de clave; se ejecuta sobre las claves
antes de que ningún dato salga de la partición.
Si construyes esa condición begins_with a mano, acierta con las etiquetas de tipo: un
USERS# de más en lugar de USER# no devuelve nada, en silencio. El
generador de expresiones genera la
KeyConditionExpression y el mapa ExpressionAttributeValues para que los prefijos
coincidan con lo que realmente escribiste.
Sobrecarga también el índice
El mismo truco vale para un . Dale nombres de clave genéricos — gsi1pk,
gsi1sk — y deja que cada entidad escriba lo que necesite. Un solo índice responde entonces
a patrones que la tabla base no puede.
| pk | sk | gsi1pk | gsi1sk |
|---|---|---|---|
| TENANT#acme | INVOICE#2026-0015 | STATUS#open | 2026-06-30 |
| TENANT#acme | INVOICE#2026-0014 | STATUS#paid | 2026-06-12 |
| TENANT#beta | INVOICE#2026-0099 | STATUS#open | 2026-06-25 |
Ahora Query gsi1 WHERE gsi1pk = "STATUS#open" lista todas las facturas abiertas de
todos los inquilinos, ordenadas por fecha de vencimiento: una vista entre particiones que
las claves de la tabla base, acotadas al inquilino, nunca podrían servir. Otra entidad puede
reutilizar gsi1 con su propio significado (por ejemplo gsi1pk = "ROLE#admin"), así que
un índice cubre varias lecturas. Recuerda solo que un GSI es
eventualmente consistente: sus escrituras van por detrás de la
tabla base.
Hazlo en DynoTable
Las claves sobrecargadas en bruto son hostiles de leer: INVOICE#2026-0015 y
EVENT#2026-06-23T09:12Z se desdibujan en una lista plana. Un visor que agrupa por
partición y superficies los prefijos convierten el cajón de basura nuevamente en entidades.

Escollos
- Elija los delimitadores una vez y nunca los cambie.
#es la convención. Mezclando#y:entre entidades rompebegins_withde maneras que no te interesan. - No sobrecargues valores que necesitan cálculos de rango. Una clave de clasificación de
INVOICE#2026-0015ordena léxicamente, no numéricamente: identificadores y usa ISO-8601 fechas para que el orden de las cadenas coincida con el orden al que se refiere. - Reserve el espacio de nombres del prefijo. Dos tipos de entidad que comienzan con
USER(digamosUSER#yUSERGROUP#) chocarán bajobegins_with(sk, "USER"). hacer prefijos inequívocos desde el primer carácter. - Planifique la lectura antes de las claves. La sobrecarga sirve a los patrones de acceso que ha enumerado. Si aún no conoces tus lecturas, consulta diseño de tabla única primero: las claves están en sentido descendente de las consultas.
Asigne una partición, luego descargue DynoTable para buscar la suya propia.
claves sobrecargadas y observe cómo un Query retira a todo un inquilino a la vez.
Query costo en una partición sobrecargada
Listar a todos los miembros menores de TENANT#acme con
begins_with(sk, "USER#") lee solo filas de usuarios, no facturas ni eventos,
porque la condición clave se filtra antes de que los datos abandonen la partición. sobre un inquilino
con 200 usuarios (2 KB cada uno) y 5000 eventos de auditoría (1 KB cada uno), eso query
toca ~400 KB (~100 RCU eventualmente consistentes). Un Scan en toda la tabla
para encontrar usuarios medirían cada artículo en cada inquilino.
Pegue elementos sobrecargados representativos en el calculadora de tamaño de artículo, luego lista de estimaciones consultas en la calculadora de precios.
Diseñar con la herramienta de tabla única
Ingrese entidades (Inquilino, Usuario, Factura, Evento) y patrones de acceso ("lista de usuarios
para inquilino", "facturas abiertas entre inquilinos") en el
herramienta de diseño de una sola tabla. propone
pk/sk plantillas y GSI claves que coincidan con los prefijos de sobrecarga que utilizará
en producción, antes de confirmar CloudFormation.
Emitir consultas desde patrones
Una vez que se fijan los prefijos, cree condiciones clave en el
generador de expresiones y exportar un paginado
programa del query constructor. Errores tipográficos de prefijo
(USER# vs USERS#) devuelven conjuntos vacíos sin errores: expresiones generadas
reducir ese modo de falla silencioso.
Registro de prefijo de tipo de entidad
Mantenga una breve tabla interna a la que los desarrolladores puedan hacer referencia:
| Entidad | Ordenar prefijo | Ejemplo SK | Query rebanada |
|---|---|---|---|
| Meta inquilino | META | META | Obtener un solo artículo |
| Usuario | USER# | USER#u_3001 | begins_with(sk, "USER#") |
| Factura | INVOICE# | INVOICE#2026-0015 | begins_with(sk, "INVOICE#") |
| Evento | EVENT# | EVENT#2026-06-23T09:12Z | cola ordenada en el tiempo con descfinal de lectura |
Los nuevos tipos de entidades deben elegir prefijos que no colisionen en begins_with de
Los prefijos existentes: USER# y USERGROUP# coinciden con begins_with(sk, "USER") a menos que alargues o separes los delimitadores con cuidado.


