Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Флейм (http://www.flasher.ru/forum/forumdisplay.php?f=53)
-   -   Pagination (Разбивка на страницы) (http://www.flasher.ru/forum/showthread.php?t=194473)

wvxvw 15.02.2013 00:38

Pagination (Разбивка на страницы)
 
Тут вот у нас давече вышел спор, хочется услышать мнения бывалых форумчан :)

Для начала опишу проблему, для тех, кто не в курсе:
Очень часто возникает необходимость показать пользователю часть данных, разбив их на страницы. Проблема, на первый взгляд тривиальная: посчитать сколько есть, и поделить на размер страницы, загрузив первую, и дальше грузить последующие. Проблема становится менее тривиальной в тот момент, когда приходит понимание, что "а черт, это ж два запроса к БД". Но потом как-то успокаиваешся, говоря себе - да ну и что, если сделать count да еще и по индексированому полю - это ж копеечная нагрузка.
Вторая стадия проблемы наступает (или не наступает?) тогда, когда понимаешь, что между тем, чтобы посчитать количество записей и выдать страницу может случится непоправимое - записи будут удалены. Но тут на помощь приходят АСИД транзакции, которые вроде как гарантируют, что такого не произойдет...
Далее, не смотря на то, что мы уже во всеоружии подготовились встретить проблему, мы понимаем, что транзакция не может закончится до того, как пользователь не перестанет разглядывать страницы (а то, опять же - другой пользователь удалил записи, и разбивка на страницы порушилась).

Итак, есть два подхода решения:

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

carrotoff 15.02.2013 10:31

Первый подход - классический.
Второй - загадочный.

Я - сторонник классики

mooncar 15.02.2013 10:31

Цитата:

Сообщение от wvxvw (Сообщение 1120738)
посчитать количество записей и выдать страницу может случится непоправимое - записи будут удалены. Но тут на помощь приходят АСИД транзакции, которые вроде как гарантируют, что такого не произойдет...

Почему вроде?
Цитата:

Сообщение от wvxvw (Сообщение 1120738)
... мы понимаем, что транзакция не может закончится до того, как пользователь не перестанет разглядывать страницы.

Ты о ситуации, когда юзер пытается что-то сделать с выведенными на страницу данными, а оказалось, что они уже удалены? Так такое бывает сплошь и рядом.
Это задача не уровня БД, а уровня логики движка. Оно вполне может быть, при этом разработчик предусмотрит вывод нечто знакомого: "тема была удалена" или что-то подобного.

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

wvxvw 15.02.2013 12:56

Вроде как - потому, что и на этом уровне есть проблемы. Локи с которыми не хочестя связываться, например. Выборка, сама по себе может быть недетерминированой (например, если в выборке использован rand()), но может быть и менее явно - т.как сиквел не гарантирует какого-то определенного порядка записей в базе, а запрос может неявно зависеть от порядка (например, в транзакт сиквеле можно объявить переменную-счетчик, для того, чтобы выбрать Х записей, но это могут быть не всегда те же записи).

По поводу традиционности первого и нетрадиционности второго - я боюсь, что вы ошибаетесь. GMail не считает все результаты поиска, когда вы исчите в почте, или считает очень примерно. Например, я часто наблюдаю картину, когда я ищу что-нибудь в почте и в результатах поиска появляется "показываю сообщения с 1 по 100 из (примерно) 400", но если я начну перебирать их, то, возможно их там будет не больше 300, а может и 500. Аналогично Фейсбук - они так вообще считают только до двадцати, и разбивка на страницы у них делается так, что ты никогда не знаешь, сколько их еще есть, знаешь только, что их либо больше 20, либо нет.

dark256 15.02.2013 15:10

Хороший юзер - мертвый юзер.
В конечном счете, подобные фичи интерфейсов я делаю для себя.
А там уж....
1й вариант.

Psycho Tiger 16.02.2013 00:59

1-ый, конечно. Пользователь хочет знать, сколько результатов, хотя-бы примерно. Хотя просматривать он будет всё равно по странице. Этот странный user expirience.

СлаваRa 16.02.2013 01:14

2ой..
ну, не нравится мне, когда "говорят" доступно 40 страниц, а при клике на 10, я оказываюсь на 5ой и она последняя.

wvxvw 16.02.2013 02:37

Дык это, примерно получится и в том и в другом случае. Просто в первом неточность подразумевается, но не сообщается о том, что данные могут быть не точными. Т.е. типичный результат / процесс использования:

1. Пользователь загрузил страницу с письмами.
2. На странице оказалось 10 писем.
3. Под письмами оказались ссылки на другие страницы, содержащие по 10 писем с первого по девяностое.
4. Пользователь перешагнул на следующую страницу и получил письма с девяносто первого по восемдесят первое (потому что во время перехода добавилось еще одно письмо к началу списка).

И тут возникла неувязка: мы шли к началу, но начало от нас отдаляется, и при определенном темпе мы никогда до начала не доберемся / данные станут критически неверными (наберется лишняя страница). (так это происходит, например, на stackoverflow).

4.1 Пользователь перешагнул на следующую страницу, и увидел письма с девяностого по восьмидесятое, вернусля на страницу обратно, а сто первое письмо "потерялось", либо "потерялось" девяносто первое. (примерно так это происходит в VBuletin).

Но если бы мы изначально не зарекались по поводу того, сколько у нас еще есть писем - то когнитивного диссонанса не произошло бы. Сказали, что есть "больше двадцати" - ну так их и было +/– честно. И переходы в таком случае не гарантируют точный индекс, а только индекс относительно последней показаной таблицы.

Последний вариант, по крайней мере, с точки зрения базы данных, гораздо удобнее.

iNils 16.02.2013 15:15

Цитата:

Но если бы мы изначально не зарекались по поводу того, сколько у нас еще есть писем - то когнитивного диссонанса не произошло бы. Сказали, что есть "больше двадцати" - ну так их и было +/– честно. И переходы в таком случае не гарантируют точный индекс, а только индекс относительно последней показаной таблицы.
Больше 20, это и 21 и 1000. В обоих случаях ты можешь оценить временные затраты на просмотр, если будешь знать число страниц. Для 21 это - 2, а для 1000 - 50. Согласись, что есть разница?
А если не будешь, и потому, что число страниц изменится, то "волков бояться - в лес не ходить". А что касается "прыжков" из-за добавления новых данных (при условии, что это частые случаи), то лично я считаю, что вывод данных "новое - первое" не имеет права быть. Сообщения должны оставаться на своих местах при добавлении новых.
К примеру. У нас на форуме, новые темы идут первыми, но добавление новой темы, не такое частое явление по сравнению с добавлением нового ответа в теме. Поэтому среди тем потеряться сложно, а среди сообщений легко.
На форуме ixbt и в комментариях к новостям, есть выбор что показывать первым. Я поставил сначала старые и перестал теряться.
А на форуме sports.ru новые комментарии к новости могут появляться по несколько штук в минуту и после рефреша страницы приходиться заново находить где ты остановился.

dark256 16.02.2013 18:08

Трёп ни о чем.
Эсхатологические реминисценции рефлексирующей интеллигенции...

dixi


Часовой пояс GMT +4, время: 10:47.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.