amazon-web-services - services - dynamodb wikipedia
Consultando DynamoDB por fecha (7)
Dada su estructura de tabla actual, esto no es posible actualmente en DynamoDB. El gran desafío es comprender que la clave Hash de la tabla (partición) debe tratarse como crear tablas separadas. De alguna manera, esto es realmente poderoso (piense en las claves de partición como crear una nueva tabla para cada usuario o cliente, etc.).
Las consultas solo pueden hacerse en una sola partición. Ese es realmente el final de la historia. Esto significa que si desea consultar por fecha (querrá usar msec desde epoch), todos los elementos que desea recuperar en una sola consulta deben tener el mismo Hash (clave de partición).
Yo debería calificar esto. Puedes scan
absolutamente según el criterio que estés buscando, eso no es problema, pero eso significa que estarás mirando cada fila de tu tabla y luego verificando si esa fila tiene una fecha que coincida con tus parámetros. Esto es realmente costoso, especialmente si está en el negocio de almacenar eventos por fecha en primer lugar (es decir, tiene muchas filas).
Puede que tenga la tentación de poner todos los datos en una sola partición para resolver el problema, y absolutamente puede, sin embargo, su rendimiento será penosamente bajo, dado que cada partición solo recibe una fracción de la cantidad total establecida.
Lo mejor que puede hacer es determinar particiones más útiles para crear y guardar los datos:
¿Realmente necesita mirar todas las filas o solo las filas de un usuario específico?
¿Estaría bien primero reducir la lista por Mes y hacer múltiples consultas (una para cada mes)? ¿O por año?
Si está haciendo análisis de series de tiempo, hay un par de opciones, cambie la clave de partición a algo calculado en
PUT
para facilitar laquery
, o use otro producto de aws como kinesis que se presta para el registro de solo anexar.
Vengo de un fondo de base de datos relacional y trato de trabajar con DynamoDB de Amazon
Tengo una tabla con una clave hash "DataID" y un rango "CreatedAt" y un montón de elementos en ella.
Estoy tratando de obtener todos los elementos que se crearon después de una fecha específica y ordenados por fecha. Lo cual es bastante sencillo en una base de datos relacional.
En DynamoDB lo más parecido que pude encontrar es una consulta y el uso de la clave de rango mayor que el filtro. El único problema es que para realizar una consulta, necesito una clave hash que anula el objetivo.
Entonces, ¿qué estoy haciendo mal? ¿El esquema de mi tabla es incorrecto? ¿No debería la clave hash ser única? o hay otra manera de consultar?
El enfoque que seguí para resolver este problema es crear un Índice Secundario Global como el siguiente. No estoy seguro de si este es el mejor enfoque, pero con suerte si es útil para alguien.
Hash Key | Range Key
------------------------------------
Date value of CreatedAt | CreatedAt
Limitación impuesta al usuario de la API HTTP para especificar el número de días para recuperar datos, predeterminado en 24 horas.
De esta forma, siempre puedo especificar la HashKey como el día de la fecha actual y RangeKey puede usar los operadores> y <mientras recupera. De esta forma, los datos también se distribuyen en múltiples fragmentos.
Puede hacer que la tecla Hash sea similar a una ID de "categoría de producto", luego la clave de rango como una combinación de una marca de tiempo con una ID única adjunta al final. De esta forma, conoce la clave hash y aún puede consultar la fecha con un valor superior a.
Puede tener múltiples claves hash idénticas; pero solo si tienes una clave de rango que varía. Piense en ello como formatos de archivo; puede tener 2 archivos con el mismo nombre en la misma carpeta, siempre que su formato sea diferente. Si su formato es el mismo, su nombre debe ser diferente. El mismo concepto se aplica a las teclas hash / range de DynamoDB; solo piense en el hash como el nombre y el rango como el formato.
Además, no recuerdo si los tenían en el momento del OP (no creo que lo hayan hecho), pero ahora ofrecen índices locales secundarios.
Mi comprensión de estos es que ahora debería permitirle realizar las consultas deseadas sin tener que hacer un análisis completo. La desventaja es que estos índices deben especificarse en la creación de la tabla, y también (creo) no pueden estar en blanco cuando se crea un elemento. Además, requieren un rendimiento adicional (aunque normalmente no tanto como un escaneo) y almacenamiento, por lo que no es una solución perfecta, sino una alternativa viable, para algunos.
Todavía recomiendo la respuesta de Mike Brant como el método preferido para usar DynamoDB; y usar ese método yo mismo. En mi caso, solo tengo una tabla central con solo una clave hash como mi ID, luego tablas secundarias que tienen un hash y rango que se puede consultar, luego el elemento apunta el código al "elemento de interés" de la tabla central, directamente .
Se pueden encontrar datos adicionales sobre los índices secundarios en la documentación de DynamoDB de Amazon here para aquellos interesados.
De todos modos, espero que esto ayude a cualquier otra persona que sucede en este hilo.
Respuesta actualizada:
DynamoDB permite la especificación de índices secundarios para ayudar en este tipo de consultas. Los índices secundarios pueden ser globales, lo que significa que el índice abarca toda la tabla a través de claves hash, o el significado local de que el índice existiría dentro de cada partición de clave hash, por lo que también se debe especificar la clave hash al realizar la consulta.
Para el caso de uso en esta pregunta, le conviene usar un índice secundario global en el campo "CreatedAt".
Para obtener más información sobre los índices secundarios de DynamoDB, consulte la documentación del índice secundario.
Respuesta Original:
DynamoDB no permite búsquedas indexadas solo en la tecla de rango. La clave hash es necesaria para que el servicio sepa qué partición buscar para buscar los datos.
Por supuesto, puede realizar una operación de escaneo para filtrar por el valor de la fecha, sin embargo, esto requeriría un escaneo completo de la tabla, por lo que no es ideal.
Si necesita realizar una búsqueda indexada de registros por tiempo a través de varias claves primarias, DynamoDB podría no ser el servicio ideal para su uso, o podría necesitar utilizar una tabla separada (ya sea en DynamoDB o en una tienda relacional) para almacenar elementos metadatos contra los que puede realizar una búsqueda indexada.
Su clave Hash (primaria de clase) tiene que ser única (a menos que tenga un rango como el declarado por otros).
En su caso, para consultar su tabla debe tener un índice secundario.
| ID | DataID | Created | Data |
|------+--------+---------+------|
| hash | xxxxx | 1234567 | blah |
Su clave Hash es ID Su índice secundario se define como: ID creado por DataID (ese es el nombre que usará DynamoDB)
Entonces, puedes hacer una consulta como esta:
var params = {
TableName: "Table",
IndexName: "DataID-Created-index",
KeyConditionExpression: "DataID = :v_ID AND Created > :v_created",
ExpressionAttributeValues: {":v_ID": {S: "some_id"},
":v_created": {N: "timestamp"}
},
ProjectionExpression: "ID, DataID, Created, Data"
};
ddb.query(params, function(err, data) {
if (err)
console.log(err);
else {
data.Items.sort(function(a, b) {
return parseFloat(a.Created.N) - parseFloat(b.Created.N);
});
// More code here
}
});
Esencialmente su consulta se ve así:
SELECT * FROM TABLE WHERE DataID = "some_id" AND Created > timestamp;
El índice secundario aumentará las unidades de capacidad de lectura / escritura requeridas, por lo que debe tenerlo en cuenta. Todavía es mucho mejor que hacer un escaneo, lo cual será costoso en lecturas y en el tiempo (y está limitado a 100 elementos, creo).
Puede que esta no sea la mejor manera de hacerlo, pero para alguien acostumbrado a RD (también estoy acostumbrado a SQL) es la forma más rápida de ser productivo. Como no hay restricciones con respecto al esquema, puede activar algo que funciona y una vez que tenga el ancho de banda para trabajar de la manera más eficiente, puede cambiar las cosas.
Respuesta actualizada No hay una forma conveniente de hacerlo mediante las consultas de Dynamo DB con rendimiento predecible. Una opción (subóptima) es usar un GSI con un HashKey y CreatedAt artificiales. A continuación, consulte solo por HashKey y mencione ScanIndexForward para ordenar los resultados. Si puede encontrar una HashKey natural (digamos la categoría del artículo, etc.), este método es un ganador. Por otro lado, si mantiene la misma HashKey para todos los elementos, entonces afectará el rendimiento sobre todo cuando su conjunto de datos supere los 10 GB (una partición)
Respuesta original: Puede hacer esto ahora en DynamoDB usando GSI. Cree el campo "CreatedAt" como un GSI y emita consultas como (GT some_date). Almacene la fecha como un número (msecs desde época) para este tipo de consultas.
Los detalles están disponibles aquí: Índices Secundarios Globales - Amazon DynamoDB: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html#GSI.Using
Esta es una característica muy poderosa. Tenga en cuenta que la consulta está limitada a (EQ | LE | LT | GE | GT | BEGINS_WITH | BETWEEN) Condición: Amazon DynamoDB: http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html