Ordre aléatoire cohérent dans une requête MySQL
j'ai une base de données de photos et je veux laisser les visiteurs parcourir les photos. J'ai un "à côté" et un "précédent" lien.
mais ce que je veux c'est montrer à chaque visiteur un autre ordre des photos. Comment puis-je le faire? Si J'utilise ORDER BY RANDOM (), j'afficherai parfois des images dupliquées.
quelqu'un Peut m'aider s'il vous plaît? Je vous remercie!
6 réponses
Vous pouvez essayer d'utiliser des semences en fonction aléatoire:
SELECT something
FROM somewhere
ORDER BY rand(123)
123 est une graine. Aléatoire doit retourner la même valeur.
Le problème vient du fait que chaque page run RAND()
et n'a aucun moyen de savoir si les photos retournées ont déjà été retournées auparavant. Vous devez composer votre requête de manière à filtrer les images déjà présentées sur les pages précédentes, de sorte que RAND()
moins d'options à choisir.
une idée serait de randomiser les images, sélectionner les IDs, stocker les IDs dans la session, puis SELECT
à l'aide de ces Identifiants. Ce manière, chaque utilisateur dispose d'images aléatoire, mais ils seront en mesure de paginer à travers eux sans re-sélectionnant aléatoirement à chaque page.
Donc, quelque chose comme:
SELECT id FROM pictures ORDER BY RAND() LIMIT x
si vous n'avez pas les ID dans la session déjà- stocker les ID dans la session
SELECT ... FROM pictures WHERE id IN (IDs from session) LIMIT x
une autre idée est de stocker en session les identifiants que l'Utilisateur a déjà vus et de les filtrer. Pour exemple:
SELECT ... FROM pictures ORDER BY RAND() LIMIT x
si la session ne contient pas D'ID- ajouter les IDs de la requête courante à la session
SELECT ... FROM pictures WHERE id NOT IN (IDs from session) ORDER BY RAND() LIMIT x
une Autre façon semble être d'utiliser une graine, comme izi points. Je dois dire que je ne savais pas pour la graine, mais il semble retourner les mêmes résultats pour la même valeur exacte de la graine. Ainsi, l'exécution de votre habitude de la requête et de l'utilisation RAND(seed)
au lieu de RAND()
, où la "graine" est un chaîne ou numéro unique. Vous pouvez utiliser l'ID de session comme une graine, parce qu'il est unique pour chaque visiteur.
vous pouvez lancer la fonction aléatoire comme suggéré par izi, ou garder une trace des images visitées vs les images non visitées comme suggéré par rdineiu.
je tiens à souligner qu'aucune option ne fonctionnera bien, cependant. Soit vous mènera à trier votre table entière (ou la partie de celle-ci d'intérêt) en utilisant un critère arbitraire et l'extraction du haut n
lignes, éventuellement avec un décalage. Ce sera terriblement lent.
ainsi, considérez un instant combien il est important que tous les le visiteur devrait obtenir un ordre d'image différent. Probablement, ce sera pas important, tant que les choses semblent aléatoires. Si tel est le cas, envisagez cette solution...
Ajouter un extra float
champ à votre table, appelle sort_ord
. Ajouter un index. À chaque insertion ou mise à jour, attribuez-lui une valeur aléatoire. Le but ici est de finir avec un ordre apparemment aléatoire (du point de vue du visiteur) sans compromettre performance.
une telle configuration vous permettra de saisir le haut n
les lignes et paginer vos images en utilisant un index, plutôt que de trier votre table entière.
à votre choix, avoir une tâche cron périodiquement définir une nouvelle valeur:
update yourtable
set sort_ord = rand();
également à votre choix, créez plusieurs champs de ce type et assignez-en un aux visiteurs lorsqu'ils visitent votre site (cookie ou session).
Cela va résoudre:
SELECT DISTINCT RAND() as rnd, [rest of your query] ORDER BY rnd;
Use RAND (SEED). À partir de la documentation: "si un argument entier constant n est spécifié, il est utilisé comme valeur de départ." (http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_rand).
Dans l'exemple ci-dessus, le résultat est toujours le même. Vous changez simplement la graine (351) et vous obtenez un nouvel ordre aléatoire.
SELECT * FROM your_table ORDER BY RAND(351);
Vous pouvez changer la graine chaque fois que l'utilisateur frappe la première page.
sans voir le SQL, je suppose que vous pourriez essayer SELECT DISTINCT...