JeuWeb - Crée ton jeu par navigateur
UPDATE mysql dans une boucle: alternative? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : UPDATE mysql dans une boucle: alternative? (/showthread.php?tid=5919)

Pages : 1 2 3


RE: UPDATE mysql dans une boucle: alternative? - kasou - 16-01-2012

Salut,

Si c'est juste une boucle sur les villages du joueur, tant qu'il en a pas des centaines, et que ta requête soit légère (un update d'une valeur), ce n'est pas un soucis.

Il ne faut pas se dire: "ho je boucle des requêtes, c'est super mauvais, il faut que je trouve une autre solution à tout prix", il faut regarder le contexte.

kasou


RE: UPDATE mysql dans une boucle: alternative? - nicodd - 16-01-2012

N'empèche que si une solution efficace permet de faire en une requête la même chose, pourquoi s'en priver ?
Surtout ça évite de devoir tout englober dans des transactions pour être certain d'avoir le comportement escompté.


RE: UPDATE mysql dans une boucle: alternative? - niahoo - 16-01-2012

Les transactions ça sera quand même utile. entre le moment où tu calcules les valeurs de ta requête et celui ou tu la lance, les valeurs en base de donnée peuvent avoir changé. Donc boucle ou pas, les transactions c'est sympa.

Ensuite, même d'une seule unité par village un écart d'arrondi n'est pas acceptable. sur 600 grains de blé on s'en fout un peu mais sur 3 diamants c'est autre chose.


RE: UPDATE mysql dans une boucle: alternative? - Roworll - 16-01-2012

Juste un petit exemple comme ça utilisant les tables temporaires.

Je suppose une table organisée comme suit
Table Village
Colonne JID - ID du joueur
Colonne VID - ID du Village
Colonne Res - Quantité de ressource

Lorsque des ressources sont prélevées, elle le sont comme dans l'exemple, dans l'ordre des ID de village.
On commence par enlever les ressources demandées du village 1.
S'il reste des ressources à prendre, on va chercher dans le village 2 et ainsi de suite.

L'idée est d'utiliser une combinaison de sous-requête et de table temporaire pour faire le boulot.
Je suppose ici que l'on veuille retirer 1000 ressources pour le joueur 1


UPDATE Village
INNER JOIN (
SELECT
JID,
ID,
GREATEST(Res - GREATEST(1000-(
SELECT IFNULL(SUM(Res),0)
FROM Village V2
WHERE V2.ID < V1.ID),0),0) as NewRes
FROM Village V1
WHERE JID=1) TmpRes
ON
Village.JID = TmpRes.JID AND
Village.ID = TmpRes.ID
SET Village.Res = TmpRes.NewRes;

Je fais donc un UPDATE sur la table principale.
J'effectue une jointure sur une table temporaire TmpRes, construite à la volée.
Dans cette table temporaire, j'utilise une sous-requête pour calculer le nouveau montant de ressource pour chaque village (NewRes).

Le passage via une table temporaire est nécessaire car MySQL interdit l'auto référencement direct d'une table via une sous requête lors d'un update.

Au final, tous les villages du joueur sont mis à jour en un seul passage.

[Edit]
Petite simplification de la requête


RE: UPDATE mysql dans une boucle: alternative? - niahoo - 16-01-2012

Je ne comprends pas ton code, où fais tu la récursion/boucle sur les villages suivants ?


RE: UPDATE mysql dans une boucle: alternative? - nicodd - 16-01-2012

(16-01-2012, 03:51 PM)niahoo a écrit : Les transactions ça sera quand même utile. entre le moment où tu calcules les valeurs de ta requête et celui ou tu la lance, les valeurs en base de donnée peuvent avoir changé. Donc boucle ou pas, les transactions c'est sympa.
Pourquoi aurait-on besoin de récupérer préalablement des données pour faire l'update ? Le calcul peut être fait entièrement par le moteur de base de donnée.

Sinon, effectivement cela peut poser problème selon la nature des ressources, si une fraction d'unité de cette ressource à du sens ou pas.


RE: UPDATE mysql dans une boucle: alternative? - niahoo - 16-01-2012

C'est possible, il faudrait poser tout ça pour voir, mais je me dis que pour donner les chiffres à retirer à chaque village il faut pouvoir calculer à l'avance ce qu'on va enlever. (sauf si bien sur on prends la solution d'une simple division mais ça n'a pas été retenu).

Et donc à part une procédure stockée dans ce cas là je ne vois pas comment faire sans transaction mais bon je n'ai jamais trop expérimenté avec les RDBMS


RE: UPDATE mysql dans une boucle: alternative? - Ter Rowan - 16-01-2012

ce qui m'embête quand j'entends procédure stockée c'est que du coup, on se retrouve souvent avec du code métier dans la base de données.

On n'est donc plus dans une séparation du code métier et du code bdd

typiquement dans l'exemple, la répartition de la consommation par village est un algorithme métier.

Est ce que cette optimisation vaut le coup de ce point de vue ?


RE: UPDATE mysql dans une boucle: alternative? - php_addict - 16-01-2012

(16-01-2012, 06:54 PM)Ter Rowan a écrit : Est ce que cette optimisation vaut le coup de ce point de vue ?

effectivement après vos remarques, même une 50 aine d'update ne me parait pas si lourd que ca si c'est pour des actions assez peu fréquentes


RE: UPDATE mysql dans une boucle: alternative? - niahoo - 17-01-2012

Nous y voilà Smile

Je suis plutot d'accord. Vaut voir si tu as besoin des transactions, et si oui, si ça ne coupe pas trop l'accès à la base.