Имеется таблица mysql с записями, которые через php выводятся на страницу в определённом порядке, например: 128, 59, 70, 293, 19 и т.д. Каждая новая запись должна занимать определённое место в данном порядке (порядок записей определяю сам в зависимости от контента). Например, новая запись 476 должна быть вставлена между 59 и 70, т.е. образуется такой массив.
Сейчас я делаю это так: каждой записи даю некоторое число и в запросе указываю сортировку по этим числам. Но я думаю такой алгоритм не очень эффективен, тем более, что данные числа я прописываю вручную.
Есть идеи как можно сделать это по нормальному, не нагружая сильно сервер?
Ответ
На самом деле отдельное поле с идентификаторами задающими порядок - не такая плохая идея. Поле числовое, поэтому сортировка по нему осуществляется очень быстро, оно может быть проиндексировано, поэтому запрос может быть еще более ускорен и практически не зависеть по скорости от объема таблицы.
Заполнять это поле не обязательно вручную, можно прикрутить интерфейс, позволяющий перетаскивать позиции пользователю и пересчитывать это поле автоматически.
Альтернатив не так много и они уже не так эффективны. Например, MySQL-функция FIELD(), которая возвращает позицию вхождения первого аргумента в список, который задается оставшимися аргументами.
В качестве первого параметра передается поле id, а в качестве остальных аргументов используется список 128, 59, 70, 293, 19. Так как все не входящие в список значения будут получать значение 0, его лучше заменить на 65536
SELECT
*
FROM
tbl
ORDER BY
IF(FIELD(id, 128, 59, 70, 293, 19) = 0, 65536, FIELD(id, 128, 59, 70, 293, 19))
или в качестве альтернативы можно обратить список и использовать ключевое слово DESC, тогда значения 0, возвращаемые функций FIELD() выстроятся в конец и их можно будет отсортировать по какому-то другому полю
SELECT
*
FROM
tbl
ORDER BY
FIELD(id, 19, 293, 70, 59, 128) DESC, name;
Однако этот подход хуже, чем дополнительное поле, так как вычисления позиции осуществляются при выборки каждой строки, такое динамическое поле невозможно проиндексировать (по крайней мере в MySQL).
Лучше оставить отдельное поле для сортировки, однако рассмотреть возможность его автоматического заполнения. Например, по умолчанию присваивать ему максимальное значение + 1, т.е. размещать в конце, а при перетаскивании элемента, вычислять смещение и изменять (UPDATE) это поле у всех строк в интервале смещения.
Комментариев нет:
Отправить комментарий