Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 8 sur 8
  1. #1
    Invité de passage
    Homme Profil pro Matthieu Bornarel
    Étudiant
    Inscrit en
    février 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Nom : Homme Matthieu Bornarel
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : février 2012
    Messages : 16
    Points : 3
    Points
    3

    Par défaut Checkbox et SET datatype

    Bien le bonjour à toutes et tous,

    Voilà je viens vers vous car notre ami Google m'a lâché sur ce coup-là.
    Je suis actuellement en train de monter de mes petites mains un site pour une association de Jeux et j'ai un souci avec une donnée que je souhaiterais stocker/affiché, il s'agit des genres de jeux. Alors, vous allez me dire, ce n’est qu’une donnée parmi d’autres rien de bien compliqué.

    Eh bien si, je souhaite tout d’abord, pour faciliter l’utilisation par les usagers, présenter cela sous forme de checkbox pour les différents genres sachant que ça peut être, par exemple, un jeu de cartes, un jeu de stratégie ou un jeu de cartes ET de stratégie. Afin de stocker ce type de données, il était dit à de multiples reprises sur le net que le type le plus optimisé sur mysql pour ce genre de stockage (point de vue place mémoire et sécurité sur les valeurs entrantes) était le type SET (comme un ENUM mais pouvant prendre plusieurs des valeurs données). Or j’ai souffert comme un damné déjà pour réussir à obtenir dynamiquement avec une fonction php/sql les valeurs contenues dans le SET de façon à générer les checkbox cependant maintenant je bloque car :
    1. je ne vois pas comment rentrer l’info dans la base de données vu que le principe du SET est de juste stocker un binaire avec un bit pour chaque valeur du SET, et donc je ne vois pas comment faire le parallèle avec les checkbox
    2. j’ai du mal à visualiser comment je pourrais récupérer « aisément » les genres d’un jeu de façon à pouvoir gérer des affichages thématiques plus tard.


    Alors, d’aucuns diront que le plus simple serait de changer de type de stockage de l’info ou de la travailler différemment et ils n'auront peut-être pas tort, cependant j’aimerais par pure envie de savoir qu’on m’aide à trouver une solution, et ensuite que l’on me conseille sur la manière la plus optimisé de faire ça.

    J’espère avoir été clair, si jamais vous avez besoin de certains de mes codes pour expliciter certains points, n’hésitez pas à me dire ce qu’il vous faut.

    Par avance merci.

  2. #2
    Expert Confirmé Avatar de RunCodePhp
    Profil pro
    Inscrit en
    janvier 2010
    Messages
    2 964
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : janvier 2010
    Messages : 2 964
    Points : 3 676
    Points
    3 676

    Par défaut

    Salut

    Alors, d’aucuns diront que le plus simple serait de changer de type de stockage de l’info ou de la travailler différemment et ils n'auront peut-être pas tort, cependant j’aimerais par pure envie de savoir qu’on m’aide à trouver une solution, et ensuite que l’on me conseille sur la manière la plus optimisé de faire ça.
    D'après tes explications, un champ de type SET (ou ENUM) s'y prêterait mal, voir pas du tout.

    Ce que tu souhaites c'est de représenter des combinaisons, donc un ou plusieurs voire tous parmi une liste.
    Genre : bleu, vert, rouge, orange, jaune comme choix.
    Et avoir : orange
    ou : bleu, rouge, jaune
    ... etc ... toutes combinaisons possibles.

    Un champ SET (ou ENUM) est bien plus fait pour un bouton radio (coté HTML), c'est à dire 1 seul et unique choix parmi plusieurs choix (ou propositions).
    C'est radicalement pas la même chose.


    Ceci dit, faut voir si dans ton cas c'est possible, s'il n'y a pas trop de combinaisons en faite, de tricher un peu (si on peu dire), de faire en sorte qu'il y ait qu'un seul choix.
    Si on prend ton exemple : cartes, stratégie, cartes et stratégie
    On peu peu faire (insérer) ainsi : cartes, strategie, cartes_strategie
    Donc de créer les 3 combinaisons (uniques) possibles, et le tour est joué.
    Coté formulaire, il suffit de créer un groupe de boutons radios, de proposer les mêmes choix (3 ici), et 1 seul sera choisi.
    Faut voir.


    Attention, il faut bien comprendre que ce type de champs fait que les données sont figées, il sera alors très difficile (très compliqué) de les faire évoluées, comme modifier une ou plusieurs valeurs (combinaisons).
    Ceci peut être un énorme inconvénient (selon le cas).
    Ce type de champ est bon pour des données comme :
    Mr, Mme, Mlle
    ou encore Homme, Femme, Enfant
    Ce genre de données n'évolueront pour ainsi dire jamais.


    Si on perçois qu'au fil du temps cela peu évoluer, ce type de champ ne sera pas adapté.
    Il serait nettement mieux de le faire proprement, c'est à dire de créer une table "activites" par exemple et d'insérer tous les type d'activité.
    Exemple :
    table "activites"
    activite_id | nom
    (liste des activites)

    table "activites_usagers"
    usagers_id | activites_id
    (liste des associations/combinaisons des activites des usagers)

    Ici, le nom de l'activité à (presque) aucune importance car le principe du fonctionnement repose sur des identifiants (donc jointures de tables, etc ...).


    Tout cela sauf erreur (comme d'hab)
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  3. #3
    Expert Confirmé Avatar de RunCodePhp
    Profil pro
    Inscrit en
    janvier 2010
    Messages
    2 964
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : janvier 2010
    Messages : 2 964
    Points : 3 676
    Points
    3 676

    Par défaut

    Citation Envoyé par RunCodePhp
    Tout cela sauf erreur (comme d'hab)
    Il me semble avoir dit une bêtise.

    Dans la doc de MySQL on peu voir ceci pour champ de type SET :
    La doc : Le type SET
    FIND_IN_SET() :

    mysql> SELECT * FROM nom_de_table WHERE set_col LIKE '%value%';
    mysql> SELECT * FROM nom_de_table WHERE FIND_IN_SET('value',set_col)>0;

    Mais ce qui suit fonctionnera aussi :

    mysql> SELECT * FROM nom_de_table WHERE set_col = 'val1,val2';
    mysql> SELECT * FROM nom_de_table WHERE set_col & 1;
    Donc la différence entre le type Enum et SET, c'est que le type ENUM permet d'insérer qu'un seul ET unique choix parmi plusieurs mais le type SET permet d'insérer plusieurs choix (théoriquement tous) parmi plusieurs.

    On peu alors insérer comme ceci :
    Code :
    1
    2
    INSERT INTO usagers (usagers_id, activites)
    VALUES (10, 'bleu,vert,jaune')

    je ne vois pas comment rentrer l’info dans la base de données vu que le principe du SET est de juste stocker un binaire avec un bit pour chaque valeur du SET, et donc je ne vois pas comment faire le parallèle avec les checkbox
    Normalement non, rien obligerait à stocker un binaire.
    C'est comme le champ ENUM, on insère une chaine séparée par une virgule des différents choix possibles à la création du champ :
    Exemple : bleu, vert, rouge, orange, jaune
    Après on insère les différentes combinaisons qu'on aura récupéré, une chaine séparé par une virgule (exemple plus haut).

    Ce qui fait qu'à la récupération de la donnée, ce sera aussi une chaine séparée par une virgule s'il y a plusieurs choix d'effectués.
    Un simple explode() en Php suffit pour obtenir un tableau des différents choix.


    J'espère cette fois ne pas dire trop de bêtises.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  4. #4
    Invité de passage
    Homme Profil pro Matthieu Bornarel
    Étudiant
    Inscrit en
    février 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Nom : Homme Matthieu Bornarel
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : février 2012
    Messages : 16
    Points : 3
    Points
    3

    Par défaut

    Tout d'abord, merci pour tes réponses

    Ensuite, pour le champs SET, j'avais déjà lu la doc et c'est justement ce qui m'avait conforté dans les différentes infos trouvées sur les autres forums, autrement dit que l'on pouvait stocker un élément du SET ou une combinaison de ceux-ci. Pour ce qui est du stockage en binaire dont je parle, c'est parce que sur ces fameux site/forum où j'ai entendu parler de SET, ils disaient que le stockage se faisait sous forme indexé, exemple:

    un set défini tel que: set('carte',strategie','plateau'); sera fait l'association: 'carte'=00000001, 'strategie'=00000010, 'plateau'=00000100; ensuite la donnée 'carte' sera stocké sous la forme: 00000001, quant à la combinaison carte+plateau ce serai: 00000101.

    Après, si ce que tu dis sur le fait de rentrer une chaine avec des virgules, j'avoue que ça simplifierai bien les choses, je vais tenter de faire un test de suite après ce post ^^

    Enfin, pour récupérer les valeurs des checkbox, qui sont comme on peut s'en douter dans un formulaire, j'utilise un tableau de checkbox, donc obtenir la chaine devrai pas être compliqué avec
    Code :
    $chaine=implode(', ', $montableau)
    cependant dans la fonction de mise à jour de ma table je me contente de mettre $chaine dans mon UPDATE au niveau du champs des genre de jeux ou je dois faire une manip alambiquée?

  5. #5
    Invité de passage
    Homme Profil pro Matthieu Bornarel
    Étudiant
    Inscrit en
    février 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Nom : Homme Matthieu Bornarel
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : février 2012
    Messages : 16
    Points : 3
    Points
    3

    Par défaut

    Alors bonne nouvelle, en effet ça à l'aire de prendre les chaines de caractères. Dans le code ci-après permettant l'action de mon formulaire (pour les valeurs des checkbox et ce qui s'y rapporte, il faut suivre la variable $type) j'arrive à obtenir une chaine de caractère cohérente (par exemple: carte, plateau) cependant seul le premier mot (ici 'carte') est pris par la base de données...

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    				if (isset($_POST['nom_jeu']) AND isset($_POST['description_jeu']) AND isset($_POST['nombre_joueur']) AND isset($_POST['temps_moyen']) AND isset($_POST['type']) AND isset($_POST['disponibilite']) )
    				{
    					$nom_jeu = addslashes($_POST['nom_jeu']);
    					$description_jeu = addslashes($_POST['description_jeu']);
    					$nombre_joueur = addslashes($_POST['nombre_joueur']);
    					$temps_moyen = addslashes($_POST['temps_moyen']);
    					$note = addslashes($_POST['note']);
    					$type=$_POST['type'];
    					$type=implode(', ', $type);
    					echo $type;
    					$disponibilite = addslashes($_POST['disponibilite']);
    					$id_visuel = addslashes($_POST['id_visuel']);
    					// On vérifie si c'est une modification d'un jeu ou pas
    					if ($_POST['id'] == 0)
    					{
    						// Ce n'est pas une modification, on crée une nouvelle entrée dans la table
    						mysql_query("INSERT INTO jeux VALUES('" . $nom_jeu . "', '" . $description_jeu . "', '" . $nombre_joueur . "', '" . $temps_moyen . "', '" . $note . "', '". $type ."', '" . $disponibilite . "', '" . $id_visuel . "', '')");
    					}
    					else
    					{
    						// On protège la variable "id" pour éviter une faille SQL
    						$_POST['id'] = addslashes($_POST['id']);
    						// C'est une modification, on met à jour l'affichage
    						mysql_query("UPDATE jeux SET nom_jeux='" . $nom_jeu . "', description_jeu='" . $description_jeu . "', nombre_joueur='" . $nombre_joueur . "', temps_moyen='" . $temps_moyen . "', note='" . $note . "', type='" . $type . "', disponibilite='" . $disponibilite . "', id_visuel='" . $id_visuel . "' WHERE id='" . $_POST['id'] . "'");
    					}
    				}
    Par la suite j'ai essayé d'autre implode pour voir si cela pouvait venir de la formulation de la chaine de caractère mais pour tout ceux ci-après, je n'ai même plus l'entré qui ce fait dans la BDD...

    Code :
    1
    2
    3
    4
    5
    $type='\''. implode(', ', $type).'\''	génère $type='carte, plateau'
    $type='\''. implode(',', $type).'\''	génère $type='carte,plateau'
    $type='\''. implode('\',\'', $type).'\''	génère $type='carte','plateau'
    $type='\''. implode('\', \'', $type).'\''	génère $type='carte', 'plateau'
    $type='"\''. implode('\',\'', $type).'\'"'	génère $type="'carte','plateau'"

  6. #6
    Expert Confirmé Avatar de RunCodePhp
    Profil pro
    Inscrit en
    janvier 2010
    Messages
    2 964
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : janvier 2010
    Messages : 2 964
    Points : 3 676
    Points
    3 676

    Par défaut

    Code :
    if (isset($_POST['nom_jeu']) AND isset($_POST['description_jeu']) AND isset($_POST['nombre_joueur']) AND isset($_POST['temps_moyen']) AND isset($_POST['type']) AND isset($_POST['disponibilite']) )
    La fonction isset() accepte n éléments, ce qui éviter les répétitions de code inutiles.
    La doc : isset()

    Exemple :
    Code :
    1
    2
    3
    if (isset($_POST['nom_jeu'], $_POST['description_jeu'], $_POST['nombre_joueur'], $_POST['temps_moyen'], $_POST['type'], $_POST['disponibilite'], $_POST['disponibilite'])) {
        // ... etc ...
    }
    Aussi, il ne faut pas utiliser addslashes(), mais dans ton cas : mysql_real_escape_string().
    Cette fonction est dédiée pour cela : échapper la chaine et éviter une éventuelle injection SQL.
    La doc : http://fr2.php.net/manual/fr/functio...ape-string.php
    Exemple :
    Code :
    $nom_jeu = mysql_real_escape_string($_POST['nom_jeu']);
    Code :
    $_POST['id'] = addslashes($_POST['id']);
    Et lorsque qu'un type de donnée DOIT être un identifiant (donc 1, 10, 200, etc ...), c'est nettement plus efficace de caster (ou typer) la donné que de l'échapper.



    J'ai commis une erreur dans l'exemple de code que j'ai mis pour l'insertion.
    Il ne faut pas mettre d'espace entre chaque valeur.
    En rectifiant :
    Code :
    1
    2
    INSERT INTO usagers (usagers_id, activites)
    VALUES (10, 'bleu,vert,jaune')
    Au niveau de ton code ça donnerait ceci :
    Code :
    1
    2
    3
    $type = $_POST['type'];
    $type = implode(',', $type);
    $type = mysql_real_escape_string($type);
    Qu'est-ce qui te pousses à utiliser un type SET au lieu de concevoir cela plus proprement, comme l'exemple que j'avais donné, c'est à dire avec 2 tables (tables des activités et tables des associations des activités des usagers).

    En faite, perçois tu que la gestion de ces types sera plus facile à gérer avec cette solution ci-dessus qu'avec un champ de type SET ?
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

  7. #7
    Invité de passage
    Homme Profil pro Matthieu Bornarel
    Étudiant
    Inscrit en
    février 2012
    Messages
    16
    Détails du profil
    Informations personnelles :
    Nom : Homme Matthieu Bornarel
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : février 2012
    Messages : 16
    Points : 3
    Points
    3

    Par défaut

    Yataaaa !!!

    Merci beaucoup, grâce à ton dernier post j'ai fais de super modif entre le "mysql_real_escape_string" et la factorisation du "isset" (pour laquelle je m'en veux atrocement de pas y avoir penser tout seul ...). Quant à ce code avec le "implode" marche niquel et les entrées ce font parfaitement!

    Après pour répondre à tes questions, la première chose qui m'a fait utiliser le SET est, comme je le dis depuis le début, tout simplement le fait que j'ai vu un peu partout que c'était le type le plus optimisé pour stocker les données tel que je souhaiter le faire.

    Ensuite, maintenant que j'y vois plus clair sur son fonctionnement et que tu m'as éclairer sur comment le manipulé, je suis conforté dans l'idée que c'est le bon type de données même s'il est pas du plus aisé pour l'utiliser, de plus tel les ENUM je trouve ça plus sécuritaire de passer par un typage n'autorisant que certaine valeur.

    Enfin, je ne passe pas par une autre table tout simplement car ça me ferai juste créer une table avec les genre de jeux et leurs id que je devrait linkerai avec mon autre table des jeux et même si c'est plus facilement manipulable dans le code je trouve que c'est du gaspillage d'espace, mais bon après c'est ma vision des choses et je peux parfaitement comprendre qu'on soit pas de mon avis sur ce point. ^^

    Et juste pour éclairage personnel, en fait ce que je fais, n'associe pas des activités à des usagers, mais sert à un formulaire permettant à des gens de créer des fiches de descriptions correspondant à des jeux de société.

    En tout, encore merci beaucoup, tu m'as bien aidé, bonne continuation

  8. #8
    Expert Confirmé Avatar de RunCodePhp
    Profil pro
    Inscrit en
    janvier 2010
    Messages
    2 964
    Détails du profil
    Informations personnelles :
    Localisation : Réunion

    Informations forums :
    Inscription : janvier 2010
    Messages : 2 964
    Points : 3 676
    Points
    3 676

    Par défaut

    Enfin, je ne passe pas par une autre table tout simplement car ça me ferai juste créer une table avec les genre de jeux et leurs id que je devrait linkerai avec mon autre table des jeux et même si c'est plus facilement manipulable dans le code je trouve que c'est du gaspillage d'espace, mais bon après c'est ma vision des choses et je peux parfaitement comprendre qu'on soit pas de mon avis sur ce point. ^^
    Pour ma part ce sont des idées reçues.
    Il est prouvé nulle part que le nombre de table fasse chuter les performances, dans bien des cas ce sera au contraire plus performant.
    Une Bdd c'est fait pour ça, les jointures de tables sont là pour ça, tout repose là dessus.

    C'est aussi fait pour gérer des données, et en grande quantité.
    Si demain tu dois par exemple renommer un des choix listé dans le SET, ça peut être la croix et la bannière.
    Mais c'est pas sûr, qu'on s'entende bien.


    Maintenant, il est vrai aussi que créer une Bdd en respectant 100% "l'art et la manière" de la concevoir, ça peu faire chuter les performances.
    Mais encore faut il en être certain.


    A coté de ça, si ce type de champ te conviens, et bien il n'y a pas de raison de faire autrement.
    Faut juste éviter les mauvaises raisons, si on peu dire.
    Win XP | WampServer 2.2d | Apache 2.2.21 | Php 5.3.10 | MySQL 5.5.20
    Si debugger, c'est supprimer des bugs, alors programmer ne peut être que les ajouter [Edsger Dijkstra]

+ Répondre à la discussion
Cette discussion est résolue.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •