Ленивая загрузка SQL - ВЫБЕРИТЕ диапазон, но откажитесь от ранее выбранных записей - PullRequest
0 голосов
/ 02 мая 2018

У меня есть набор brochure объектов, которые имеют разные версии language, хранящиеся в моей базе данных. brochure поделится doc_id во всех своих версиях. Вот как выглядит моя БД:

 ___________________________________________________
|   id   |   doc_id   |   language   |   etc...     |
|    1   |  628fdd40  |      en      |              |
|    2   |  628fdd40  |      fr      |              |
|    3   |  0ba86e5b  |      en      |              |
|    4   |  628fdd40  |      jp      |              |
 etc...

Я хочу лениво загружать эти брошюры по мере необходимости, используя запрос, подобный

SELECT * FROM Brochures
WHERE (id BETWEEN 10 AND 20)

но я не хочу выбирать какие-либо брошюры дважды - то есть, если я выбрал французскую версию, я не хочу также выбирать английскую, японскую и т. Д. Версии. Я не могу гарантировать, что брошюры будут внесены в базу данных последовательно (как показано в примере с БД выше)

Я думал об использовании предложения NOT IN для фильтрации ранее выбранных doc_id, но это потребовало бы от меня постоянно растущего списка doc_id где-то, скорее всего в $_SESSION или передать этот список с помощью моих запросов AJAX. Это не похоже на элегантное решение.

Я также подумал, что, может быть, мне удастся запустить другую таблицу, которая отслеживает ранее выбранные doc_id против сессий, запустив UPDATE после каждого выбора и затем выполнив подзапрос предложения NOT IN. Я не уверен в последствиях там.

Есть ли что-нибудь умное, что я могу сделать здесь? Кто-нибудь придумал что-нибудь подобное? Имеет ли это смысл?

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Вы можете получить первое появление брошюры, используя такой запрос:

select b.*
from brochures b
where b.id = (select min(b2.id) from brochures b2 where b2.doc_id = b.doc_id)
order by id;

Для производительности вам нужен индекс на brochures(doc_id, id).

Тем не менее, ваш запрос будет работать на практике. Однако SQL и MySQL не гарантируют порядок набора результатов, если вы не включите ORDER BY для самого внешнего SELECT. Вы должны включить ORDER BY, чтобы ваш код был устойчивым (например, изменение базы данных или переключение представления для таблицы может привести к непредвиденным последствиям).

0 голосов
/ 02 мая 2018

Перечитав вопрос и просмотрев ваши комментарии, я могу категорически заявить, что вы не используете MySQL должным образом. Вы предположили, что вам нужно использовать WHERE (id= range) для достижения нумерации страниц. Это неверно, вам нужно использовать специальные инструменты в MySQL, чтобы получить PAGINATION. (то, что вы назвали ленивой загрузкой)

 SELECT * FROM Brochures ORDER BY id LIMIT 0,10
 SELECT * FROM Brochures ORDER BY id LIMIT 10,10
 SELECT * FROM Brochures ORDER BY id LIMIT 20,10

Этот механик достигает этого - тривиально добавить к этому WHERE предложений.

это будет означать, что вы получаете десять записей за раз, просто выбирая со спецификой - используя WHERE distinct или group by

Я ценю, что это несколько ускорило процесс обучения, но это задача. Это как это сделать, я прав. Удачи. убедитесь, что вы используете order by id

PS: Я бы порекомендовал добавить индекс на id, когда вы используете порядок в своей нумерации страниц.

PPS: Недавно я объяснил другому пользователю SO , как он тоже получил роль предложения where, запутавшегося с ролью limit, это более подробно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...