Топ контрибуторов
loading
loading
Знаете ли Вы, что

Список полученных сертификатов находится на странице Вашего профиля. Сертификаты можно распечатать или разместить на Вашем сайте.

Лента обновлений
ссылка Mar 27 19:27
Комментарий от Kibalcish:
прошло пять лет....
ссылка Mar 27 10:48
Добавлен вопрос в тест Алгоритмы
ссылка Mar 26 18:58
Комментарий от DimaDK:
посмотрите на это так:
(a, b) = (0, 1) т.е. а принимае зн...
ссылка Mar 26 08:47
Комментарий от user000:
извиняюсь, всё верно - этот вариант ответа не подходит и...
ссылка Mar 25 21:00
Комментарий от dolbatehnik:
1. A - это абстрактный класс, его объект создать нел...
Статистика

Тестов: 153, вопросов: 8597. Пройдено: 456538 / 2235288.

Разбиение на страницы в SQL (paging, постраничка)

head tail Статья
категория
Базы данных
дата15.07.2009
авторmanuna
голосов17

[Disclaimer: Данная статья была переведена в рамках "Конкурса на лучший перевод статьи" на сервисе Quizful. Ссылка на оригинал находится внизу страницы.]

Разбиение на страницы — это термин, обозначающий получение подвыборки даных из набора записей. Представьте, что имеется список из 1000 записей, но пользователю одновременно все они не нужны — тогда есть смысл разбить их на страницы. Устанавливается размер страницы и пользователь одновременно сможет просматривать, скажем, по 50 или по 100 записей на странице, перелистывая их по мере надобности.

Обычным практическим примером использования этого в сети является программное обеспечение форумов. Вместо отображения 9 миллиардов ответов темы, оно отображает только 10 за раз. Почему? Во-первых, если пользователь хочет увидеть новые сообщения в цепочке, ему надо будет загрузить только последнюю страницу (или только первую, если надо просмотреть лишь начало темы). Во-вторых, если сервер будет отдавать по 10 сообщений, то в 99 случаях из 100 это уменьшит требуемую пропускную способность канала и время загрузки страниц.

Давайте посмотрим на SQL для генерации набора записей:

SELECT * FROM table_name

Этот запрос вернет все даные из таблицы table_name. Если же мы хотим получить первые 30 записей этой таблицы, надо будет использовать синтаксис, специфический для базы данных (то есть один и тот же запрос не станет работать для MS SQL Server и для MySQL). Для MySQL запрос выглядит так:

SELECT *  FROM table_name LIMIT 30

А для MS SQL server - вот так:

SELECT TOP 30 * FROM table_name

LIMIT, как вы уже догадались — это удивительное ключевое слово. У него есть два варианта: один выбирает первые <сколько-там-указано> записей, а другой выбирает диапазон. Итак — что если нам нужна третья “страница” данных, записи с 61 по 90? С использованием LIMIT, в MySQL это будет выглядеть вот так:

SELECT * FROM table_name LIMIT 60, 30

Синтаксис LIMIT такой:

LIMIT <смещение>, <количество строк>

Итак, все просто — как два байта переслать. А вот в MS SQL — совсем другое дело. Как пользователь MySQL, MS SQL и PostgreSQL, могу со всей ответственностью заявить, что это почти что самая раздражающая дыра в MS SQL,которую следовало бы пофиксить еще пару лет назад... Но вернемся к коду:

SELECT *
FROM (
SELECT TOP 30 *
FROM (
SELECT TOP 90 *
FROM table_name
) AS internal
ORDER BY internal.ID DESC
) AS external
ORDER BY external.ID ASC

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

Второй запрос реверсирует упорядочивание (так, чтобы порядок ID данных был 90, 89, 88, 87, ...) и берет первые 30 записей.

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

У Oracle есть свой собственный способ работы со страницами (с использованием достаточно интуитивно понятной переменной ROWNUM, подставляемой в выражение WHERE). Это выглядит так:

SELECT * FROM table_name WHERE ROWNUM > 60 AND ROWNUM <= 90

PostgreSQL использует альтернативный способ (который был также введен в синтаксис MySQL):

SELECT * FROM table_name LIMIT 30 OFFSET 60

При создании системы, которая может использовать одни и те же SQL-запросы на разных базах данных, следует хорошенько подумать о том, как будет производиться разбиение на страницы. Возможно, в такой среде проще будет запросить у базы все ID и вручную определить, как располагаются диапазоны, а потом выбрать их при помощи WHERE.

Надеюсь, кому-то это пригодится.

----------
Оригинальный текст статьи: Paging In SQL

Если Вам понравилась статья, проголосуйте за нее

Голосов: 17  loading...
manuna   clumsy   googperson   googman   googler   admin   Crabar   globus   ulidtko   SunDrop   c0nst   access   denmir   helpa   fil7   sefire   WooDmaN