Detta är ett problem utan en helt tillfredsställande lösning eftersom du försöker kombinera väsentligen inkompatibla krav:
-
Skicka bara den nödvändiga mängden data till klienten på begäran, dvs. du kan inte ladda ner hela datamängden och sedan paginera den på klientsidan.
-
Minimera mängden tillstånd per klient som servern måste hålla reda på, för skalbarhet med ett stort antal klienter.
-
Behåll olika tillstånd för varje klient
Detta är en "välj valfri två" typ av situation. Du måste kompromissa; acceptera att du inte kan hålla varje klients sidnumreringstillstånd exakt rätt, acceptera att du måste ladda ner en stor datamängd till klienten, eller acceptera att du måste använda en enorm mängd serverresurser för att bibehålla klienttillstånd.
Det finns variationer inom de som blandar de olika kompromisserna, men det är vad det hela handlar om.
Till exempel kommer vissa personer att skicka några till klienten extra data, tillräckligt för att tillfredsställa de flesta kundkrav. Om klienten överskrider det får den trasig paginering.
Vissa system cachelagrar klienttillstånd under en kort period (med kortlivade ologgade tabeller, temporära filer eller vad som helst), men förfaller det snabbt, så om klienten inte ständigt efterfrågar nya data blir den bruten sidnumrering.
Etc.
Se även:
- Hur tillhandahåller man en API-klient med 1 000 000 databasresultat?
- Använda "Cursors" för personsökning i PostgreSQL
- Iterera över stora externa postgres db, manipulera rader, skriv utdata till rails postgres db
- offset/limit prestandaoptimering
- Om PostgreSQL-antalet(*) alltid är långsamt, hur paginerar man komplexa frågor?
- Hur man returnerar exempelrad från databasen en efter en
Jag skulle förmodligen implementera en hybridlösning av någon form, som:
-
Använd en markör, läs och skicka omedelbart den första delen av data till klienten.
-
Hämta omedelbart tillräckligt med extra data från markören för att tillfredsställa 99 % av kundernas krav. Lagra den i en snabb, osäker cache som memcached, Redis, BigMemory, EHCache, vad som helst under en nyckel som låter mig hämta den för senare förfrågningar från samma klient. Stäng sedan markören för att frigöra DB-resurserna.
-
Upphör cacheminnet på en basis som har använts minst nyligen, så om klienten inte fortsätter läsa tillräckligt snabbt måste de hämta en ny uppsättning data från DB, och sidnumren ändras.
-
Om klienten vill ha fler resultat än den stora majoriteten av sina kamrater, kommer sidnumreringen att ändras någon gång när du byter till att läsa direkt från databasen istället för cachen eller genererar en ny större cachad datauppsättning.
På så sätt kommer de flesta klienter inte att märka pagineringsproblem och du behöver inte skicka stora mängder data till de flesta klienter, men du kommer inte att smälta din DB-server. Du behöver dock en stor boofy cache för att komma undan med detta. Dess praktiska beror på om dina klienter kan klara av pagineringsbrytning - om det helt enkelt inte är acceptabelt att bryta paginering, så har du fastnat med att göra det på DB-sidan med markörer, temporära tabeller, hantera hela resultatuppsättningen vid första begäran, etc. Det beror också på datauppsättningens storlek och hur mycket data varje klient vanligtvis kräver.