your tool online modeler google data database-design

database design - tool - Mantenimiento del orden de clasificación de las filas de la tabla de la base de datos



google database design tool (12)

El problema que quiero evitar es tener los artículos numerados 1,2,3,4, .., 100

Sugeriría que no intentes y que tu clave de clasificación sea tu clave principal o que sea única. Si la clave no es única, puede tener varios elementos con el mismo valor. Probablemente desee simplemente hacer que su clave de clasificación sea una escala simple de 1-10.

Entonces, quizás las cosas en el nivel 10 serían extremadamente interesantes, 5 serían normales y 1 sería extremadamente aburrido. Cuando algo se vuelve aburrido o más interesante, simplemente ajuste el valor de la tecla de clasificación hacia abajo o hacia arriba.

Digamos que tengo en la tabla de la base de datos que contiene información sobre un artículo de noticias en cada fila. La tabla tiene una columna de "clasificación" entera para dictar el orden en que se presentarán los artículos en un sitio web. ¿Cómo puedo implementar y mantener este orden de clasificación?

El problema que quiero evitar es tener los artículos numerados 1,2,3,4, .., 100 y cuando el artículo número 50 se vuelve de repente interesante, obtiene su número de clasificación en 1 y luego todos los artículos entre ellos deben tener su género número aumentado en uno.

Claro, establecer números de clasificación iniciales en 100,200,300,400 etc. deja algo de espacio para moverse, pero en algún momento se romperá.

¿Hay una forma correcta de hacer esto, tal vez un enfoque completamente diferente?

Added-1 :

Todos los títulos de los artículos se muestran en una lista que vincula los contenidos, por lo que sí, todos los elementos ordenados se muestran a la vez.

Added-2 :

Un elemento no se mueve necesariamente a la parte superior de la lista; cualquier artículo puede colocarse en cualquier lugar de la lista ordenada.


Me gustaría ir con la respuesta que la mayoría de la gente está diciendo, es decir, que debe tener una columna separada en su tabla con el valor de clasificación / interés del registro. Si desea factorizar algún tipo de argumento de tiempo mientras se mantiene robusto, es posible que desee intentar incorporar una "vista" de datos para un período de tiempo determinado.

Es decir, todas las noches a la medianoche, usted crea una vista de tabla de su tabla principal, pero solo la crea utilizando artículos de los últimos 2 o 3 días, luego mantenga los recuentos de clasificación / interés estrictamente en esa tabla. Si alguien selecciona un artículo anterior que no está en esa tabla (por ejemplo, hace una semana), siempre puede insertarlo en la vista actual. De esta forma puede obtener un efecto de desactualización.

El objetivo principal sería mantener índices pequeños en la tabla donde los insertos y las actualizaciones de los valores de clasificación / interés deberían permanecer relativamente rápidos. Solo debe pagar las combinaciones complicadas una vez por adelantado durante la creación de la vista, luego puede mantenerla plana para optimizar las lecturas excesivas. ¿Cuál es el máximo que tendría en la vista, un par de cientos, dos mil? Es mejor tratar de clasificar cien mil cada vez que alguien hace una solicitud.


Olvídate de todo: el problema que quieres evitar no es gran cosa, sino un par de instrucciones UPDATE según tu RDBMS (supongo que Oracle está moviendo el artículo "arriba" de la lista):

UPDATE Articles SET sort_number = sort_number + 1 WHERE sort_number BETWEEN :new_sort_number and :current_sort_number - 1; UPDATE Articles SET sort_number = :new_sort_number WHERE article_id = :article_id;

La advertencia más importante es que la funcionalidad SET no funciona igual en todos los RDBMS.

Si realmente quiere considerar que es correcto , considere replantear la pregunta en términos de estructuras de datos: lo que podría estar preguntando es cómo implementar una lista vinculada en una base de datos.

Una alternativa para mantener su columna de número de clasificación sería mantener una columna de ID principal . Esto es posiblemente más correcto, ya que preserva la serialización de sus datos, pero el inconveniente es que consultar los datos no es bonito ni eficiente (piense en CONNECT BY en Oracle, por ejemplo).

Si la pregunta es, en cambio, lo mejor es que desee considerar tanto la columna de ID padre para la corrección y desnormalización de los datos derivando un valor de columna de número de orden, posiblemente a partir de los datos de ID padre o de la primera solución.


Para hacer esto, configuramos las filas para incrementar enteros, luego usamos un proceso almacenado para mover ítems. El proceso toma dos argumentos, el índice actual del elemento y el nuevo índice al que desea moverlo. Hace una actualización de elementos set index = index + sign (@newidx - @oldidx) donde index entre itemMax (@newidx, @oldidx) y itemMin (@newidx, @oldidx) para actualizar los elementos intermedios y luego una actualización que cambia el elemento real al nuevo índice. Este no es el código real, solo de memoria. En nuestra tabla, tenemos dos columnas, la identificación y el índice, de modo que, aunque en un momento haya terminado con dos elementos en el mismo índice, podemos diferenciarlos por ID. Esto podría evitarse haciendo una actualización del elemento a ser movido e índice de -1 tal vez, luego actualizando el resto y finalmente moviendo el nuevo ítem en -1 al nuevo índice.


Si entiendo tu problema correctamente; Usaría una columna que contenga algún tipo de índice de clasificación. Este número no tiene que ser único. Tendrá que encontrar algún tipo de algoritmo para calcular el rango.

Luego solo ordena en la columna de clasificación, con una columna secundaria para manejar los vínculos de clasificación (tal vez la fecha de creación o algo así).


Todos los títulos de los artículos se muestran en una lista que vincula los contenidos, por lo que sí, todos los elementos ordenados se muestran a la vez.


Un elemento no se mueve necesariamente a la parte superior de la lista, cualquier elemento puede colocarse en cualquier lugar de la lista ordenada.


Use el orden de clasificación descendente, es decir, el número de clasificación más alto se muestra en la parte superior.

Si un artículo anterior debe colocarse en la parte superior de la lista, simplemente configure su columna Ordenar en MAX (Ordenar) +1. No es necesario volver a numerar toda la tabla.

Actualiza tus comentarios:

Cambiar el orden de clasificación al punto flotante. Si el orden de clasificación de un artículo se reorganiza entre otros dos artículos, el nuevo valor de clasificación se establece en ((Clase de artículo anterior) + (Clase de próximo artículo)) / 2. De lo contrario, establezca Ordenar a MAX + 1.


Modele su tabla después de la estructura de datos de la lista vinculada. Deshágase de la columna "ordenar", en su lugar tenga una columna next_article_id que apunte al siguiente artículo después de ella. Luego, cuando desee agregar un nuevo artículo en la posición 50, solo tiene que actualizar el artículo 49 para que apunte a su nuevo artículo, luego apunte su nuevo artículo al artículo anterior.


Usar un número real parecería ser la opción más eficiente desde el punto de vista computacional. Puede mover una fila entre otras dos sumando la mitad de la distancia entre las dos filas. Para mover un newrow entre row1 y row2, calcule newrow como newrow = row1 + (row2 - row1) /2.0. Sin embargo, debido a los límites de coma flotante, esta serie (con doble precisión) convergerá en 53 iteraciones. En el peor de los casos, solo puedes hacer 53 inserciones (más si no siempre insertas entre la última nueva fila y la fila2). Esto es similar a la idea de dejar huecos y rellenarlos. La idea de hacer la actualización es menos eficiente, pero no se rompe después de un cierto número de insertos. Mantener la columna indexada probablemente sea útil.


(perdón por el inglés, estoy estudiando)

Es muy simple. Necesitas tener un "agujero de cardinalidad"

estructura que necesita para tener 2 columnas

1) pk = 32bit int

2) orden = 64 bits bigint (BIGINT, NO DOBLE !!!)

insertar / actualizar

1) cuando insertas el primer registro nuevo debes establecer order = round (max_bigint / 2).

2) si inserta al comienzo de la tabla, debe establecer order = round ("orden del primer registro" / 2)

3) si inserta al final de la tabla, debe establecer order = round ("max_bigint - orden del último registro" / 2)

4) si inserta en el centro, debe establecer order = round ("orden de registro anterior - orden del registro después de" / 2)

este método tiene un gran cariño. si tiene un error de restricción o si cree que tiene una cardinalidad pequeña, puede reconstruir la columna de orden (normalizar).

en la situación de máxima con normalización (con esta estructura) puede tener un "agujero de cardinalidad" en 32 bits.

es muy simple y rápido!

recuerda NO HAY DOBLE !!! ¡Sólo INT - orden es el valor de precisión!


Para construir sobre la respuesta de Alkini (yo respondería a eso directamente pero me faltan puntos / privilegios por el momento). Ese método funciona solo si el nuevo orden de visualización es menor que el nuevo. Si es al revés, entonces necesita desplazar los artículos intermedios en la otra dirección.

if (new_sort_number == current_sort_number)

Do nothing

if (new_sort_number <current_sort_number)

UPDATE Articles SET sort_number = sort_number + 1 WHERE sort_number BETWEEN :new_sort_number and :current_sort_number - 1;

if (new_sort_number> current_sort_number)

UPDATE Articles SET sort_number = sort_number - 1 WHERE sort_number BETWEEN :current_sort_number + 1 and :new_sort_number;

Luego, en cualquier caso, actualice el artículo que se movió.

UPDATE Articles SET sort_number = :new_sort_number WHERE article_id = :article_id;

Espero que ayude a alguien más a buscar un algoritmo de actualización de orden de visualización generalizada.