2009-01-31 7 views
20

Supongamos que tengo algunos objetos, y quiero que el usuario sea capaz de cambiar el orden de los mismos en cualquier forma que deseen, por ejemplo, arrastrando a su alrededor. Así que tendríaCómo ahorrar una, mutable "orden" en particular en una base de datos

  • queso
  • magdalenas
  • leche

y luego el usuario arrastra 'leche' a la parte superior, por lo que el nuevo orden

  • leche
  • queso
  • magdalenas

¿Existe una mejor práctica sobre cómo almacenar el orden de estos objetos en una base de datos? El enfoque ingenuo probablemente sería simplemente almacenar un valor numérico llamado "orden" para cada objeto, pero esto me parece demasiado molesto, porque tendría que mezclar los valores de la orden la mayor parte del tiempo.

+1

Duplicado de http://stackoverflow.com/questions/495390/orm-or-something-to-handle-sql-tables-with-an-order-column- de manera eficiente – cletus

Respuesta

11

El enfoque de "ingenua" que sugieres es también la mejor práctica!

2

Si desea que se vuelvan a mostrar en el mismo orden Y desea que se puedan reordenar en cualquier momento, no creo que pueda evitar almacenar algún valor que indique prioridad de visualización en la base de datos. He utilizado el mismo enfoque que describe para pedir elementos en una FAQ, investigadores asociados con una subvención, el orden de los elementos en un menú, ...

12

Teniendo en cuenta la respuesta de Tony Andrews, podría almacenar una alternativa índice "siguiente" con cada entrada. Luego, cuando los atraes a todos, recorre la matriz siguiendo la cadena. Eso hace que mover un objeto sea más fácil, ya que solo tiene que tocar un máximo de dos filas.

La desventaja de este enfoque es que si alguna vez necesita un subconjunto (por ejemplo, los primeros 3 artículos) que todavía tienen que tirar de todos los artículos, o utilice un bucle de SQL. Por lo tanto, se trata de afectar todas las filas durante la actualización o acceder a todos los elementos durante la lectura. Como siempre, mida la velocidad y vea cuál es mejor para su situación.

2

Sí, en una base de datos relacional no hay orden, que es uno de los conceptos fundamentales. Así que simplemente no hay forma sin un valor numérico o algo así.

5

Mirando a Tony Andrew y respuestas de Mark en particular, parece que realmente tienen sólo dos alternativas:

  • guardar un valor de 'siguiente', por lo que los objetos se comportan como una lista enlazada (véase la respuesta de Mark)
    Con esto, cambiar el orden es barato, pero tendría que recuperar los artículos y luego ordenarlos por su valor 'siguiente', que es caro
  • Guardar un valor de 'orden' (ver la respuesta de Tony Andrew)
    Esto hace que recuperar sea barato pero guardando una nueva orde potencialmente costoso, porque en el peor de los casos, tendría que cambiar todos los valores de la orden. cletus señala que se podría usar un número grande en forma de 2^n para el multiplicador de órdenes.

Meta: Todas estas respuestas son buenas y correctas, lo que uno debe elegir como correcta?

+0

Como ha preguntado sobre el almacenamiento en un DB, votaría por el enfoque "ingenuo" ... insertando originalmente los objetos con un desplazamiento de, digamos 100, podría minimizar la colisión de reordenación (cuando tendría para cambiar más de un objeto para volver a insertarlo en una nueva posición) – lexu

+3

Ninguno es absolutamente el 100% "mejor". Si tiene mucho más lecturas que escrituras, la velocidad de recuperación es probablemente la principal preocupación. Si tiene muchas escrituras o tiene que pedir una gran cantidad de artículos, la velocidad de escritura es importante. Es un juicio caso por caso. – Tadmas

3

En mis aplicaciones las operaciones de lectura van a suceder con mucha más frecuencia que las escrituras. Vaya con el valor numérico para indicar el orden de clasificación y ocuparse del costo de reordenar los artículos. Esto está más que compensado por el hecho de que puede recuperar los elementos en el orden correcto para fines de visualización (que en una aplicación típica ocurre con más frecuencia que recurrir).

Además, como ya se mencionó, si recupera un subconjunto de los datos (filtra en el tipo o algo así) los elementos restantes siguen estando en el orden correcto.

Recuerda el mantra K.I.S.S.

14

La mejor manera que he encontrado para manejar esto es tener un campo de orden de punto flotante. Cuando mueve algo entre otros dos elementos, establezca ese campo a medio camino entre sus vecinos.

Esto es barato tanto en lecturas como en escrituras. El único inconveniente es que las carrozas siguen haciéndose más largas :)

+1

+1 para tipo de datos de coma flotante. Si establece los valores de orden iniciales para ser compensados ​​por 100 y flotantes usados, podría evitar lugares decimales gigantescos y aún tener el beneficio de no tener que ajustar un tipo de datos de búsqueda de una colisión. – aviemet

Cuestiones relacionadas