Jest to problem bez całkowicie satysfakcjonującego rozwiązania, ponieważ próbujesz połączyć zasadniczo niezgodne wymagania:
-
Wysyłaj tylko wymaganą ilość danych do klienta na żądanie, tj. nie możesz pobrać całego zestawu danych, a następnie podzielić go na strony po stronie klienta.
-
Zminimalizuj ilość stanu na klienta, którą serwer musi śledzić, aby uzyskać skalowalność z dużą liczbą klientów.
-
Utrzymuj inny stan dla każdego klienta
Jest to sytuacja typu „wybierz dowolne dwa”. Musisz iść na kompromis; zaakceptuj fakt, że nie możesz zachować dokładnego stanu stronicowania każdego klienta, zaakceptuj, że musisz pobrać zestaw dużych zbiorów danych do klienta lub zaakceptuj, że musisz użyć ogromnej ilości zasobów serwera, aby utrzymać stan klienta.
Istnieją odmiany w tych, które mieszają różne kompromisy, ale do tego wszystko się sprowadza.
Na przykład niektórzy wyślą klienta niektóre dodatkowe dane, wystarczające do zaspokojenia większości wymagań klienta. Jeśli klient przekroczy tę wartość, zostanie przerwana paginacja.
Niektóre systemy buforują stan klienta przez krótki czas (z krótkotrwałymi niezalogowanymi tabelami, plikami tymczasowymi itp.), ale szybko go wygasają, więc jeśli klient nie prosi ciągle o świeże dane, jego stronicowanie zostaje przerwane.
Itd.
Zobacz też:
- Jak zapewnić klientowi API 1 000 000 wyników z bazy danych?
- Korzystanie z „Kursorów” do stronicowania w PostgreSQL
- Iterowanie po dużej zewnętrznej bazie danych postgres, manipulowanie wierszami, zapisywanie danych wyjściowych do bazy danych postgres na szynach
- optymalizacja przesunięć/limitów
- Jeśli liczba PostgreSQL(*) jest zawsze wolna, jak podzielić złożone zapytania na strony?
- Jak zwrócić przykładowy wiersz z bazy danych jeden po drugim
Prawdopodobnie zaimplementowałbym rozwiązanie hybrydowe w jakiejś formie, takie jak:
-
Używając kursora, odczytaj i natychmiast wyślij pierwszą część danych do klienta.
-
Natychmiast pobierz wystarczającą ilość dodatkowych danych z kursora, aby spełnić 99% wymagań klientów. Przechowuj go w szybkiej, niebezpiecznej pamięci podręcznej, takiej jak memcached, Redis, BigMemory, EHCache, cokolwiek pod kluczem, który pozwoli mi pobrać go na późniejsze żądania tego samego klienta. Następnie zamknij kursor, aby zwolnić zasoby bazy danych.
-
Przedawniaj pamięć podręczną na podstawie najdawniej używanej, więc jeśli klient nie czyta wystarczająco szybko, musi pobrać świeży zestaw danych z bazy danych, a podział na strony ulega zmianie.
-
Jeśli klient chce uzyskać więcej wyników niż zdecydowana większość jego odpowiedników, stronicowanie zmieni się w pewnym momencie, gdy przełączysz się na odczyt bezpośrednio z bazy danych zamiast z pamięci podręcznej lub wygenerujesz nowy, większy zbiór danych w pamięci podręcznej.
W ten sposób większość klientów nie zauważy problemów z paginacją i nie będziesz musiał wysyłać ogromnych ilości danych do większości klientów, ale nie stopisz swojego serwera DB. Potrzebujesz jednak dużej pamięci podręcznej, aby uciec z tego. Jego praktyczność zależy od tego, czy Twoi klienci poradzą sobie z łamaniem paginacji - jeśli po prostu niedopuszczalne jest zerwanie paginacji, to utkniesz z robieniem tego po stronie DB z kursorami, tabelami tymczasowymi, radzenie sobie z całym zbiorem wyników przy pierwszym żądaniu itp. Zależy to również od rozmiaru zestawu danych i ilości danych zwykle wymaganych przez każdego klienta.