Есть сайт вопросов и ответов, в нём, в конце списка вопросов, повесил кнопку "Показать еще" (вопросы). Эта кнопка передает ajax запросом в php скрипт, параметр позиции элемента с которого необходимо вернуть новую пачку вопросов. Если использовать в качестве этого параметра, её порядковый номер, например 10, соответственно SQL запрос, в теле php скрипта, будет типа SELECT .... LIMIT 10, 40
(40 - количество), то появляется проблема, так как если, после того как кнопка будет сформирована и выведена в браузере пользователя, будут добавлены новые вопросы, то скрипт продублирует уже выведенные вопросы, так как позиция таблицы уже сместилась. Пришла идея использовать в качестве стартовой позиции - идентификатор последнего вопроса, что-то вроде startID
, но не знаю как это реализовать, что-то вроде SELECT .... LIMIT $startID, 40
, запрос должен вывести 40 записей, после того как встретит запись с заданным startID
. Решение WHERE id > $startID LIMIT 40
не годится так, как строки отсортированы не по полю id. Позволяет ли язык SQL реализовать эту идею?
Всё верно, пагинация через offset предполагает такие артефакты, не говоря о том что такая пагинация медлительна. Направление для решения вы выбрали верное, но вам нужен не абстрактный ID, а сперва вам необходимо явно и недвусмысленно зафиксировать сортировку результата. Запрос where .. limit
для пагинации не имеет смысла. У вас обязан быть order by
при том включающий в себя какой-либо признак уникальности. Например, имея уникальный идентификатор id и если вы хотите сортировать по не уникальному полю created_at с датой создания сущности, то вам необходима сортировка:
order by created_at desc, id desc
Затем, при необходимости загрузить следующий фрагмент данных, вы передаёте на backend оба значение: и created_at и id последней строки которую вы показали пользователю. И запрашиваете следующую порцию данных:
WHERE (created_at, id) < (?, ?)
ORDER BY created_at DESC, id DESC
LIMIT 10
Просто, элегантно, соответствует стандарту, быстро по составному индексу (created_at, id)
. Нормально поддерживается только в postgresql... В mysql выполняется логика верно, но без поддержки индекса (впрочем, может у меня устарели сведения), так что объясняем необходимую логику фильтрации вручную:
WHERE created_at <= ?
AND NOT (created_at = ? AND id >= ?)
ORDER BY created_at DESC, id DESC
limit 10
По материалам статьи Markus Winand, которые весьма рекомендую к прочтению.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Создал бота Telegram, который по нажатию на кнопки выводит заданные результате по командам: /help /test и тд
ЗдрастеМне задали задачку сделать несколько ссылок на одном фото