Estoy buscando almacenar una lista ordenada dentro de una base de datos. Quiero realizar las siguientes operaciones de manera eficiente.
- Insertar (x): inserte el registro x en la tabla
- Eliminar (x): eliminar el registro x de la tabla
- Before (x, n): devuelve los registros 'n' que preceden al registro x en la lista ordenada.
- After (x, n): devuelve los registros 'n' que suceden al registro x en la lista ordenada.
- Primero (n): devuelve los primeros registros 'n' de la lista ordenada.
- Último (n): devuelve los últimos registros 'n' de la lista ordenada.
- Compare (x, y): dados dos registros x e y de la tabla, encuentre si x> y.
El método simple que se me ocurre es almacenar algún tipo de atributo de 'rango' en la tabla y consultar ordenando ese atributo. Pero en este método, insertar / modificar un registro con un rango se convierte en una operación costosa. hay algun metodo mejor?
Específicamente, estoy buscando implementar la tabla usando SimpleDB de Amazon. Pero una respuesta general para una base de datos relacional también debería ser útil.
Actualización en el perfil de carga:
Como estoy planeando esto para una aplicación web, depende de la cantidad de usuarios que usen la aplicación.
Si hay 100k usuarios activos (súper optimismo: P), entonces mi estimación aproximada por día sería
500k selecciona, 100k inserta y elimina, 500k actualizaciones
Esperaría que la mesa crezca hasta 500k en total.
Estoy buscando optimizar las actualizaciones, la inserción y las operaciones de comparación. El rango de los elementos cambiará constantemente y necesito mantener la tabla actualizada.
fuente
Respuestas:
Si el rango no es completamente arbitrario, sino que se puede derivar de alguna otra propiedad (por ejemplo, nombre, puntaje del jugador, etc.), eche un vistazo a la respuesta de Joel .
Si es una propiedad arbitraria de sus datos, debe almacenarse como una columna en su tabla de registros. Suponiendo que el SimpleDB de Amazon es similar al RDBMS típico, puede indexar esta columna y satisfacer rápidamente todas sus consultas anteriores con la estrategia de indexación adecuada. Esto es normal para un RDBMS.
Dado que espera una alta actividad de inserción y actualización, pero también una actividad de lectura relativamente alta, le recomiendo hacer lo siguiente:
INCLUDE
clasifique el rango, o simplemente registre si se ha agrupado en el rango) satisfaría la consulta 7.FILLFACTOR
en SQL Server). Esto es especialmente importante si se agrupa en rango.Si espera lecturas de 100K + en una tabla de tamaño de 100K +, no recomiendo usar el enfoque de lista vinculada. No escalará bien a esos tamaños.
fuente
FILLFACTOR
, verás que básicamente está destinado a crear ese espacio extra para los registros en un índice, tal como las brechas de rango que describí crean espacio para cambios de rango e inserciones.Generalmente uso el método de "rango" que usted describe. En lugar de perder el tiempo con la actualización de filas cuando los elementos debían reordenarse, a menudo he podido eliminar todos los registros de la lista y volver a insertar nuevos elementos en el orden correcto. Este método está claramente optimizado para su recuperación.
Un enfoque alternativo sería modelar los registros como una lista vinculada mediante el uso de una columna de clave externa reflexiva "predecesora" en la tabla:
Puede recuperar fácilmente una lista y agregar y quitar elementos con poca sobrecarga, pero sacar los registros en el orden correcto será complicado. Quizás haya una manera inteligente de hacerlo en una sola consulta, probablemente con muchas uniones de tabla con alias.
Utilizo este último enfoque a menudo cuando estoy modelando una relación de estilo de árbol (categorías, carpetas, conjuntos y subconjuntos). En general, he tenido una función recursiva de algún tipo para reconstruir el árbol completo en mi aplicación.
fuente
Creo que lo que hay que hacer es almacenar la propiedad o propiedades que se utilizan para calcular el rango y luego construir un índice sobre ellas. En lugar de intentar forzar a la base de datos a almacenar físicamente los datos en orden de clasificación o usar una lista vinculada administrada manualmente, ¿por qué no dejar que el motor de la base de datos haga lo que fue diseñado para hacer?
fuente
Estas son las limitaciones de un no RDBMS como simpleDB. Las características que necesita no se pueden implementar en el lado de DB en simpleDB, deben implementarse desde el lado de la programación / aplicación.
Para un RDBMS como
SQL server
, las características que necesita son rudimentarias para el índice agrupado.Before (x, n): devuelve los registros 'n' que preceden al registro x en la lista ordenada. > Seleccione los mejores resultados n donde x menos que el valor y ordene por cláusula.
After (x, n): devuelve los registros 'n' que suceden al registro x en la lista ordenada. > Seleccione n resultados superiores donde x sea mayor que el valor y ordene por cláusula.
Primero (n): devuelve los primeros registros 'n' de la lista ordenada. > Seleccione los mejores n resultados.
Último (n): devuelve los últimos registros 'n' de la lista ordenada. > Seleccione los mejores resultados después de ordenar por desc.
fuente
Esto es lo que solía volver a clasificar mi tabla de Postgres después de cada inserción:
Para mi caso de uso, el rendimiento no es una preocupación, pero la confianza de que nunca se romperá o actuará de manera extraña es importante.
fuente