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 :

ENUM ou table annexe ? [Normalisation]


Sujet :

Schéma

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 179
    Par défaut ENUM ou table annexe ?
    Bonjour,

    je me pose régulièrement la même question lorsque je créée mes tables. Est ce plus avantageux de créer un champs énuméré dans une table ou bien de créer une autre table et d'y mettre les choix possibles ?

    Par exemple pour une couleur de cheveux, vaut il mieux créer un champs ENUM avec valeurs blonds, noirs, roux...ou une table reliée par jointure avec des enregistrements blonds, noirs, roux ?

    Quels peuvent être les avantages des 2 solutions svp ?

    Au niveau applicatif (java) dans le cas d'un champs de type ENUM il est plus propre d'avoir je pense une Enumeration afin de gérer les possibilités mais niveau maintenabilité c'est moins aisé que d'avoir une table annexe.

    En cas de table annexe, cela fait une jointure en plus...

    Je précise que je pense avoir entre 5 et 10 valeurs possibles.

    Merci pour vos conseils

  2. #2
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 209
    Billets dans le blog
    16
    Par défaut
    Bonsoir,


    Si vous utilisez SQL, sachez qu’il est fait pour travailler verticalement plutôt qu’horizontalement (pensez par exemple aux opérateurs relationnels, JOIN, UNION, RESTRICT, PROJECT, etc., ainsi qu’aux opérateurs d’agrégation, SUM, AVG, MAX, etc.) Par ailleurs, je ne sache pas que le type ENUM fasse partie de ceux qui sont proposés en standard par les SGBD/R, vous aurez donc à le construire (si tant est que votre SGBD vous le permette).

    Supposons maintenant que vous ayez une table des personnes : chaque personne a une seule couleur de cheveux (aux chauves près...) Votre table comportera donc une colonne hébergeant des valeurs atomiques (par exemple : "blonds"), mais avec une contrainte de table pour vous assurer que la couleur de cheveux de chaque personne est valide :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE PERSONNE
    (
            PersonneId            INT              NOT NULL
          , PersonneNom           VARCHAR(64)      NOT NULL    
          , PersonnePrenom        VARCHAR(64)      NOT NULL 
          , CouleurCheveux        VARCHAR(64)      NOT NULL 
        , CONSTRAINT PERSONNE_PK PRIMARY KEY (PersonneId)
        , CONSTRAINT CouleurCheveux_CHCK01 CHECK (CouleurCheveux IN ('blonds', 'blancs', 'roux', 'noirs', 'blonds vénitien', 'Châtain clair avec des reflets mordorés'))
    ) ;
    Il n’est pas dit que tous les SGBD/R permettent la mise en œuvre de contraintes CHECK, mais quoi qu’il en soit, la solution la plus couramment pratiquée consiste quand même à définir une table des couleurs de cheveux :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    CREATE TABLE COULEUR_CHEVEUX
    (
            CouleurId             INT              NOT NULL
          , CouleurNom            VARCHAR(64)      NOT NULL    
        , CONSTRAINT COULEUR_CHEVEUX_PK PRIMARY KEY (CouleurId)
    ) ;
    Et établir une contrainte référentielle entre les deux tables :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE PERSONNE
    (
            PersonneId            INT              NOT NULL
          , PersonneNom           VARCHAR(64)      NOT NULL    
          , PersonnePrenom        VARCHAR(64)      NOT NULL 
          , CouleurCheveuxId      INT              NOT NULL           
        , CONSTRAINT PERSONNE_PK PRIMARY KEY (PersonneId)
        , CONSTRAINT PERSONNE_COULEUR_CHEVEUX_FK FOREIGN KEY (CouleurCheveuxId)
                     REFERENCES COULEUR_CHEVEUX (CouleurId)
    ) ;

    Un début de jeu d’essai :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    INSERT INTO COULEUR_CHEVEUX (CouleurId, CouleurNom) VALUES (1, 'blonds') ;
    INSERT INTO COULEUR_CHEVEUX (CouleurId, CouleurNom) VALUES (2, 'blancs') ;
    INSERT INTO COULEUR_CHEVEUX (CouleurId, CouleurNom) VALUES (3, 'roux') ;
    INSERT INTO COULEUR_CHEVEUX (CouleurId, CouleurNom) VALUES (4, 'noirs') ;
     
    INSERT INTO PERSONNE (PersonneId, PersonneNom, PersonnePrenom, CouleurCheveuxId) VALUES (1, 'Martin', 'Albert', 2) ;
    INSERT INTO PERSONNE (PersonneId, PersonneNom, PersonnePrenom, CouleurCheveuxId) VALUES (2, 'Dupond', 'Bernard', 3) ;
    INSERT INTO PERSONNE (PersonneId, PersonneNom, PersonnePrenom, CouleurCheveuxId) VALUES (3, 'Dupond', 'Carole', 1) ;
    INSERT INTO PERSONNE (PersonneId, PersonneNom, PersonnePrenom, CouleurCheveuxId) VALUES (4, 'Durand', 'Denis', 2) ; 
    INSERT INTO PERSONNE (PersonneId, PersonneNom, PersonnePrenom, CouleurCheveuxId) VALUES (5, 'LeBlanc', 'Emile', 1) ;

    Quelles sont les personnes ayant des cheveux blonds :

    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT x.PersonnePrenom, x.PersonneNom
    FROM   PERSONNE AS x JOIN COULEUR_CHEVEUX AS y ON x.CouleurCheveuxId = y.CouleurId
    WHERE  y.CouleurNom = 'blonds' ;

    Réponse :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    PersonnePrenom  PersonneNom
    --------------  -----------
    Carole          Dupond
    Emile           LeBlanc
    A noter que si la table PERSONNE est dotée d’un index sur la colonne CouleurCheveuxId, vous aurez une possibilité de filtrage que n’auriez probablement pas avec un type ENUM, lequel pénaliserait donc la performance.


    La jointure semble vous inquiéter : rassurez-vous, les optimiseurs des SGBD/R la mignotent et sont attentifs à sa performance. En outre, l’encombrement de la table COULEUR_CHEVEUX est epsilonesque et elle résidera donc en mémoire : les jointures ne seront pas la cause d’une baisse de performance. En tout cas, après une longue carrière de DBA, ce ne sont pas les jointures avec ce genre de table qui m’ont causé des soucis.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 179
    Par défaut
    Bonjour et merci pour cette réponse détaillée.

    En fait je connais bien le principe et les notions élémentaires des SGBDR (PK, FK, contraintes...).

    Dans mon cas de figure, je vais utiliser PostgreSQL et je peux donc créer un type pour gérer mes énumérations.

    J'ai donc le choix entre 2 possibilités, soit créer un nouveau type énuméré, soit créer une nouvelle table comme vous l'avez bien expliqué dans votre message.

    Le tout étant maintenant de choisir la bonne méthode...

    Or, je ne sais finalement pas trop les raisons qui légitiment telle ou telle méthode, c'est ce que j'aimerais comprendre.

    Merci encore pour l'explication

  4. #4
    Expert confirmé Avatar de Richard_35
    Homme Profil pro
    Inscrit en
    Juillet 2007
    Messages
    3 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 3 121
    Par défaut
    Bonjour Jecomprendsrien et Fsmrel,

    Personnellement, je considère les champs ENUM comme des "faux amis" qui, à terme, sont la source de beaucoup d'ennuis.

    Avec une table par champ ENUM, la maintenance et l'évolutivité sont assurées.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 179
    Par défaut
    Bonjour Richard, merci pour ton avis.

    je vais donc m'orienter vers une table supplémentaire comme tu le suggères. Il sera toujours temps de modifier à l'usage...

    Merci pour vos avis en tout cas

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 18/12/2013, 14h29
  2. Table des annexes ?
    Par khayyam90 dans le forum Mise en forme
    Réponses: 9
    Dernier message: 05/08/2012, 20h44
  3. Importer des données d'une table annexes
    Par jmjmjm dans le forum Oracle
    Réponses: 2
    Dernier message: 13/06/2007, 15h23
  4. Réponses: 4
    Dernier message: 11/05/2007, 17h40
  5. [TABLE][ENUM] u champs à choix multiple ?
    Par narmataru dans le forum SQL
    Réponses: 2
    Dernier message: 04/11/2003, 10h25

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