콘텐츠 등급이 빠르게 변경 될 수있는 경우 페이지 매김이 어려우며 사용자 별 순위가 다를 때 페이지가 더 힘들어집니다. (무한한 스크롤을 링크가 보이지 않는 일종의 페이지 매김으로 취급합시다.) 두 가지 어려운 문제가 있습니다. 처음에 새로 추가 된 내용과 다시 읽은 내용입니다.급변하는 콘텐츠 목록을 처리 할 수있는 페이지 매김 방식은 무엇입니까?
새로 추가 된 콘텐츠를 잊어 버리고 페이지 1을 새로 고침하여보아야합니다. 우리가 순수한 것을하는 척하자. ORDER BY position
; 다른 명령으로 주문하는 경우 창 기능을 사용해야 할 수도 있습니다. 우리 페이지에는 페이지 당 4 행의 동물이 있습니다. 우리는 1 페이지를 가져
+----+----------+-----------+
| id | position^| animal |
+----+----------+-----------+
| 1 | 1 | Alpacas |
| 2 | 2 | Bats |
| 3 | 3 | Cows |
| 4 | 4 | Dogs |
| 5 | 5 | Elephants |
| 6 | 6 | Foxes |
| 7 | 7 | Giraffes |
| 8 | 8 | Horses |
+----+----------+-----------+
후, 우리는 2 페이지를 가져 오기 전에 항목이 많이 이동할 : 그들은 시작합니다. DB를 지금 : 일반적인 세 가지 방법이 있습니다
+----+----------+-----------+
| id | position^| animal |
+----+----------+-----------+
| 4 | 1 | Dogs |
| 2 | 2 | Bats |
| 1 | 3 | Alpacas |
| 5 | 4 | Elephants |
| 6 | 5 | Foxes |
| 7 | 6 | Giraffes |
| 3 | 7 | Cows |
| 8 | 8 | Horses |
+----+----------+-----------+
:
오프셋/제한 접근
이 전형적인 순진 접근 방법이다; Rails에서는 will_paginate 및 Kaminari이 작동하는 방식입니다. 2면을 가져 오려면
SELECT * FROM animals
ORDER BY animals.position
OFFSET ((:page_num - 1) * :page_size)
LIMIT :page_size;
행이 5-8 행이됩니다. 나는 코끼리를 결코 보지 않을 것이다. 그리고 나는 암소를 두 번 볼 것이다.
마지막 ID 방식을
레딧 다른 접근 방식을 취를 본. 페이지 크기를 기반으로 첫 번째 행을 계산하는 대신 클라이언트는 북마크와 같이 본 마지막 항목의 ID를 추적합니다. "다음"을 클릭하면 그 북마크에서부터 검색을 시작합니다.
SELECT * FROM animals
WHERE position > (
SELECT position FROM animals
WHERE id = :last_seen_id
)
ORDER BY position
LIMIT :page_size;
경우에 따라 페이지/오프셋보다 잘 작동합니다. 그러나 우리의 경우, 마지막으로 본 포스트 인 Dogs는 # 1로 확대되었습니다. 그래서 클라이언트는 ?last_seen_id=4
을 보내고 내 페이지 2는 박쥐, 알파카, 코끼리, 여우입니다. 나는 어떤 동물도 놓치지 않았다. 그러나 나는 Bats와 Alpacas를 두 번 본다.
서버 측 상태
HackerNews (지금 당장 사이트)이 서버 측에 연속성을 해결한다; 그들은 전체 결과 집합을 저장하거나 (적어도 몇 페이지를 미리 작성 했습니까?), "계속"링크는 해당 연속을 참조합니다. 2 페이지를 가져올 때 "원래 쿼리의 2 페이지"를 요청합니다. 그것은 동일한 오프셋/한계 계산을 사용하지만, 원래의 쿼리와는 반대이므로, 이제는 상황이 바뀌어도 상관하지 않습니다. 나는 코끼리, 여우, 기린, 말을 봅니다. 속임수도, 누락 된 아이템도 없습니다.
단점은 서버에 많은 상태를 저장해야한다는 것입니다. HN에 저장된 내용은 RAM에 저장되며, 실제로는 "계속"버튼을 누르기 전에 만료됩니다. 따라서 유효한 링크를 찾기 위해 페이지 1로 다시 이동해야합니다. 대부분의 응용 프로그램에서 memcached 또는 데이터베이스 자체에 저장할 수 있습니다 (자체 테이블 또는 Oracle 또는 PostgreSQL에서 유지 커서를 사용하여). 응용 프로그램에 따라 성능이 저하 될 수 있습니다. PostgreSQL에서 적어도 올바른 데이터베이스 연결을 다시 시작하는 방법을 찾아야합니다.이 방법은 끈적 끈적한 상태 또는 영리한 백엔드 라우팅이 많이 필요합니다.
유일한 방법은 있습니까? 그렇지 않다면, 이것에 관해 읽을만한 Google 주스를 줄 컴퓨터 과학 개념이 있습니까? 전체 결과 집합을 저장하지 않고 연속 접근법을 근사화하는 방법이 있습니까? 장기적으로 볼 때 복잡한 이벤트 스트리밍/포인트 인 타임 시스템이 있는데 "1 페이지를 가져온 순간의 결과 집합"은 영원히 파생됩니다. 그것의 짧은 ...?
다른 각도에서 보도록 제안합니다. 아마도 무제한 스크롤 + 페이지 재로드없이 목록을 업데이트하고 사용자 편의를 위해 적절한 ↑/↓ 기호를 표시하는 광범위한 스크립팅을 사용하여 페이지 매김을 피할 수 있습니다. 그것은 유스 케이스에 따라 다르다. 업데이트 : FWIW, 여기 [관련 질문] (http://ux.stackexchange.com/questions/2997/best-way-to-add-items-to-a-paginated-list/2999#2999) from UX StackExchange . – Tony
그래, 그게 우리의 유스 케이스에 대해 작동하지 않습니다 ... 일들이 지속적으로 reranked, 당신은 지속적으로 디스플레이를 업데이 트하고 싶지 않을 것입니다. 그래도 좋은 생각입니다. –
클라이언트에 상태를 저장하고 모든 레코드의 ID를 보낼 수 있습니다. –