sql >> Databáze >  >> RDS >> Mysql

mySQL - Stránkování filtrovaných řádků

Nemůžete vědět, jaké je první id na dané stránce, protože čísla id nemusejí nutně následovat. Jinými slovy, v sekvenci mohou být mezery, takže řádky na páté stránce ze 100 řádků nemusí nutně začínat na id 500. Mohou například začínat na id 527, to je nemožné vědět.

Řečeno ještě jinak:id je hodnota, nikoli číslo řádku.

Jedním z možných řešení, pokud váš klient postupuje stránkami ve vzestupném pořadí, je, že každý požadavek REST načte data, uvádí největší hodnotu id na této stránce a poté ji použije v další Požadavek REST, takže se dotazuje na hodnoty ID, které jsou větší.

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

Ale pokud váš požadavek REST může načíst jakoukoli náhodnou stránku, toto řešení nefunguje. Záleží na tom, zda jste již načetli předchozí stránku.

Dalším řešením je použití LIMIT <x> OFFSET <y> syntax. To vám umožní požádat o jakoukoli libovolnou stránku. LIMIT <y>, <x> funguje stejně, ale z nějakého důvodu jsou x a y ve dvou různých formách syntaxe obrácené, takže na to pamatujte.

Pomocí LIMIT...OFFSET není příliš efektivní, když požadujete stránku, která má ve výsledku mnoho stránek. Řekněme, že požadujete 5000. stránku. MySQL musí vygenerovat výsledek na straně serveru 5 000 stránek, pak jich 4 999 zahodit a vrátit poslední stránku ve výsledku. Promiňte, ale tak to funguje.

K vašemu komentáři:

Musíte pochopit, že WHERE aplikuje podmínky na hodnoty v řádcích, ale stránky jsou definovány pozicí řádků. Toto jsou dva různé způsoby určování řádků!

Pokud máte sloupec, který je zaručeně číslo řádku , pak můžete tuto hodnotu použít jako pozici řádku. Můžete na něj dokonce umístit index nebo jej použít jako primární klíč.

Hodnoty primárního klíče se však mohou změnit a nemusí být po sobě jdoucí, například pokud aktualizujete nebo odstraníte řádky nebo vrátíte zpět některé transakce a tak dále. Přečíslování hodnot primárního klíče je špatný nápad, protože na hodnoty primárního klíče mohou odkazovat jiné tabulky nebo externí data.

Můžete tedy přidat další sloupec, který není primární klíč, ale pouze číslo řádku.

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

Potom vyplňte hodnoty, když potřebujete přečíslovat řádky.

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

Pokud byste například někdy smazali řádky, museli byste řádky přečíslovat. Není efektivní to dělat často, v závislosti na velikosti tabulky.

Nové vložky také nemohou vytvořit správné hodnoty čísel řádků bez uzamčení tabulky. To je nezbytné, aby se zabránilo rasovým podmínkám.

Pokud máte záruku, že row_number je posloupnost po sobě jdoucích hodnot, pak je to jak hodnota, tak pozice řádku, takže jej můžete použít pro vysoce výkonné indexové vyhledávání pro jakoukoli libovolnou stránku řádků.

SELECT * FROM MyTable WHERE row_number BETWEEN 401 AND 500;

Alespoň do doby, než bude posloupnost čísel řádků zpochybněna odstraněním nebo novým vložením.



  1. Oracle SQL vkládá hodnoty sloupce do jednoho řádku

  2. Číslo řádku na serveru SQL jako LINE v USER_SOURCE oracle

  3. Vrátíte Min() a další pole?

  4. Tinyint vs Bit?