IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Schéma Discussion :

Optimisation : nombre de colonnes


Sujet :

Schéma

  1. #1
    Membre régulier Avatar de Lost In Translation
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    166
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 166
    Points : 89
    Points
    89
    Par défaut Optimisation : nombre de colonnes
    Bonjour,

    J'ai regardé dans la FAQ et ai pu lire qu'on pouvait avoir environ 2000 colonnes dans une table.

    Ma question va sembler un peu bête, mais vaut-il mieux travailler sur une "table gigantesque" ou sur des "petites tables"

    Par exemple... On pourrait faire une table gigantesque qui représente "toutes" les données d'un humain : son nom, prénom, date de naissance... date de vaccin pour le machin... taille de son petit orteil...

    Mais on pourrait aussi surement découper toutes ses données en famille et donc en table :
    - identité (nom prénom, lieu de naissance...)
    - physique (couleur de peau, des yeux, des cheveux...)

    Qu'elle est la manière la plus "judicieuse" et la plus légère pour MySQL ?

    Intuitivement, je suppose qu'il vaut mieux faire 1 seule requête en sélectionnant les champs qui nous intéressent... que de faire des tonnes de INNER JOIN pour obtenir la totalité des informations.

    Mais j'aimerais en avoir confirmation si possible. Merci


    EDIT à 16h27 :

    En fait, j'aimerais décortiquer mon problème.

    Par exemple, sur la tonne d'infos d'un "Humain" je n'ai pas besoin de toutes les colonnes tout le temps ? Par exemple, je n'ai besoin de son age, de son poids, son lieu de naissance que quand j'affiche sa "carte d'identité". Est-il plus judicieux de séparer les données en plusieurs petites tables ?

  2. #2
    Expert éminent
    Avatar de qi130
    Homme Profil pro
    Expert Processus IT
    Inscrit en
    Mars 2003
    Messages
    3 913
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Expert Processus IT
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2003
    Messages : 3 913
    Points : 6 032
    Points
    6 032
    Par défaut
    Utilise plutôt des petites tables et des clés étrangères...

    Sinon, et pour ne prendre que la couleur des yeux, tu vas stocker "bleue" chaque fois qu'une personne a les yeux bleus, alors qu'il est préférable de stocker la clé de la table "COULEUR_DES_YEUX" pointant sur la couleur bleue.

    Exemple de cette table:
    1 -> bleue
    2 -> marron
    3 -> noire
    etc...
    On voit tout de suite l'économie de place
    Même remarque pour la nationalité et toutes les autres caractéristiques de même nature.

    Recherche sur DVP les posts de fsmrel. il explique celà beaucoup plus académiquement que moi

  3. #3
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Commençons par distinguer deux cas :
    1) Les informations à caractère unique
    Par exemple, la date de naissance est une caractéristique unique.

    2) Les informations pouvant être multiples
    Tu as cité le cas des vaccins. Un être humain subit généralement plusieurs vaccins au cours de sa vie.

    Les informations à caractère unique peuvent figurer dans la table "humain".
    Les informations multiples doivent figurer dans une table séparée et associée à la table "humain".

    Mais fsmrel, cité par qi130, te dirait aussi que si des informations uniques peuvent ne pas être connues, il faut aussi les séparer de la table "humain" pour éviter l'envahissement de cette table par des cohortes de bonshommes NULL.

    On en arrive à un principe qui fonctionne :
    Les informations à caractère unique et qui sont obligatoires figureront dans la table des humains. Les autres seront préférentiellement séparées. fsmrel serait plus catégorique que moi sur ce dernier point.

    J'ai par exemple une table d'artistes dans ma BDD consacrée à ma documentation de cinéma dans laquelle figure la date de décès et qui est autorisée à NULL puisque tous les artistes de ma table ne sont pas morts. Ça ne m'apporterait pas grand chose de séparer cette date fatidique dans une table séparée.

    Si tu as beaucoup de caractéristiques facultatives et/ou multiples, tu peux créer une table des caractéristiques et l'associer à la table des humains.

    MCD :
    humain -0,n----Avoir----0,n- caracteristique

    Tables : (exemple)
    humain (hmn_id, hmn_nom, hmn_prenom_usuel, hmn_sexe, hmn_date_naissance...)
    caracteristique (ctq_id, ctq_libelle, ctq_type_valeur, ctq_unique...)
    hmn_avoir_ctq (hac_id_caracteristique, hac_id_humain, hac_numero, hac_valeur)

    ctq_type_valeur indique s'il s'agit d'un nombre ou d'un texte.
    ctq_unique est un booléen indiquant si la caractéristique est à caractère unique ou non.
    hac_numero est pour autoriser les caractéristiques multiples (les vaccins).

    À adapter à ton cas réel.

  4. #4
    Membre régulier Avatar de Lost In Translation
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    166
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 166
    Points : 89
    Points
    89
    Par défaut
    J'ai préféré faire une image via MySQL Workbench.

    J'ai séparé "les colonnes à contenus statiques"... C'est à dire que des attributs dont les valeurs sont statiques (1 résultat parmi N choix) je les ai externalisés.

    Mais après, il y a comme je disais, toute la pléiades d'attributs qui :
    - peuvent être groupés en famille et donc mis dans des tables (exemple dans le cadre orange)
    - restent dans la même table (cadre bleu).

    Quel modèle semble être le "plus optimisé", le "moins lourd" et le plus "maintenable" (je ne pense pas que ça se dise... j'entends par là "qui est facile à gérer" ^^).




    EDIT : Nos messages se sont croisés (même avec 30 minutes d'écart, je n'ai pas rafraichi avant envoi ^^).

    C'est effectivement ce que j'avais fait la première fois.
    Cela me forçait par contre à faire souvent des jointures.

    Ca ne me pose pas de soucis de faire des jointures. Mais je voulais savoir si cela était "vraiment très lourd" (genre 30% de requêtes avec Jointure) ou si au final "on s'en fout" ?

  5. #5
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Il est clair que les colonnes HMN_CARPHY* en pagaille, ce n'est pas bon !

    Les tables T_CARPHY et T_CARMENT ne vont pas non plus puisqu'elles ont également des colonnes répétitives.

    Je verrais plutôt un modèle de ce genre :
    Humain -1,n----Avoir----0,n- Caractéristique -0,n----Autoriser----(1,1)- Valeur_possible

    Ce qui donnerait les tables suivantes :
    te_humain_hmn (hmn_id, hmn_nom, hmn_prenom...)
    te_caracteristique_ctq (ctq_id, ctq_libelle, ctq_type_valeur, ctq_unique)
    te_valeur_possible_vps (vp_id_caracteristique, vp_numero, vp_valeur)
    tj_hmn_avoir_ctq (hac_id_humain, hac_id_caracteristique, hac_numero, hac_valeur)

    Il faudra prévoir des triggers pour interdire plusieurs couples {hac_id_humain, hac_id_caracteristique} si la caractéristique est à caractère unique et pour vérifier que les valeurs renseignées font bien partie des valeurs possibles.

    En terme de données, ça donnerait par exemple ceci :
    te_humain_hmn (hmn_id, hmn_nom, hmn_prenom...)
    1, 'Leménager', 'Philippe'

    te_caracteristique_ctq (ctq_id, ctq_libelle, ctq_type_valeur, ctq_unique)
    1, 'Couleur des yeux', 'Entier', TRUE

    te_valeur_possible_vps (vp_id_caracteristique, vp_numero, vp_valeur)
    1, 1, 'Bleus'
    1, 2, 'Verts'
    1, 3, 'Marrons'
    1, 4, 'Gris'
    1, 5, 'Noirs'
    1, 6, 'Vairons'

    tj_hmn_avoir_ctq (hac_id_humain, hac_id_caracteristique, hac_numero, hac_valeur)
    1, 1, 1, '1'

    Le dernier 1 est entre apostrophes parce que comme la colonne peut aussi accueillir des données textuelles, sont type sera VARCHAR.

    Ce modèle est peut-être améliorable mais je pense qu'il fonctionne, à condition de prévoir les triggers permettant de valider les données et empêcher que j'aie les yeux à la fois bleus et marrons ou avec une valeur incompatible (Européen par exemple).

  6. #6
    Membre régulier Avatar de Lost In Translation
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    166
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 166
    Points : 89
    Points
    89
    Par défaut
    Je sentais le moment venir où il faudrait que je change ma couche !

    Mes connaissances en base de données sont relativement "scolaires" pour ne pas dire relevant de l'autodidaxie. J'avoue sans honte n'avoir jamais eu besoin d'utiliser de trigger de toute ma vie.

    Je sens le moment poindre où ma réponse va être "ce n'est que pour une petite application sans prétention en PHP/MySql" où les données sont contrôlées avant insertion par un... ben controller (modèle MVC).

    Il est donc formellement impossible (et j'insiste sur l'impossibilité - hors bug hein ^^ - ) qu'une donnée insérée soit "fausse". Du coup, quid de l'utilisation d'un Trigger dans ce genre d'application ? Je ne m'y connais pas assez pour dire "j'en ai besoin/pas besoin". Mais de mémoire, je n'ai pas souvenir que des applications du même type sur lesquelles j'ai pu collaborer utilisaient des triggers. Mais ça, c'est ma faute, si je m'exprimais clairement depuis le début, j'aurais peut être directement posé le schéma sur lequel j'ai des questionnements :s

    Je crois que je m'enfonce avec mon idée de "l'humain" que je ne maitrise pas tant que ça. Épris d'une sorte de "honte" d'avouer la réelle teneur de l'application qui est en fait "un jeu" : je me disais que peut être vous considèreriez avec moins d'intérêt mon questionnement s'il tenait de l'oisif.

    Mais bon, je me lance. J'essaye de refaire toute la base de données d'un jeu (php/mysql) que j'ai conçu il y a quelques années. Hier, je me suis intéressé au convention de nommage (grâce à l'article de SQLPro)...

    Et j'aimerais vraiment avoir une base de données qui "ait de la gueule". Surtout pour progresser dans le domaine...

    Je vous joins le dernier MCD en date que j'ai fais... (la BDD a un peu évolué depuis, mais bon, la fonction d'import d'un script sql vers mysql workbench semble bugguer un peu encore...)



    J'ai déjà prévu de tout renommer avec la norme =)
    Mais sur ce schéma : obtenir toutes les informations d'un personnage revient à faire une requête sur plusieurs tables ou "plusieurs petites requêtes".

    La question était "ne serait-ce pas mieux" si tout ce qui a un rapport avec le personnage était dans la même table.

    Au vu de ce que vous me dites, j'ai l'impression que ce schéma n'est "pas si mal" vu que vous me conseiller de grouper les attributs dans des tables...

  7. #7
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Pourquoi dénigrerais-je un jeu ?
    Je joue moi-même tous les jours à Swing.

    Après un coup d'oeil rapide, je dirais qu'effectivement, ce schéma n'est pas mal.
    Et comme tu as des associations de type (0,n---0,n), tu ne peux pas mettre tout dans une seule table.

    Essaie le principe que j'ai donné dans mon précédent message : si des attributs sont facultatifs, sors les de la table des personnages pour éventuellement les regrouper par familles.

  8. #8
    Membre régulier Avatar de Lost In Translation
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    166
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 166
    Points : 89
    Points
    89
    Par défaut
    Pourquoi dénigrerais-je un jeu ?
    Je joue moi-même tous les jours à Swing.
    J'adore ce jeu ! Très très longtemps j'y ai joué en escouade... Jusqu'à ce qu'elle disparaisse. Mais ce jeu "seul" n'a pas grand intérêt ! J'vais quand même y jeter un oeil, ça fait longtemps ♥

    Je vais essayer de faire un nouveau modèle (par contre, ce sera à priori un MPD car Mysql Workbench ne gère pas la couche conceptuelle) et le soumettrais pour voir si vous avez quelques conseils d'optimisation à me fournir.

    Merci =)

  9. #9
    Membre régulier Avatar de Lost In Translation
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    166
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mai 2007
    Messages : 166
    Points : 89
    Points
    89
    Par défaut
    Je viens d'avancer dans la nouvelle version de mon MCD (qui est en fait un MPD )

    Je vous mets un lien externe vers l'image PNG, elle est trop grand pour s'afficher correctement.

    Je n'ai pas saisi tous les attributs, mais je pense pouvoir déjà en parler plus clairement et donc confronter mes idées à vos remarques et conseils.

    Je suis parti du principe que "tout" a des caractéristiques et qu'au final, il est très dur de définir un nombre "fini" de caractéristiques surtout dans une application qui se veut évolutive.

    La position d'un personnage sur une carte, celle d'un objet, la couleur d'un bâtiment... Tout ça répond aux mêmes critères : Une clé, une valeur.

    Chaque caractéristique peut être décrite : un nom (position, couleur...), une description, un type... C'est ce que j'ai voulu modéliser par une table T_ATTRIBUT

    Je suis donc parti de cette idée.

    Petit commentaire pour vous expliquer ce que j'essaie d'exprimer dans ce schéma.

    Un être humain (vous, moi) s'inscrit sur le jeu pour y posséder un seul et unique compte (il faudra que je fasse quelques restrictions sur les adresses IP, et tout... mais c'est tellement contournable de nos jours ). Le compte d'un joueur est identifié par un ID unique et aussi par son adresse email (peut être rajouter un INDEX UNIQUE sur l'attribut email ?).

    Chaque compte peut avoir 0 ou N personnage (max N = 2).

    Un personnage arrive avec 1 identité de base mais pourra en "acquérir" plusieurs dans le temps. En se déguisant par exemple (Edmond Dantès / Comte de Monte Christo ou Bruce Wayne / Batman... j'espère ne pas spoiler :p)...

    Chaque identité va répondre à des caractéristiques du genre état civil : nom prénom, couleur des yeux, des cheveux.

    Indépendant de son identité à un moment T, un personnage a des caractéristiques plus ou moins "invariables" (qui vont progresser à force de travail, mais qui ne peuvent pas être simulée ou feinte) : la notion de force, d'intelligence, de dextérité...

    Toujours indépendamment de ça le personnage peut posséder plusieurs classes. La classe est une notion de jeu de rôle qui représente un métier/une vocation... Si on prend Batman, il est "bi-classé" (deux classes) : Super Héros et Business Man. Bon si on s'accroche vraiment au Background du personnage de Batman, on comprend très vite qu'il est multi classé.

    Une classe a plein de petites choses : des actions spécifiques. Un boulanger fait du pain, un guerrier fait des coups puissants, un archer peut tirer deux flèches (alors qu'un pékin de base qui n'a jamais touché un arc de sa vie aura du mal à en tirer ne serait-ce qu'une)... Une classe dépend aussi parfois d'autres classes. On ne peut pas être "Disciple du Dragon Rouge" si on est pas au moins barde ou ensorceleur.

    Pour la table T_RACE, je pense que je me suis auto-piné (désolé de l'expression), je pense qu'au final, une race (elfe, nain, humain...) est une caractéristique comme une autre. Du coup, je suppose que je vais la faire disparaître.

    Ensuite, il y a la notion d'objet. Un objet a tout un tas de caractéristiques (propriété curative, des dégâts si c'est une arme...). Un bâtiment (tel une boutique - notion que je n'ai pas encore mis dans ce MPD) ou un joueur peut en transporter un stock. La table T_PSG_OBJ n'est autre qu'un "inventaire", un gros sac. Il existera surement un T_BAT_OBJ quand la notion de bâtiment sera implémentée.

    Vous remarquerez cependant 2 tables qui font les malines tout en haut, seulement entre elles. C'est la notion de quartier. Le quartier, c'est une zone de la ville. Dans ce jeu, il n'existe pas de représentation de "la ville". La Ville est "si grande" que chaque quartier pourrait être une cité.

    Bref, chaque quartier est une sorte de grille (comme dans swing), sur laquelle sont placés les différents éléments. C'est en gros un repère cartésien ou chaque objet, décor et personnage sont identifiés sur la carte par le couple (X,Y) et Z... en fait. Z est là pour différencier le quartier A du quartier N =)

    Ainsi deux joueurs peuvent être à la position (5;8) mais dans 2 quartiers différents. Du coup, ils ne peuvent pas se croiser.

    Mon Soucis... qui n'en est peut être pas un, c'est que par exemple, les Objets (quand ils sont jetés à terre) et les personnages et les bâtiments sont présents dans ces quartiers aux positions X/Y.

    D'après ma réflexion, les positions, ne sont qu'une caractéristiques d'OBJ, BAT ou PSG. Donc à aucun moment ces 3 tables ne doivent être reliés à la table "T_QUARTIER". Me trompé-je ?

    Mais comme vous pouvez le voir, sortir les informations d'un personnage va demander un "grand nombre" d'union ou alors, beaucoup de petites requêtes.

    A votre avis, je me plante de direction dans ma conception, ou alors, je m'approche un peu de la vérité ?

Discussions similaires

  1. [T-SQL] Connaître le nombre de colonnes retourner par une PS
    Par NeoMan dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 28/12/2005, 11h30
  2. Nombre de colonnes avec le nom de la table
    Par benji41 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 10/07/2005, 20h17
  3. [débutant] nombre de colonne dan sun fichier csv
    Par mandagor dans le forum C++
    Réponses: 18
    Dernier message: 15/06/2005, 15h42
  4. [JTextArea]changer dynamiquement le nombre de colonnes
    Par MrDuChnok dans le forum Composants
    Réponses: 9
    Dernier message: 27/04/2004, 13h31
  5. [RDB$PRIMARY] Nombre de colonnes
    Par Lucien dans le forum InterBase
    Réponses: 4
    Dernier message: 17/01/2004, 12h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo