Выборка предыдущей и следующей записи

Prolix

Новичок
Выборка предыдущей и следующей записи

Здравствуйте!

Имеется таблица records, в которой сортировка производится по флажку "важности" и символьному значению. Например:

-----------------------------------
ID | title | importance
-----------------------------------

1 - C - 0
2 - A - 0
3 - D - 1
4 - B - 0

ID - стандартное поле auto_increment. importance = 1 или 0.

Когда скрипт отображает определенную запись, например, "select * from records where ID=2" (запись A), неким запросом нужно отображать ID и заголовок записей, которые следуют до и после этой записи, однако сортировка производится не по ID, а по "importance DESC, title ASC". Т.е. предыдущая по отношению к A будет D, а следующая - B. Если помечена запись D, то предыдущей не будет, а следующая будет A.

Самым простым решением, конечно же, является проход по всем записям и выбор двух нужных. Однако этот вариант не годится, ибо кол-во записей может быть очень большим, а запрос должен быть маскимально быстрым. Это могут быть также два быстрых запроса, если необходимо (как если бы двумя запросами выбирать записи по ID).

Поиск по форуму я делал, но есть только похожая тема с данным вопросом... там обсуждается, как выбрать пред./след. запись по ID, насколько я понимаю. Но тут вопрос другой. Может быть, у кого-то есть какие-либо идеи по этому поводу... спасибо.
 

Фанат

oncle terrible
Команда форума
поищи ещё. тем таких было море.

да и не с одним ID задача решается точно так же, как с одним.
 

Prolix

Новичок
Фанат
Если бы таких тем было море, я бы сюда не постил...

Вдумаетесь в описание - поймете, что только с виду все просто.

На форуме подобная тема найдена мною только тут:

http://phpclub.ru/talk/showthread.php?threadid=66224

Про сравнение на больше-меньше здесь речи не идет, и про ID тоже.
 

Фанат

oncle terrible
Команда форума
вдумываться мне не во что. проблема стандартная.
не надо думать, что ты такой уникальный, и первый, кто с таким вопросом столкнулся.
андестенд?

-~{}~ 22.11.06 12:55:

условие добавь в свой запрос. еще одно.
не одна сортировка? значит и условие при поиске не одно.
 

AnToXa

prodigy-одаренный ребенок
можно прям при выборке для показа списка со всеми сортировками и проч просто положить этот список в сессию юзеру уже в нужном порядке, а потом при клике уже найти только в сессии пред/след записи. минус: если данные в таблице обновились между кликами, то возможны не совсем актуальные данные, иногда это даже хорошо, а иногда - нет.
если это критично, можно еще в сессию положить время создания и работать с ней как с кешем.
 

Prolix

Новичок
Фанат
Определенно, я не первый, кто с таким вопросом столкнулся, и своей уникальностью не бахвалюсь - а вы умеете только на личности сразу переходить? Два поста и никакой полезной информации, а еще oncle terrible. Ваши 20827 сообщений на форуме - все в таком же духе?

Какое может быть "еще не одно" условие при поиске? Я же вроде нарисовал подробно схему. При выборке по ID предыдущая и следующая запись относительно записи ID 2 находятся просто.

select * from records where ID<2 order by id asc limit 1; // предыдущая запись
select * from records where ID>2 order by id asc limit 1; // следующая запись

Теперь поясните, пожалуйста, где в подобном запросе я могу применить "не одно условие", если записи сортируются в порядке "importance DESC, title ASC" (а теоретически, могут сортироваться в любом необходимом порядке). Сравнивать по title - хорошо, а как быть с importance?

AnToXa
Вариант с сессиями не годится, к сожалению. Тогда уж лучше кэшировать данные в доп. таблице, но нужно простое и эффективное решение.
 

Prolix

Новичок
почему -

1. нужно простое, эффективное, нересурсоемкое, универсальное решение

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

3. штука эта должна работать для поисковика, а не для юзера
 

hermit_refined

Отшельник
Тогда уж лучше кэшировать данные в доп. таблице, но нужно простое и эффективное решение.
не вижу ничего сложного и неэффективного в том, чтобы периодически пересоздавать дополнительную таблицу с соответствующей сортировкой.
выборка будет очень быстрой, работы программиста - минут десять, намного меньше, чем вы уже думаете об этом.
 

AnToXa

prodigy-одаренный ребенок
1. нужно простое, эффективное, нересурсоемкое, универсальное решение
ага, сессии

2. могут быть тысячи записей, их всех в сессию не положишь
не надо хранить там все, надо страницу хранить, это записей 10-20-30, совсем немного.

3. штука эта должна работать для поисковика, а не для юзера
в чем проблема? пхп работает одинаково, что для поисковика, что для браузера.
 

hermit_refined

Отшельник
не надо хранить там все, надо страницу хранить, это записей 10-20-30, совсем немного.
тут действительно есть проблемы - поисковик может сначала пройтись по страницам, а уже после - по взятым ссылкам.

да и потом - нужно всё-таки, чтобы страница взятая поисковиком, совпадала с той, что увидит пользователь, на неё зайдя - сессии тут со многих сторон неподходящий вариант.

P.S. Кстати, а почему бы не передавать айдишники соседних записей в урле?..
 

Prolix

Новичок
не вижу ничего сложного и неэффективного в том, чтобы периодически пересоздавать дополнительную таблицу с соответствующей сортировкой - если пересоздавать таблицу с тысячами записей ВСЕГО ЛИШЬ для отображения следующей и предыдущей вам кажется эффективным решением, то для меня - нет. Поэтому и создана тема.

не надо хранить там все, надо страницу хранить, это записей 10-20-30, совсем немного - не понял, какую именно страницу? Что, вообще, в подобного рода сессии можно хранить? Делать полную выборку данных по таблице, пока не найдено искомое, и это закидывать в сессию? И так каждый раз для нового юзера??? Ничего себе, эффективно и быстро...

пхп работает одинаково, что для поисковика, что для браузера - пхп-то одинаково работает, а вот поисковик - нет. Или вы думаете, что поисковик обрабатывает cookie? ID-то сессии хранится в cookie.

сессии тут со многих сторон неподходящий вариант - именно так...

почему бы не передавать айдишники соседних записей в урле - а откуда же их брать?

-~{}~ 23.11.06 14:46:

alpine
крон?.. временная таблица?..

Да овчинка выделки не стоит, народ. Вопрос не просто в том, КАК это сделать, уж поверьте, варианты есть, и мне они известны, вопрос в том, как это сделать МАКСИМАЛЬНО ЭФФЕКТИВНО И БЫСТРО. Этот проект посещают тысячи пиплов в час, какие сессии, какие временные таблицы????
 

AnToXa

prodigy-одаренный ребенок
ID-то сессии хранится в cookie.
либо передается в урле.

Делать полную выборку данных по таблице, пока не найдено искомое, и это закидывать в сессию? И так каждый раз для нового юзера??? Ничего себе, эффективно и быстро...
страница - это набор записей, размер этого набора - фиксированый, например 20 записей, в нужном порядке сортировки. любая запись принадлежит некоторой странице.
вот одну такую страницу класть в сессию, когда показывается какая-то запись из нее.

Этот проект посещают тысячи пиплов в час
и что? это настолько много, что создать сессию - накладно? вы проводили тесты?
 

hermit_refined

Отшельник
если пересоздавать таблицу с тысячами записей ВСЕГО ЛИШЬ для отображения следующей и предыдущей вам кажется эффективным решением, то для меня - нет.
значит, у вас неправильные представления об эффективности.
замечу - таблицу с двумя полями типа int.
но в данном случае, как я уже сказал, можно проще, да - при условии, что на эту страницу, которую вы хотите получить, вы переходите с постраничного списка с той же сортировкой (это обычная ситуация, и именно её, как я понимаю, предполагал AnToXa).

P.S.Или вы думаете, что поисковик обрабатывает cookie?
кстати, нормальный поисковик - да, обрабатывает, хотя бы для того, чтобы сессия в урле не маячила.

P.P.S.
Этот проект посещают тысячи пиплов в час, какие сессии, какие временные таблицы????
вы даже не пытаетесь понять, что вам говорят.
актуальность данных - не нужна, ибо они для поисковика. пересоздавать раз в несколько дней таблицу из какой-то жалкой тысячи записей - это для вас огромная нагрузка? ну-ну.
 

Prolix

Новичок
Вследствие нехватки времени опускаю пустобрехню, по поводу:

alpine
Ты до конца прочитай сначала тот топик там было найдено нормальное решение - я почитал, ключевое там

То есть получаем позицию нашего элемента в отсортированной выборке

вот это именно то, что нужно, только в упор не догоняю, как определить позицию в выборке моего типа...

-~{}~ 23.11.06 17:27:

Могу предложить для изучения следующие статьи:

http://xaprb.com/blog/2006/04/28/how-to-find-next-and-previous-records-in-sql/

там приводится, по сути, то, что я бы хотел увидеть, но я не понимаю, каким образом это работает в mySQL.

А вот здесь - вообще идеальный вариант:

http://jystewart.net/process/archives/2005/06/nextprevious-with-mysql/

но непонятно, как в mySQL работает, опять же.
 

MiksIr

miksir@home:~$
переменные считаются при выводе данных (т.е. уже отфильтрованных по where).
Оптимальный вариант, да еще если нагрузки большие, построить вспомогательную таблицу и перестраивать ее после каждого UPDATE/DELETE (хоть руками, хоть тригером).
CREATE TABLE orders (ord int not null primary key auto_increment, id int);
INSERT INTO orders(id) SELECT id FROM records ORDER BY importance DESC, title ASC;
 

hermit_refined

Отшельник
http://xaprb.com/blog/2006/04/28/how-to-find-next-and-previous-records-in-sql/
там приводится, по сути, то, что я бы хотел увидеть
предлагаемые методы используют последовательный просмотр таблицы (причем зря - так как в их - но не вашем - случае вполне можно заюзать индексы). как это вяжется с вашим желанием "эффективности" известно только вам. тупите дальше, конечно, только непонятно, зачем вы задали свой вопрос на форуме.

Автор оригинала: MiksIr
перестраивать ее после каждого UPDATE/DELETE (хоть руками, хоть тригером).
перелёт, после каждого тут явно не нужно.
 

Prolix

Новичок
пересоздавать раз в несколько дней таблицу из какой-то жалкой тысячи записей - все дело как раз в том, что записи могут пересоздаваться гораздо чаще, скажем, пару раз в минуту. Чаще всего - INSERT, реже - DELETE или UPDATE.

В общем-то, о временной таблице у меня были мысли, но подсказка MiksIr оповестила о том, что это, наверное, и есть самое оптимальное решение. Хотя, наверное, если бы в mySQL была возможность как-то помечать системный порядковый номер записи при любой сортировке, это и было бы тем, что нужно. Но такой возможности, видимо, нет.
 
Сверху