sql >> Database teknologi >  >> RDS >> Mysql

mySQL - Sideinddeling af filtrerede rækker

Du kan ikke vide, hvad det første id på en given side er, fordi id-numre ikke nødvendigvis er sekventielle. Med andre ord kan der være huller i rækkefølgen, så rækker på den femte side med 100 rækker starter ikke nødvendigvis ved id 500. Det kunne f.eks. starte på id 527. Det er umuligt at vide.

Sagt på en anden måde:id er en værdi, ikke et rækkenummer.

En mulig løsning, hvis din klient går videre gennem siderne i stigende rækkefølge, er, at hver REST-anmodning henter data, bemærker den største id-værdi på den side, og bruger den derefter i næste REST-anmodning, så den forespørger på id-værdier, der er større.

SELECT ... FROM ... WHERE filterKey = filterValue 
AND id > id_of_last_match_of_previous_page

Men hvis din REST-anmodning kan hente en hvilken som helst tilfældig side, virker denne løsning ikke. Det afhænger af, at du allerede har hentet den foregående side.

En anden løsning er at bruge LIMIT <x> OFFSET <y> syntaks. Dette giver dig mulighed for at anmode om enhver vilkårlig side. LIMIT <y>, <x> fungerer det samme, men af ​​en eller anden grund er x og y omvendt i de to forskellige syntaksformer, så husk det.

Bruger LIMIT...OFFSET er ikke særlig effektiv, når du anmoder om en side, der er mange sider i resultatet. Lad os sige, at du anmoder om den 5.000. side. MySQL skal generere et resultat på serversiden på 5.000 sider, derefter kassere 4.999 af dem og returnere den sidste side i resultatet. Beklager, men det er sådan det virker.

Om din kommentar:

Du skal forstå det WHERE anvender betingelser for værdier i rækker, men sider er defineret af positionen af rækker. Dette er to forskellige måder at bestemme rækker på!

Hvis du har en kolonne, der med garanti er et rækkenummer , så kan du bruge denne værdi som en rækkeposition. Du kan endda sætte et indeks på det eller bruge det som den primære nøgle.

Men primærnøgleværdier kan ændre sig og er muligvis ikke fortløbende, for eksempel hvis du opdaterer eller sletter rækker eller tilbagefører nogle transaktioner og så videre. Det er en dårlig idé at omnummerere primærnøgleværdier, fordi andre tabeller eller eksterne data kan referere til primærnøgleværdier.

Så du kan tilføje endnu en kolonne, der ikke er den primære nøgle, men kun et rækkenummer.

ALTER TABLE MyTable ADD COLUMN row_number BIGINT UNSIGNED, ADD KEY (row_number);

Udfyld derefter værdierne, når du skal omnummerere rækkerne.

SET @row := 0;
UPDATE MyTable SET row_number = (@row := @row + 1) ORDER BY id;

Du bliver nødt til at omnummerere rækkerne, hvis du f.eks. nogensinde sletter nogle. Det er ikke effektivt at gøre dette ofte, afhængigt af bordets størrelse.

Nye indsæt kan heller ikke oprette korrekte rækkenummerværdier uden at låse tabellen. Dette er nødvendigt for at forhindre løbsforhold.

Hvis du har en garanti for, at row_number er en sekvens af på hinanden følgende værdier, så er det både en værdi og en rækkeposition, så du kan bruge den til højtydende indeksopslag for enhver vilkårlig side med rækker.

SELECT * FROM MyTable WHERE row_number BETWEEN 401 AND 500;

I hvert fald indtil næste gang rækkefølgen af ​​rækkenumre sættes i tvivl ved en sletning eller ved nye indsættelser.



  1. Hvordan kan jeg deaktivere et auto-inkrementerende ID fra at blive opdateret ved dubletnøgleopdatering?

  2. Hvordan indsætter du en PHP-konstant i en SQL-forespørgsel?

  3. Psycopg2 Indsæt i tabel med pladsholdere

  4. mysql-forespørgsel for at forbinde 3 forespørgsler i 1 tabel, mens gennemsnittet beregnes