2012-02-22 2 views
3

Мне нужно прочитать содержимое таблицы базы данных MS SQL, используя разбиение на страницы, т.е. выборку первой страницы из N строк, затем вторую страницу из N строк и т. Д.Разбиение страницы на быстро меняющийся контент базы данных

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

SELECT * 
FROM (SELECT a.*, 
    ROW_NUMBER() OVER (ORDER BY id) AS rnum 
    FROM articles a) 
WHERE rnum <= 10 
AND rnum >= 6; 

не может надежно работать. Вставляемые строки могут быть пропущены или могут повторять последующие строки, а удаленные строки могут привести к пропущению последующих строк.

Я мог бы избежать таких проблем, выполнив одно из следующих действий:

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

Я вроде как 3 решения, но я считаю, что трудно осуществить, когда есть повторяющиеся значения в столбце сортировки (s).

Например, допустим, у меня есть список статей, отсортированных по нисходящей оценке. Если рейтинг такой же, они сортируются по возрастанию ID (идентификаторы уникальны):

ID  RATING 
9  34 
3  32 
6  32 
8  32 
12  32 
1  25 
2  23 

Теперь я хочу страниц 3 статей, что означает первая страница будет иметь статьи 9, 3 и 6. Это делается путем запроса трех лучших статей из отсортированного списка.

Теперь я хочу принять следующие 3 статьи, возобновляемые из статьи 8, используя идентификатор статьи в качестве маркера для возобновления.

Если бы я сказал базу данных, чтобы взять на себя репутацию статьи 8 и чем принять 3 статьи, которые имеют репутацию ниже, чем, я бы пропустить статью 12.

Если бы я сказал базу данных, чтобы взять на себя репутацию статьи 8, а затем взять 3 статьи, у которых репутация ниже или равна этой, я бы повторил статьи 3 и 6.

Какой SQL-запрос (или комбинация запросов) можно использовать для возобновления разбивки на страницы из статьи 8, используя идентификатор статьи как маркер для возобновления?

+0

К сожалению, ваши требования не могут не противоречить самим себе. Ваша цель всегда показывать персональные статьи, которые они не видели ранее в этой сессии, или убедиться, что рейтинг является точным?Если я смотрю на верхнюю 3, то кто-то меняет ID 8, чтобы иметь рейтинг 33 (нажатие 6 до второй страницы), вы не хотите показывать 6 на второй странице, потому что они уже видели это ? Что делать, если они снова перейдут на страницу 1? –

+0

@AaronBertrand OK, хороший пункт. Я хочу показать пользователям статьи, которые они не видели раньше. Что бы вы сделали тогда в этом случае? Является ли кэширование всей таблицы единственным решением для обеспечения последовательных результатов по страницам? –

+0

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

ответ

3

Преобразование комментария к ответу, поскольку он, похоже, решил вопрос пользователя.

Похоже, что вы должны кэшировать результат для этого пользователя (например, вы можете отправить все идентификаторы в приложение и просто вытащить по 3 статьи за раз на каждой выборке), но также добавить отказ от ответственности, если он занимает полчаса, чтобы прокручивать список, список больше не может быть точным.

Смежные вопросы