Задать вопрос

PHP + MySQL: Как правильно сделать сортировку?

Здравствуйте. Проблема вот в чём:


В базе данных есть 10 000 записей, у каждой записи своя позиция 1, 2, 3… и так до 10 000. Все они выводятся на страницу и пользователь предоставляется возможность переместить эту запись на какую угодно позицию. Пример: Я беру запись под номером 10 и перемещаю её на место записи 50. При этом в базе данных должно произойти смещение записей (10 запись становится 50, а 50 становится 51, 52 становится 53 и т.д.). Все бы хорошо, но я не считаю это нормальным изменять нумерацию десяти тысяч позиций при каждом перемещении. Что можете посоветовать?


Заранее благодарен за ответ.
  • Вопрос задан
  • 4995 просмотров
Подписаться 5 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 5
Добавьте поле ранг, которое будет отвечать за позицию. Позиция должна задаваться с определёнными промежутками. Например, первая запись — ранг = 100, вторая запись — ранг равен 200, и т.д.
Когда вы переносите запись Вам достаточно изменить ранг на середину промежутка между соответствующими записями. Например, первую запись вы переместили на 50 место, т.е. между 49 и бывшим 50, тогда Вам достаточно установить ранг для новой записи 4950. Остальные записи трогать не надо.
Промежуток между записями выбирается в зависимости от частоты изменений + периодически необходимо производить выравнивание рангов.
Ответ написан
Как вариант — организовать записи в таблице как связанный список (однонаправленный, либо двунаправленный, в зависимости от задачи). В таком случае, при перемещении той или иной записи будут меняться ссылки лишь в записях, которые были до и после перемещаемой и в тех между которыми встанет перемещаемая запись.
Ответ написан
Wott
@Wott
Это точно можно назвать предварительной оптимизацией :)

Почему вы считаете что это ненормально? Сдвинуть нумерацию для всех последующих строк — один ненапряжный запрос.
Сколько нагрузки дадут все эти методы «оптимизации» по сравнению со сдвигом?
Как часто происходит перенумерация по сравнению с обычной выборкой? Может не стоит вообще заморачиваться с тем что происходит крайне редко?
Насколько усложнит и замедлит частые операции выборки дополнительные методы «оптимизации» редкой и ненагружаемой операции?
Ответ написан
Комментировать
Agent_J
@Agent_J
Если у вас не бывает перетасовки всего списка, а перемещение лишь одной записи (при том что это происходит не особенно часто), я бы порекомендовал вам выполнить сортировку в два запроса
-- к примеру новый ранг = 10
-- id сдвигаемой записи 100500
UPDATE `my_table` SET `ordering` = `ordering` + 1 WHERE `ordering`>=10;
UPDATE `my_table` SET `ordering` = 10 WHERE `id`=100500;
Ответ написан
fruitbooter
@fruitbooter
Как вариант — pastie.org/1516344 (писалось на MySQL PL/SQL в учебных помыслах)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы