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

Décisions SGBD Discussion :

Primaire, unique ou index comme clé de liaison ?


Sujet :

Décisions SGBD

  1. #1
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut Primaire, unique ou index comme clé de liaison ?
    Bonjour,

    Je n'ai pas trouvé de sous-forum vraiment approprié a ma question donc je la pose ici et je laisse le soin a un modérateur de déplacer mon sujet si gênant.

    J'ai un espace membre avec une table membres ou je stock les informations de connexion du membre, son email etc.. et je souhaite créer une deuxième table membres_informations pour stocker les informations personnelles du membre.

    Il est donc inutile de créer un champ id en auto incrément dans la table membres_informations ? mais plutôt de créer un champ idmbr avec l'id du membre.
    Cependant, je bug sur une question : Je mets quoi comme clé sur idmbr ? primaire, unique ou index ?

    Merci pour votre aide.

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    L'emplacement de la discussion n'est pas gênant mais comme tu le vois, ce n'est pas une question sur PHP.

    Si la table membres_informations ne contient qu'une ligne pour chaque membre alors ça ne sert à rien d'avoir une nouvelle table autant avoir toutes les informations dans la table membre.

    L'index PRIMARY est unique et ne peut pas être NULL. Il est utilisé pour désigner de manière univoque une ligne dans une table.
    L'index UNIQUE est unique et peut être NULL. Il garantie qu'il ne peut y avoir de doublons dans la colonne, en dehors des NULL.
    L'index INDEX n'a pas de contrainte. Placer un index permet d’accélérer grandement les recherches sur la colonne, cela sert en particulier pour faire des jointures vers l'id primaire d'une autre table.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    Citation Envoyé par sabotage Voir le message
    Si la table membres_informations ne contient qu'une ligne pour chaque membre alors ça ne sert à rien d'avoir une nouvelle table autant avoir toutes les informations dans la table membre.
    Effectivement, elle contient qu'une ligne pour chaque membre mais si je fusionne les deux je me retrouve avec 25 champs (pas énorme pour une table je sais bien) mais je voulais séparer les informations basics et les données personnelles. Mauvaise idée ? Je repasse a une seule table ?

    Voici la structure de mes deux tables :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    --
    -- Structure de la table `profils`
    --
     
    DROP TABLE IF EXISTS `profils`;
    CREATE TABLE IF NOT EXISTS `profils` (
      `idmbr` int(11) NOT NULL,
      `description` text,
      `profession` varchar(255) DEFAULT NULL,
      `taille` int(11) DEFAULT NULL,
      `origine` varchar(255) DEFAULT NULL,
      `religion` varchar(255) DEFAULT NULL,
      `tabac` varchar(255) DEFAULT NULL,
      `alcool` varchar(255) DEFAULT NULL,
      `nombre_enfants` varchar(255) DEFAULT NULL,
      `fonder_une_famille` varchar(255) DEFAULT NULL,
      UNIQUE KEY `idmbr` (`idmbr`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     
    -- --------------------------------------------------------
     
    --
    -- Structure de la table `users`
    --
     
    DROP TABLE IF EXISTS `users`;
    CREATE TABLE IF NOT EXISTS `users` (
      `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
      `genre` enum('1','2') NOT NULL,
      `genre_search` enum('1','2') NOT NULL,
      `prenom` varchar(55) NOT NULL,
      `date_naissance` date NOT NULL,
      `lng` float DEFAULT NULL,
      `lat` float DEFAULT NULL,
      `city` varchar(85) NOT NULL,
      `photo_principale` varchar(255) DEFAULT NULL,
      `email` varchar(255) NOT NULL,
      `password` varchar(255) NOT NULL,
      `remember_token` varchar(255) NOT NULL,
      `confirmation_token` varchar(255) NOT NULL,
      `confirmed_at` datetime DEFAULT NULL,
      `reset_token` varchar(255) NOT NULL,
      `reset_at` datetime DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1007 DEFAULT CHARSET=utf8;

  4. #4
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Quand tu auras besoin de récupérer les informations ça sera plus efficace sur une seule table plutôt que de faire 2 requêtes ou une jointure.

    Ce n'est par contre pas une règle absolue.
    Imaginons par exemple que tu es une valeur peu renseignée, ça peut être plus efficace d'avoir une table spécifique.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  5. #5
    Membre confirmé
    Homme Profil pro
    Déveleoppeur Web/Mobile
    Inscrit en
    Avril 2013
    Messages
    330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Déveleoppeur Web/Mobile
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2013
    Messages : 330
    Points : 545
    Points
    545
    Par défaut
    Le fait de diviser la table en deux n'est pas un mauvais choix, effectivement si tu as 25 champs ça peut te permettre d'économiser du temps d’exécution de la requête, il n'est pas obligé de faire une jointure pour récupérer les données d'ailleurs.

    Dans ton cas c'est spécial, le champs membre_id de ta nouvelle table sera à la fois une clé étrangère et une clé primaire... Mais perso je ne procéderais pas comme cela, dans membres_informations je laissera un champs id en auto increment qui sera la clé primaire, puis le champs membre_id serait en clé étrangère

  6. #6
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    ok je vois mais je mets quoi comme index pour le champ idmbr de la table membres_informations ? index ?

  7. #7
    Membre confirmé
    Homme Profil pro
    Déveleoppeur Web/Mobile
    Inscrit en
    Avril 2013
    Messages
    330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Déveleoppeur Web/Mobile
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2013
    Messages : 330
    Points : 545
    Points
    545
    Par défaut
    t'es sur phpmyadmin ? Les clés étrangères c'est un peu spécial la dessus, je te conseille de la créer avec une requête, je te laisse te renseigner du côté des CONSTRAINT FOREIGN KEY

  8. #8
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 763
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 763
    Points : 52 554
    Points
    52 554
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par sabotage Voir le message
    L'emplacement de la discussion n'est pas gênant mais comme tu le vois, ce n'est pas une question sur PHP.

    Si la table membres_informations ne contient qu'une ligne pour chaque membre alors ça ne sert à rien d'avoir une nouvelle table autant avoir toutes les informations dans la table membre.
    Non ça c'est stupide !
    L'un des principes fondamentaux de la modélisation de données est PAS DE NULL !
    En mettant tout dans le même table, vous obtiendrez des tables obèses (à lire) avec plein de colonne NULL et des performances catastrophiques comme j'ai eu l'occasion de le dire maintes fois depuis 15 ans !!!

    C'est d'ailleurs pour cela qu'a été inventé la notion d'héritage et dans ce cas précis la table fille possède une clef primaire qui est aussi clef étrangères.
    A lire sur l'héritage en modélisation : http://sqlpro.developpez.com/cours/m...tion/heritage/

    Au passage il n'est pas rare d'avoir un héritage a plusieurs niveau et c'est très bénéfique tant sur le plan du volume des données que sur le plan du requêtage.

    Exemple, dans une cie d'aviation, héritage à 4 niveau, tables :
    PERSONNE (table mère)
    - CLIENT
    - EMPLOYÉ
    -- RAMPANT
    -- VOLANT
    --- PNC
    --- PILOTE

    Obtenir les noms des pilotes qualifié sur 747 400 ne nécessite qu'une seule jointure et évite de transbahuter toutes les colonnes dans les tables employés et volant, ce qui économise sans doute 50% du volume des données dans l'exécution de la requête !

    Pour vous former à la modélisation des données et éviter de donner des conseils stupide :
    Nom : Soutou Brouard Modélisation bases de données.jpg
Affichages : 365
Taille : 40,3 Ko



    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  9. #9
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    -Rpass- : Je pense que j'ai trouvé la page sur phpmyadmin regarde :


    Nom : localhost   Local Databases   site1   users   phpMyAdmin 4.5.2.png
Affichages : 476
Taille : 68,0 Ko

    par contre, je ne sais pas l'utiliser cette page, je vais voir s'il existe un tuto sur le net consacré à cette page.


    SQLpro : Salut, j'ai lu ton article, très intéressant !
    en résumé : mieux vaut avoir plusieurs tables qui ne dépasse pas 10 colonnes plutôt qu'une seule table "obèse" .. Je résume bien-sur!

  10. #10
    Membre confirmé
    Homme Profil pro
    Déveleoppeur Web/Mobile
    Inscrit en
    Avril 2013
    Messages
    330
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Déveleoppeur Web/Mobile
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2013
    Messages : 330
    Points : 545
    Points
    545
    Par défaut
    Ah bien vu, oui il faut que ta table soit en mode InnoDB pour activer cette vue il me semble !

    Oui renseigne toi sur comment fonctionne les clés étrangères mais c'est assez simple :
    - tu renseignes le nom de ta clé (peut-importe le nom ce n'est pas très important)
    - tu indiques le nom de la colonne concernée (pour toi idmbr)
    - puis le nom de la table et colonne référencée ( tu dois bien entendue aussi indiquer la table), dans ton cas : membres.id_membre

  11. #11
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 763
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 763
    Points : 52 554
    Points
    52 554
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par bndd24 Voir le message
    SQLpro : Salut, j'ai lu ton article, très intéressant !
    en résumé : mieux vaut avoir plusieurs tables qui ne dépasse pas 10 colonnes plutôt qu'une seule table "obèse" .. Je résume bien-sur!
    Oh que oui ! Quand je fais des audits, je tue dès qu'une table dépasse colonnes et c'est déjà beaucoup !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  12. #12
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 133
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 133
    Points : 38 556
    Points
    38 556
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par bndd24 Voir le message
    Voici la structure de mes deux tables :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    --
    -- Structure de la table `profils`
    --
     
    DROP TABLE IF EXISTS `profils`;
    CREATE TABLE IF NOT EXISTS `profils` (
      `idmbr` int(11) NOT NULL,
      `description` text,
      `profession` varchar(255) DEFAULT NULL,
      `taille` int(11) DEFAULT NULL,
      `origine` varchar(255) DEFAULT NULL,
      `religion` varchar(255) DEFAULT NULL,
      `tabac` varchar(255) DEFAULT NULL,
      `alcool` varchar(255) DEFAULT NULL,
      `nombre_enfants` varchar(255) DEFAULT NULL,
      `fonder_une_famille` varchar(255) DEFAULT NULL,
      UNIQUE KEY `idmbr` (`idmbr`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     
    -- --------------------------------------------------------
     
    --
    -- Structure de la table `users`
    --
     
    DROP TABLE IF EXISTS `users`;
    CREATE TABLE IF NOT EXISTS `users` (
      `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
      `genre` enum('1','2') NOT NULL,
      `genre_search` enum('1','2') NOT NULL,
      `prenom` varchar(55) NOT NULL,
      `date_naissance` date NOT NULL,
      `lng` float DEFAULT NULL,
      `lat` float DEFAULT NULL,
      `city` varchar(85) NOT NULL,
      `photo_principale` varchar(255) DEFAULT NULL,
      `email` varchar(255) NOT NULL,
      `password` varchar(255) NOT NULL,
      `remember_token` varchar(255) NOT NULL,
      `confirmation_token` varchar(255) NOT NULL,
      `confirmed_at` datetime DEFAULT NULL,
      `reset_token` varchar(255) NOT NULL,
      `reset_at` datetime DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1007 DEFAULT CHARSET=utf8;
    Outre la remarque de SQLPro à laquelle je souscris totalement, j'ajoute que vos tables sont mal construites car :
    - il y a des libellés qui devraient être remplacés par des codes (profession, religion, origine...)
    - les formats de données sont mal choisis (nombre_enfant varchar(255) , taille integer...), probablement aussi vos 2 colonnes définies en float, à quoi servent elles ?
    - les longueurs sont inadéquates (password sur 255, il faut une sacré mémoire !)
    - la pléthore de varchar nuit aux performances

  13. #13
    Membre habitué
    Homme Profil pro
    Webmaster
    Inscrit en
    Juillet 2015
    Messages
    518
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Webmaster

    Informations forums :
    Inscription : Juillet 2015
    Messages : 518
    Points : 184
    Points
    184
    Par défaut
    escartefigue : non en effet, les types et les longueurs sont très mal définis, je suis d'accord et cela n'est que provisoire. Mon sujet porte principalement sur les liaisons.

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

Discussions similaires

  1. clé primaire composée et index
    Par ionesco dans le forum Requêtes
    Réponses: 4
    Dernier message: 13/10/2009, 09h27
  2. Réponses: 1
    Dernier message: 13/08/2009, 15h32
  3. clé primaire et clé index
    Par EIN-LESER dans le forum Débuter
    Réponses: 24
    Dernier message: 09/01/2009, 11h51
  4. Numéro d'erreur unique VB.NET ? comme err.number sur vb6
    Par moris7 dans le forum Windows Forms
    Réponses: 6
    Dernier message: 02/07/2008, 14h25
  5. [DEBUTANT] Utilisation UNIQUE KEY, INDEX,
    Par nounetmasque dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 26/07/2007, 17h07

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