JeuWeb - Crée ton jeu par navigateur
Aide dans une requetes - 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 : Aide dans une requetes (/showthread.php?tid=3284)

Pages : 1 2 3 4 5


RE: Aide dans une requetes - Jeckel - 14-12-2010

Pour le coup du hash, ce n'est utile que pour des données critiques, et en général sur la table utilisateur uniquement. (où autre s'il y a d'autres tables "critiques")

En select, on en a rarement besoin en général, un vérifie le hash uniquement lorsque l'utilisateur se connecte pour être sûr qu'un indésirable n'est pas venu modifier le mot de passe (pour pouvoir se connecter avec son compte) ou le profil de l'utilisateur (pour obtenir des droits plus importants).

Ensuite, ça peut se faire directement dans la requête :


-- vérification en select :
SELECT * FROM utilisateur WHERE login = 'jeckel' AND MD5(CONCAT(login, password, profil, "MA_GRAINE")) = mon_hash;

-- En mise à jour :
UPDATE utilisateur
SET password = "mot_de_passe_crypté", profil = "id_profil",
mon_hash = MD5(CONCAT("jeckel", "mot_de_passe_crypté", "id_profil", "MA_GRAINE"))
WHERE login = 'jeckel';

Donc, comme tu vois, pas de requête supplémentaire, juste une requête un peu plus complexe. Là c'est un exemple où, si le hash est faux, alors l'utilisateur ne remonte pas, mais tu peux très bien mettre la vérification au niveau du select pour remonter l'info sous la forme d'un flag vrai/faux pour pouvoir mettre en place un traitement alternatif adéquat (envoie d'un mail à l'administrateur comme quoi un compte semble avoir été modifié par une mauvaise source)

C'est un principe que j'ai utilisé lors de développement d'application bancaire pour lesquelles l'accès aux données n'étaient pas critique (tout le monde peut les voir) mais pour lesquels il fallait être sûre qu'elle n'aient pas été altérée par une source différente.

Petite précision, la graine (chaîne "MA_GRAINE" rajouté dans le CONCAT) ne doit pas être stockée dans la base de donnée, mais uniquement dans le code PHP.


RE: Aide dans une requetes - christouphe - 14-12-2010

j'ai le même problème que toi Nico, je suis en train de voir si je peux pas aussi mettre des informations dans des fichiers, pour le moment, j'ai réussi à travailler un maximum dans la session avec des flags de mise à jour sur les objet vitaux, mais bon je pense que pour certaines page dont le contenu change peu, je passerai par un chargement de fichier afin d'alléger le nombre de requêtes, par contre mon maximum est de 9 requêtes pour une unité complètement équipée (2 armes différentes + armure + équipement divers). Et je trouve que ça fait déjà beaucoup :p


RE: Aide dans une requetes - Myrina - 14-12-2010

@Nico & christouphe: sur l'ensemble de vos requêtes, il y a en a combien qui concerne des tables de références qui changent jamais ou presque?
Le contenu de ces tables peut facilement être mis en cache (tableau d'occurrences issu d'un fichier ou de la session); il faut par contre revoir la manière d'accéder à l'information. J'ai mis en place en mécanisme qui n'est certainement pas le top (par rapport à un ORM) mais qui rend les services nécessaires pour les tables de référence.


RE: Aide dans une requetes - Jeckel - 14-12-2010

(14-12-2010, 02:14 PM)NicoMSEvent a écrit : @Jeckel: Il en résulte que je passe de +-30 requetes (en sélection) par page (en procédural) à +-200 (en POO) parce qu'il y a de nombreux objets dont je n'ai pas besoin qui se rechargent (c'est peut-etre une mauvaise gestion de ma part).
Ca c'est le gros problème de la POO, réussir à gérer correctement le chargement chainé des objets.

Si tu veux, je peux te donner quelques astuces... mais autant créer un sujet dédié... Wink


RE: Aide dans une requetes - NicoMSEvent - 14-12-2010

@christouphe: tu n'affiche jamais plus d'une unité à la fois? pas de terrain? pas de vérification sur l'utilisateur? ni sur les éventuels nouveaux messages dans la messagerie? pas de pnj avec d'éventuelles quetes? tout cela à un cout, et c'est l'accumulation des objets que j'affiche sur une page qui me crée autant de requetes.

Même quand je recharge un morceau via AJAX, il faut que je reconstruise un contexte minimum
par exemple :mon perso, type de case sur laquelle il est (pour voir voir les actions selon le type de terrain ou le magasin dans lequel on est) et les autres éléments sur cette même case (joueurs et PNJ), uniquement pour rafraichir le "petit" cadre à droite qui détermine quelles sont les actions possibles sur la case sur laquelle on est.

@Jeckel: J'avais mal compris, j'imaginais que tu faisais une vérification sur chaque select (toutes les tables).
Il est vrai que ça apporte un plus non négligeable pour la cohérence des données, mais pas utile a mon sens (a moins que je ne vire en mode "parano", ce qui pourrait être le cas vu ma bi-polarité ^^)

@blingcru2: Tu vois, même les programmeurs expérimentés savent reconnaitre qu'ils ne connaissent pas tout. Le principe de l'apprentissage est la remise en question constante de ce qu'on croit savoir. Il faut savoir le faire humblement Wink


Le sage à dit : la seule constance dans le monde de l'informatique est le perpétuel changement.


RE: Aide dans une requetes - christouphe - 14-12-2010

:wowowow::wowowow:

Big Grin

je veux Wink (popur le sujet dédié)

@Nico: pour les 9 requêtes, c'est le descriptif d'une unité, pour l'instant la map n'est pas totalement faite.


RE: Aide dans une requetes - Myrina - 14-12-2010

@Nico: si je comprend bien, une partie de tes soucis de requêtes provient du nombre d'objets différents que tu affiches à chaque fois. Ne peux-tu pas mettre en place un mécanisme de détection de changement des infos?
Comme cela, tu récupères tes informations une première fois avec une codification de l'état des objets (TIMESTAMP du select, ou dernier ID crée par exemple). Puis les fois suivantes, tu invoques un select (ou une procédure stockée si la détection est plus complexe) avec la codification en entrée qui renvoie un booléen précisant si tu dois recharger ou non les informations récupérées la première fois, et ceci à chaque fois.


RE: Aide dans une requetes - Jeckel - 14-12-2010

@Nico : A mon avis il y a deux cas...

Premier cas, tu as des requêtes exécutées en double, par exemple un même objet lié à deux endroits différents et que tu charges du coup deux fois... par exemple si tu as une liste de joueurs, pour chaque joueur une race, et quand tu affiches la liste des joueurs, pour chacun d'eux il va chercher les informations sur la race en base... (cas des tables de refs).

Dans ce cas, une solution c'est d'avoir un objet unique (singleton) par lequel passent toutes les demandes pour obtenir la race, exemple rapide :

class RaceSingleton {
protected $_races = array();

private function __construct() {
// ici chargement de la liste des races (unique requête SQL)
$this->_races = foo();
}

static public function getInstance()
{
static $instance = null;
if (is_null($instance)) {
$instance = new self();
}
return $instance;
}

public function getRace($id)
{
return $this->_races[$id];
}
}

Et ensuite pour l'utiliser :

$infoRace1 = RaceSingleton::getInstance()->getRace(1);
$infoRace2 = RaceSingleton::getInstance()->getRace(2);

Le premier appel va créer l'instance car elle n'existe pas encore, et charger la liste des races, puis retourne la race voulue (1).
Le second appel ne fait plus que retourner la race voulue (2).

Le second cas, c'est une histoire de cache, trop de données rechargées à chaque fois alors qu'elles ne sont pas modifiées, c'est qu'explique Myrina
Hop, je rajoute que du coup, dans ton objet Joueur, ça peut donner ça :

class Joueur
{
...
protected $_race_id;

public function getRace()
{
return RaceSingleton::getInstance()->getRace($this->_race_id);
}
...
}



RE: Aide dans une requetes - christouphe - 14-12-2010

cela ne vaut que si les appels se font dans le mêm script, car les objets sont détruits en fin de script, non ?


RE: Aide dans une requetes - Jeckel - 14-12-2010

Pour ce cas là oui, mais ça permet déjà souvent de réduire fortement le nombre de requêtes...

Ensuite, la fonction foo() tu lui fait faire ce que tu veux... si tu veux aller chercher en base, ou dans un fichier de cache, c'est comme tu veux. Par contre, pour une table de ref, y a pas grand intérêt à stocker dans un fichier, jusqu'à une centaine d'enregistrement (sans doute plus même) il est en général plus rapide de charger les infos depuis la base de données que de passer par le chargement d'un fichier de cache.

Enfin ça c'est très variable... est-ce que la BDD est sur le même serveur ou pas ? est-ce que le serveur de BDD est mutualisé ou pas ? toute sorte de paramètres qui vont avoir un impacte sur les perfs. Mais sur une seule table, sans jointure, autant charger directement depuis la base.

Ce qui peut-être plus intéressant à mettre dans un cache ce sont des objets plus complexes et lourds à charger et qui ne se modifie pas systématiquement.

Pour la gestion d'un cache, on peut partir du même principe : une seule fonction de chargement qui charge l'objet (et tout ce qui va avec) une première fois, et le stocke ensuite dans un fichier. Au second appel, on vérifie si le fichier existe, si oui, on charge depuis le fichier, sinon on recharge depuis la base.
Enfin, à chaque fois qu'il y a une modification qui impacte l'objet en question, on supprime simplement le fichier en question (pour qu'au prochain appel, il recharge la version à jour depuis la base).

Mais il existe de nombreux outils de gestion de cache très performant.

Personnellement, je travaille avec Zend_Cache : http://framework.zend.com/manual/fr/zend.cache.introduction.html
C'est un peu complexe à utiliser la première fois, mais ensuite c'est très performant. Mais il en existe d'autres...