Q: Как я могу иметь дело со строками, как имя загружающий пользователь?
A: Точно так же вы имеете дело с датами и цифрами. Строки также «упорядочиваются».
В: Как я могу справиться с ситуациями, когда следующий элемент в отсортированном столбце имеет то же значение?
A: Точно так же вы будете иметь дело с повторяющимися значениями для дат, которые не являются уникальными. В дополнение к столбцу «major» sort вам нужен другой «младший» сортировочный столбец, который уникален, или комбинация «major» и «minor» вместе уникальна.
В идеале у вас должен быть PRIMARY KEY или UNIQUE KEY для столбца с нулевым значением, который может служить «младшим» порядком сортировки.
«Трюк» состоит в том, чтобы сохранить текущую позицию в списке, сохранив основные и второстепенные значения в строке «последний раз», а затем используйте эту информацию в запросе, чтобы получить «следующую» страницу.
WHERE t.major >= :last_seen_major
AND (t.major > :last_seen_major OR t.minor > :last_seen_minor)
ORDER BY t.major ASC, t.minor ASC
LIMIT 1
Из последней строки (в данном случае только один), вы хотите, чтобы сохранить значения основных и второстепенных колонн, так что те могут быть использованы в том же запросе, чтобы получить " следующей "строки.
Для получения максимальной производительности запроса вам понадобится индекс с ведущими столбцами (major, minor)
.
На основании вашего запроса, предполагая, что у вас есть id
колонки, вы могли бы сделать что-то вроде этого:
SELECT f.*
FROM Files f
WHERE f.date >= :last_seen_date
AND (f.date > :last_seen_date OR f.id > :last_seen_id)
ORDER BY f.date ASC, f.id ASC
LIMIT 1
Чтобы заказать какой-либо другой колонке заменить f.date
в WHERE и ORDER BY статей с чем-то еще , например f.name
.
Менее производительный альтернатива
Другой очень популярный подход заключается в использовании «смещение» в предложении LIMIT.
Вначале румянец, кажется, является изящным решением, но у него есть некоторые проблемы.
Вы можете сделать:
ORDER BY major ASC, minor ASC LIMIT 41,1
Для «следующего» строки, то увеличиваем смещение на 1
ORDER BY major ASC, minor ASC LIMIT 42,1
Одна из проблем, с этим подходом, если строка вставляется в диапазоне уже увиденные строки, «следующий» запрос вернет ту же строку. Поскольку 41-я строка была теперь 42-й строкой. Если кто-то удалит строку, «следующий» запрос пропустит строку. И я не хочу жить с таким дефектом в моей функции «получить следующую строку». И этот подход по-прежнему должен отслеживать позицию в списке, но, неся дополнительное смещение, которое на самом деле не является частью строки.
Другая проблема с этим подходом заключается в том, что база данных должна извлекать строки, затем заказывать их, а затем, наконец, применять предложение LIMIT, что может быть проблемой производительности с большими наборами.
есть много вопросов по аналогичной теме, с множеством ответов, которые на самом деле не работают. Вам удалось определить ключевую проблему упорядочивания нестандартных значений. «Трюк» заключается в том, чтобы заказать что-то уникальное ... ваш «главный» столбец (то, что пользователь сказал, что он хочет упорядочить предметы, а затем ваш секретный «второстепенный» столбец, который дает вам уникальный идентификатор строки «Трюк» состоит в том, чтобы использовать значения из строки «последний увиденный» для начала в «следующей» строке. Соответствующий индекс сделает это эффективным, может быть более эффективным, чем некоторые другие популярные подходы. – spencer7593