Paginazione con MySQL
Se in una pagina web dobbiamo mostrare solo una parte dei dati complessivi è conveniente che solo questa porzione venga prelevata dal database. Per fare ciò dobbiamo modificare la query che utilizziamo per recuperare i dati in modo che essa estragga solo i record necessari a costruire la pagina web richiesta dall'utente. Nello standard SQL però non è prevista una sintassi per limitare i dati provenienti da una SELECT.
I diversi database comunque hanno introdotto nel loro dialetto SQL particolari comandi proprietari per ottenere questo risultato. In particolare MySQL permette l'impiego delle clausole LIMIT e OFFSET, secondo una sintassi del tipo:
SELECT ... LIMIT n
per prelevare solo le prime n righe, e
SELECT ... LIMIT m, n
ovvero
SELECT ... LIMIT n OFFSET m
per prelevare solo n righe, partendo dalla m-esima riga. Facciamo qualche esempio, con:
SELECT * FROM nome_tabella WHERE ... LIMIT 10
otteniamo i primi 10 record estratti dalla SELECT, oppure con
SELECT * FROM nome_tabella WHERE ... LIMIT 20, 10
ovvero
SELECT * FROM nome_tabella WHERE ... LIMIT 10 OFFSET 20
otteniamo 10 record a partire dal 21° (l'offset inizia a contare da zero), cioè i record dal 21° al 30°. E' proprio questa sintassi a permetterci di estrarre i record da mostrare in una particolare pagina web. Ad esempio, se ogni pagina deve contenere 10 record, le precedenti query permettono di estrarre i record necessari a costruire la terza pagina web dei risultati.
Ma non basta la clausola LIMIT a rendere efficace la SELECT. Infatti negli esempi precedenti abbiamo considerato una numerazione per i record (i primi 10 record, i record dal 21° al 30°) senza però specificare secondo quale ordinamento va considerata questa numerazione. Infatti nelle query appena viste l'estrazione di un numero parziale di record avviene in maniera casuale poiché nell'SQL non è indicato il criterio di ordinamento con cui vogliamo che ci vengano restituiti i risultati. Pertanto solo con un ordinamento esplicitamente definito ha senso utilizzare la clausola LIMIT.
Inoltre il criterio di ordinamento deve essere univoco, cioè non deve accadere che due o più record possano essere scambiati di posizione poiché equivalenti nei confronti dell'ordinamento indicato. Vediamo il motivo con un esempio, supponiamo di voler paginare l'elenco telefonico di Napoli. Se usassimo un ordinamento per cognome le pagine contenenti i dati dei signori "Esposito", più di 7.200 record, conterrebbero un elenco casuale di nomi. Ad ogni visualizzazione di una di queste pagine, l'elenco si mostrerebbe sempre diverso, poiché secondo un ordinamento per cognome, i signori Esposito sono tutti uguali e non è possibile decidere in maniera assoluta chi viene prima e chi dopo. Una soluzione potrebbe essere ordinarli per cognome e numero di telefono. In pratica quindi specificare un criterio di ordinamento non univoco equivale in certi casi a non specificare alcun ordinamento.
Per la creazione dei link di navigazione infine serve sapere il numero totale di pagine web in cui stiamo suddividendo l'elenco di record. Questo numero è facilmente ricavabile dal numero complessivo di record da mostrare, ottenibile con una query del tipo:
SELECT COUNT(*) FROM nome_tabella WHERE ...
in cui le condizioni utilizzate nella clausola WHERE devono essere le stesse utilizzate nelle SELECT di estrazione paginata dei dati, ovvero quelle con la clausola LIMIT.