Selezionare una serie di righe da una tabella in modo casuale è semplicissimo, basta usare ORDER BY RAND() nella nostra select. Alcuni preferiscono usare anche tecniche diverse, che vanno dall’uso di PHP alla scrittura di select particolari. Il motivo è che ORDER BY RAND() risulta lenta in quanto MySQL crea una tabella temporanea con tutti i risultati e assegna poi ad ogni riga un indice casuale, ritornando poi un risultato ordinate (casuale)!
Comunque, quello che vorrei mostrare, invece, è come risolvere la paginazione di righe casuali. Come è ovvio eseguendo una select del tipo:
1 | SELECT * FROM `table` LIMIT amount OFFSET offset; |
Otteniamo una lista – non ordinata, se non per inserimento – di righe che, tramite offset possiamo paginare. Se ordiniamo tutto in modo casuale:
1 | SELECT * FROM `table` ORDER BY RAND() LIMIT amount OFFSET offset; |
Diventa immediatamente chiaro il problema! La prima volta, quando offset è uguale a 0, verranno estratte un numero pari ad amount di righe in modo casuale. E fino qui nulla di strano. Tuttavia quando offset sarà incrementato del valore di amount essendo l’ordine casuale, sicuramente otterremo righe già estratte precedentemente! La soluzione, apparentemente complessa, è data dalla stessa funzione RAND(). Quest’ultima, infatti, permette di creare una sequenza randomica che si mantiene nel tempo, tramite l’uso del parametro seed. Scrivendo, ad esempio:
1 | SELECT * FROM `table` ORDER BY RAND(1234) LIMIT amount OFFSET offset; |
Otteremo una sequenza casuale che, se rieseguita, sarà sempre la stessa! Ovviamente siamo ancora a metà dell’opera, perché la domanda che sorge inevitabilmente spontanea è: ok, comunque sia in questo modo l’utente vedrà si gli elementi ordinati in modo casuale (la prima volta) ma sarà sempre lo stesso nel tempo!
La soluzione è semplice: generare un seed in modo tale che sia duraturo ma variabile, ovvero, un seed per sessione ad esempio. Potremmo, quindi, generare un seed in modo casuale, inserirlo nella $_SESSION e utilizzarlo per tutta la durata della navigazione. Oppure, se preferite, una soluzione più sottile:
1 2 |
In questo modo una utenza, identificata da $_SERVER['REMOTE_ADDR'] paginerà in modo casuale – ma coerente – all’interno di un’ora. Poi, ovviamente, potete modificare a vostro piacere in base all’esigenze.








6
Non ci sono commenti per questo Post
Lascia un commento