Mysql : Exclusion

13 réponses
AuteurMessage

Zalex14 |
Modérateur

Photo de Zalex14

Inscrit le : 09/05/2005

# Le 10/01/2007 à 21:15

J'ai besoin de conseils sur un truc que j'ai jamais su faire proprement en mysql : l'exclusion d'enregistrements avec des tables liées.

Je cherche à tirer au sort un enregistrement de la table "photos", sachant que cette table est liée à celle des utilisateurs (pour obtenir toutes les infos) et que cet utilisateur ne doit pas exister dans les votes que le votant a déjà effectué.

J'ai donc 3 tables avec un champ commun : "numero"
Tables :
- "Utilisateurs" (les user),
- "photos" (les photos des users),
- "votes" (les votes par photo). cette dernière table à un champ "votant" qui identifie les propriétaires de chaque vote.


Je ne sais pas si je m'exprime explicitement.
Ma difficulté c'est l'exclusion des numero déjà existant dans "votes" par l'utilisateur "votant" après la jointure photos/utilisateurs.

Quel est donc la meilleure solution pour faire quelque chose de ce type :
photo<-numero->utilisateurs != votes.numero de "votant" ??

Bravo si vous avez compris





Mieux vaut s'attendre au prévisible que d'être surpris par l'inattendu.

devtribu | Olivier
Modérateur

Photo de devtribu

Inscrit le : 16/06/2005

# Le 10/01/2007 à 21:19

aie ma tete
ca me fait penser aux examens
Tu lis l'enonce... Tu te dis, bon, passons à l'exercice suivant
arrivé au bout, tu te dis. Ah ben, ca y est je sais rien faire

Février 2019, mon futur livre Tout JavaScript chez Dunod https://amzn.to/2PoLd0fOuvrir dans une nouvelle fenetre

Fred | Frédéric
Modérateur

Photo de Fred

Inscrit le : 09/05/2005

# Le 10/01/2007 à 21:22

Si j'ai bien compris, tu veux prendre un enregistrement aléatoire dans ta table de photos, sans que ce soit une photo pour laquelle l'utilisateur a déjà voté ?

"Le bois ne rend pas les coups"

Zalex14 | Alexandre
Modérateur

Photo de Zalex14

Inscrit le : 09/05/2005

# Le 10/01/2007 à 21:23

t'as tout compris
le filtre est la liste des numero qui sont approprié à votant dans la base "votes"

Mieux vaut s'attendre au prévisible que d'être surpris par l'inattendu.

devtribu | Olivier
Modérateur

Photo de devtribu

Inscrit le : 16/06/2005

# Le 10/01/2007 à 21:26

il est fort ce cowboy

un truc du genre ?
WHERE vote NOT IN (SELECT votant FROM tabledesvotes)

Février 2019, mon futur livre Tout JavaScript chez Dunod https://amzn.to/2PoLd0fOuvrir dans une nouvelle fenetre

Zalex14 | Alexandre
Modérateur

Photo de Zalex14

Inscrit le : 09/05/2005

# Le 10/01/2007 à 21:29

ouep sauf que le not in n'est pas top pour les performances.
Et comme la base des votes contient quelques centaines de milliers d'enregistrements..

Mieux vaut s'attendre au prévisible que d'être surpris par l'inattendu.

Fred | Frédéric
Modérateur

Photo de Fred

Inscrit le : 09/05/2005

# Le 10/01/2007 à 21:50

SELECT tes_champs FROM photos p
LEFT JOIN votes v ON v.photo_id = p.photo_id AND v.user_id=TON_ID
LEFT JOIN users u ON u.user_id = v.user_id
WHERE u.user_id IS NULL ORDER BY RAND() LIMIT 1


C'est du grand n'importe quoi mais ça marche
C'est juste pour te faire patienter avant la réponse de Bool

"Le bois ne rend pas les coups"

Zalex14 | Alexandre
Modérateur

Photo de Zalex14

Inscrit le : 09/05/2005

# Le 10/01/2007 à 21:55

Thanks, je vais tester

Mieux vaut s'attendre au prévisible que d'être surpris par l'inattendu.

Zalex14 | Alexandre
Modérateur

Photo de Zalex14

Inscrit le : 09/05/2005

# Le 10/01/2007 à 22:09

Humm.. 6 secondes la requete...
Pis y'a un hic : l'interet de la jointure sur users c'est de récupérer les infos du user tiré au hasard, or cette requete ne renvoi aucune information de users (puisque IS NULL)

Mieux vaut s'attendre au prévisible que d'être surpris par l'inattendu.

devtribu | Olivier
Modérateur

Photo de devtribu

Inscrit le : 16/06/2005

# Le 10/01/2007 à 22:19

le not in ne sera pas mauvais si tu as un index sur l'identifiant du votant

Février 2019, mon futur livre Tout JavaScript chez Dunod https://amzn.to/2PoLd0fOuvrir dans une nouvelle fenetre

Zalex14 | Alexandre
Modérateur

Photo de Zalex14

Inscrit le : 09/05/2005

# Le 10/01/2007 à 22:57

je viens de tester effectivement le Not In est plus rapide mais uniquement sans le Order By Rand() (environ une seconde).
Dès que j'ajoute le rand() la requete en not in mets plusieurs dizaines de secondes (et j'ai bien des index sur les identifiants et les numéro des votants)

Mieux vaut s'attendre au prévisible que d'être surpris par l'inattendu.

MathieuC | Mathieu
Modérateur

Photo de MathieuC

Inscrit le : 15/07/2005

# Le 10/01/2007 à 23:04

Le plus simple a mon avis est de scinder ca en plusieurs requetes legeres.

Par exemple, selon ta base, si le nombre de vote par personne ne depasse jamais 100, tu peux faire :

1 - d'abord un select de tous les Id_Photo pour lesquelle l'utilisateur a vote
2 - puis une deuxieme requete simple avec un not in construit en php grace aux resultats de 1

Bien sur, si une partie importante de tes membres a deja 5000 votes, il faut trouver une autre piste


Autre piste, dependant de ton nombre de photos. Si tu as une masse importante de photo, tu peux etre quasi que si tu tire une photo au pif, il y a TRES PEU de chance qu'il s'agit d'une photo pour laquelle ton membre a deja vote. Ce qui devient :
1 - on tire une photo au pif
2 - on verifie qu'il a pas deja vote pour celle la (sinon, on retourne au 1)



Ce sont des manieres de contourner la lourdeur de ta requete, et apres, ca va etre extremement dependant de ta BDD et de son contenu. Mais en terme de performances, tu auras beaucoup de mal a faire mieux

flush | Jean-Philippe
Modérateur

Photo de flush

Inscrit le : 09/05/2005

# Le 10/01/2007 à 23:15

MINUS / EXCEPT à tout hasard ?

@+ Jean-Philippe

Zalex14 | Alexandre
Modérateur

Photo de Zalex14

Inscrit le : 09/05/2005

# Le 10/01/2007 à 23:39

Telaxo : y'a des timbrés qui postent plusieurs milliers de votes par mois . Mais en moyenne un votant "normal" enregistre effectivement moins d'une centaine de votes par mois (entre 50 et 60). Le souci c'est justement qu'aujourd'hui je traite en deux parties puisque je n'arrive pas à trouver une requete suffisament optimisée pour le faire en une fois. Question performance c'est pas top actuellement et aux heures de pointe ca fait beaucoup de requetes.

Flush : ca fonctionne Minus / Except sous mysql ? Je croyais que ce n'était pas implanté. Je vais jeter un oeil de ce coté là, merci de l'idée.

Mieux vaut s'attendre au prévisible que d'être surpris par l'inattendu.

Répondre

Vous ne pouvez pas participer au forum, car votre inscription n'a pas été validée. Pour vous faire valider en tant que Membre, cliquez ici.

© MHN - Tous droits réservés | CNIL N°844440 | 24/11/2024 13:08:55 | Généré en 12.75ms | Contacts | Mentions légales |