28-03-2017, 02:52 PM
ça fait quoi le moral au juste pour les citoyens ?
28-03-2017, 02:52 PM
ça fait quoi le moral au juste pour les citoyens ?
28-03-2017, 02:59 PM
Hello !
@Ter Rowan : l'idée est intéressante si le champ random est actualisé par les actions utilisateurs (et après on applique ce % lors de la mise à jour globale) mais ça ne peut pas fonctionner dans le cas présent car tous les enregistrements auront la même valeur. @Metallique : d'après ce que je comprends de ce que tu souhaites, je pense que la solution de Xénos est appropriée dans ton cas car tu as besoin d'un traitement dédié à chaque enregistrement. Du coup tu es obligé de faire plein de requêtes, les passer en procédures stockées te permettra d'économiser des temps de transfert et certains calculs intermédiaires entre la base et l'application. N'étant pas très fan des procédures stockées je te propose une autre approche, pas forcément mieux mais différente. Tu dois probablement pouvoir faire un gros SELECT qui te ressort toutes les ressources disponibles ensuite c'est un problème algorithmique. Si tu connais ta population totale, tu sais combien de ressources de chaque type tu attends, il est alors facile de savoir si tout le monde est satisfait. Après je pense qu'il faut prioriser les populations à nourrir en premier. Ex : avec 40 serfs, 40 artisans et 20 bourgeois. Si tu en nourris 80, la répartition peut être 30 / 35 / 15 (-20% pour tout le monde) ou 40 / 40 / 0 (-20% pour 1/5 et +20% pour 4/5), la répartition du moral ne sera pas la même. C'est vrai que c'est assez général mais c'est une idée. Tu peux ajouter un champ aux personnages indiquant l'heure de récupération des ressources au moment de l'attribution. Ensuite tu comptes le nombre d'entre eux (par population) qui n'ont pas été mis à jour. Mais, de toutes façons, tant que tu as un rand() individuel à appliquer, tu auras forcément un update par personnage.
Keltaïnen
28-03-2017, 03:07 PM
@TerRowan
Clairement pas sur de grands jeux de données ! Après, cela peut faire une première ébauche pour les débuts. Citation :Tu dois probablement pouvoir faire un gros SELECT qui te ressort toutes les ressources disponiblesAttention aux concurrences: vu que le temps de traiement va être non négligeable (apparamment), que se passera-t-il si un joueur altère ses ressources pendant le traitement? l'altération sera perdue? Cf SELECT FOR UPDATE / LOCK IN SHARE MODE Citation : tant que tu as un rand() individuel à appliquer, tu auras forcément un update par personnage.Pas nécessairement. Là, si j'ai bien compris, l'idée est de donner de la nourriture au pif. Cela peut se faire en rajoutant une colonne (dans une temp table ou dans la table de population) indiquant la "priorité d'accès aux ressources". Cette colonne peut être alors remplie par un RAND, ou par l'utilisateur. Il suffit ensuite de faire son ORDER BY sur cette colonne pour attribuer les ressources à chaque tranche de population. Si nécessaire, une autre colonne "total de ressources déjà mangée par les autres" peut également être rajoutée. Elle vaudra alors qqc du genre UPDATE population_infos pi SET ressources_consommes_par_les_precedents = (SELECT SUM(ressources_consommes) FROM population ... WHERE population.priorite > pi.priorite). Il suffit alors de n'UPDATE que les lignes pour lesquelles ressources_consommes_par_les_precedents <= ressources_dispos.
28-03-2017, 03:13 PM
(Modification du message : 28-03-2017, 03:52 PM par Keltaïnen.
Raison de la modification: Info périmée
)
(28-03-2017, 03:07 PM)Xenos a écrit :Citation : tant que tu as un rand() individuel à appliquer, tu auras forcément un update par personnage.Pas nécessairement. Là, si j'ai bien compris, l'idée est de donner de la nourriture au pif. Cela peut se faire en rajoutant une colonne (dans une temp table ou dans la table de population) indiquant la "priorité d'accès aux ressources". Cette colonne peut être alors remplie par un RAND, ou par l'utilisateur. Il suffit ensuite de faire son ORDER BY sur cette colonne pour attribuer les ressources à chaque tranche de population. Oui mais ça ne change pas le fait qu'à un moment il faut faire un "update personnage set nimporte_quel_champ = RAND() where id = <id>" et qu'on ne peut pas se passer du "where" car le RAND() est calculé une seule fois par requête. Après on peut effectivement déporter le calcul du RAND() au niveau du joueur. Par exemple il est recalculé pour toute sa population à chaque fois qu'il se connecte. On aura alors 160 requête d'un coup (pour l'exemple donné) mais on soulagera le traitement global qui attribut les ressources. [edit] Je viens de tester sur un MySQL 5.7, le RAND() est maintenant appliqué individuellement sur chaque ligne lors d'un update donc on se casse les pieds pour rien, à ce niveau là du moins.
Keltaïnen
28-03-2017, 03:18 PM
J'ai oublié de répondre pour la concurrence.
A ce niveau là c'est vrai qu'on peut être embêté si on a un temps de traitement trop long. Si on le fait au niveau applicatif on pourra rapidement estimer pour chaque ressource s'il y en a suffisament (c'est pas long cette partie). On a ensuite 2 cas : - la ressource est insuffisante => on met la quantité à 0 - la ressource est suffisante => on retranche le nombre de personnages concernés. Et ensuite seulement on s'occupe de gérer les variations de moral qui prennent plus de temps. On peut aussi locker la table mais c'est pas super je trouve car si le traitement est lent ça va bloquer le reste. Il vaut mieux se casser la tête à le faire rapidement je pense.
Keltaïnen
28-03-2017, 03:31 PM
Nope:
28-03-2017, 03:43 PM
Ah là je dois dire que j'aime ton style ;-)
Ça reste dans ce que je disais juste avant puisque tu crées un rand() par personnage mais c'est malin de le passer dans le select pour limiter le nombre de requêtes. Bon je doute que ça tienne sur une table d'un million (vu que MySQL décroche généralement vers 10000 pour les inserts groupés) et tu as pas mal de jointures mais j'aime bien l'idée quand même car on peut quand même s'en sortir en découpant le résultat du select en plus petites portions.
Keltaïnen
28-03-2017, 04:24 PM
Non, tout dépend de la taille du buffer du serveur (et donc, de sa RAM). MySQL gère très bien les gros UPDATE de l'ordre du million de lignes, si on ne rate pas les index et qu'on lui fourni la RAM nécessaire.
28-03-2017, 04:48 PM
Allez, pour la curiosité de la chose, voici une proposition. La partie la plus problématique reste le cumulatif des ressources consommées. Ca peut certainement s'améliorer encore. 10secondes environ pour 65k lignes de population, 1k joueurs (65 populations/joueur)
28-03-2017, 05:15 PM
(Modification du message : 28-03-2017, 05:15 PM par MeTaLLiQuE.)
Je n'ai pas lu toutes vos réponses, j'y répondrai plusnen détail quand j'aurais plus de temps.
Mais 10 secondes pour 65k lignes ?! C'est énorme :/ alors que le jeu contiendra énormément plus de lignes (de population pa joueur). Je n'ai jamais utilisé de procédures stockées, alors vive ma misère ^^ |
|
Sujets apparemment similaires… | |||||
Sujet | Auteur | Réponses | Affichages | Dernier message | |
Boucle & Update - Optimisation | xanthius | 10 | 3 510 |
26-02-2017, 09:25 PM Dernier message: xanthius |
|
Incrémenter un champ avec la fonction rand() en php | Lindis | 24 | 9 597 |
01-02-2014, 11:23 PM Dernier message: Lindis |
|
UPDATE mysql dans une boucle: alternative? | php_addict | 29 | 12 298 |
18-01-2012, 12:14 AM Dernier message: php_addict |
|
[Rails] after_update, update et boucle infinie | popayan | 1 | 2 004 |
22-11-2011, 06:32 PM Dernier message: Sephi-Chan |
|
rand VS mt_rand? | Argorate | 7 | 5 790 |
29-04-2011, 10:22 AM Dernier message: Sephi-Chan |