mysql - una - tipos de tablas de datos
¿Cuál es la manera más eficiente de almacenar un orden de clasificación en un grupo de registros en una base de datos? (5)
¿Qué pasa con el uso de una columna integer
que define el orden? De forma predeterminada, asigna números * 1000, como 1000, 2000, 3000 ... y si mueve 3000 entre 1000 y 2000, cámbielo a 1500. Por lo tanto, en la mayoría de los casos no necesita actualizar los otros números. Yo uso este enfoque y funciona bien. También puede usar el double
pero luego no tiene control sobre los errores de precisión y redondeo, así que no lo use.
Entonces, el algoritmo se vería como : digamos que mueves B a la posición después de A. Primero, selecciona para ver el orden del registro junto a A. Si es al menos +2 más alto que el orden de A, entonces simplemente establece el orden de B para encajar en el medio. Pero si es solo +1 más alto (no hay espacio después de A), selecciona los registros limítrofes de B para ver cuánto espacio hay en este lado, divida entre 2 y luego agregue este valor al orden de todos los registros entre A y B. ¡Eso es!
(Tenga en cuenta que debe usar la transacción / bloqueo para cualquier algoritmo que contenga más de una sola consulta, por lo que esto también se aplica a este caso. La forma más sencilla es utilizar la transacción de InnoDB).
Supongamos PHP / MYSQL pero no necesariamente necesito código real, solo estoy interesado en la teoría detrás de esto.
Un buen caso de uso sería la página de la galería de fotos de Facebook. Puede arrastrar y soltar una foto en la página, lo que activa un evento Ajax para guardar el nuevo orden de clasificación. Estoy implementando algo muy similar.
Por ejemplo, tengo una tabla de base de datos "fotos" con aproximadamente un millón de registros:
ID de fotos : int, ID de usuario: int, ID de álbum: int, orden de clasificación: int, nombre de archivo: varchar, título: varchar
Digamos que tengo un álbum con 100 fotos. Arrastro / suelto una foto en una nueva ubicación y el evento Ajax se dispara para guardar en el servidor.
¿Debo pasar toda la gama de identificaciones de fotos al servidor y actualizar cada registro? Asuma la validación de entrada por " WHERE userid
= loggedin_id
", por lo que los usuarios malintencionados solo pueden loggedin_id
el orden de sus propias fotos
¿Debo pasar la identificación de la foto, su índice de ordenación anterior y su nuevo índice de ordenación, recuperar todos los registros entre estos 2 índices, ordenarlos y luego actualizar sus pedidos?
¿Qué sucede si hay miles de fotos en una sola galería y se cambia el orden de clasificación?
Almacenar como una lista vinculada, el orden es una referencia de clave externa al próximo photo_id en el conjunto.
La forma en que lo haría en una base de datos no relacional es almacenar una lista de identificaciones con foto en la entidad / registro ''álbum'', en el orden deseado. Al reordenar los resultados de las fotos se reordena la lista, y solo se escribe una base de datos.
Algunas bases de datos SQL (por ejemplo, PostgreSQL) tienen tipos de datos de listas nativas, pero MySQL no. Podría serializar la lista como una cadena o un binario en MySQL.
Los gurús de la base de datos entrenados en la 3ra forma normal le gritarán que este es un enfoque terrible, pero los RDBMS están optimizados para consultas de tipo OLAP, donde la flexibilidad de las consultas es más importante que el rendimiento de lectura. Las aplicaciones web se escriben mejor teniendo en cuenta una estrategia de "escritura pesada, lectura ligera", y este tipo de desnormalización está exactamente en línea con eso.
Para mí, el segundo método de actualización es el camino a seguir (actualizar solo el rango que cambia). Usted está mencionando "Qué sucede si hay miles de fotos en una sola galería ...", y para mí eso nunca va a suceder. Tomemos tu ejemplo de facebook. Facebook no muestra miles de fotos en una página, se dividen hasta aproximadamente 10-20 por página.
esto probablemente sería una construcción de ''lista enlazada''.