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 :

Clé primaires composées de clé étrangères


Sujet :

Décisions SGBD

  1. #1
    Candidat au Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mai 2014
    Messages : 4
    Points : 4
    Points
    4
    Par défaut Clé primaires composées de clé étrangères
    Bonjour, je viens vers vers vous afin de répondre a une question simple :

    Une clé primaire doit-elle toujours être composée de clé étrangère ? Si oui, pourquoi ?

    Afin de préciser cette question, je vais l'illustrer avec le détail d'un projet sur lequel je travaille pour mon école.

    Ce projet concerne la création d'une application de réservation de place de cinéma.

    Il est question pour un utilisateur de pouvoir réserver une place de cinéma pour une certaine séance, qui sera déterminée pour un film donné, dans une salle à une certaine date et un certain horaire.

    Ces séance auront été programmées à l'avance par un gérant de cinéma.

    Afin de stocker les différentes informations (film, séance, réservation) je dois utiliser une base de donnée MySQL.

    J'utilise le formalisme UML afin représenter mes objets dans l'application
    Nom : schema UML.jpg
Affichages : 1089
Taille : 16,8 Ko.
    À partir de mon schéma UML j'en déduis mon schéma de base de données.

    Le souci que j'ai actuellement est celui de la représentation d'une séance en base de données.

    Actuellement une séance est identifiée de manière unique par la salle dans laquelle elle a lieu, sa date, ainsi que son horaire de début (son horaire de fin étant calculé à partir de la durée du film)
    Les horaires sont en fait des tranches de 30 minutes numérotées de 1 à 48, cela permet la création d'un planning simplifié pour le gérant qui choisit sur quels chéneaux il place ses films.

    Ces trois informations constituent donc la clé primaire composée de la relation Séance.

    Ainsi un tuple Séance peut être représenté de la manière suivante :

    Séance ( idSalle, date, horaireDebut, horaireFin, film)

    Deux séances peuvent donc se dérouler à la même date pour une même salle mais pas au même horaire)
    Si mes souvenirs sont bons, il me semble qu'une clé primaire ne peut être composée que de clé étrangère.

    Ce qui signifie qu'il me faut créé une relation Date contenant les différentes date des séances, chacune d'elle identifiées de manière unique (à l'aide d'un idDate).

    De même qu'une relation Horaire dans laquelle je listerai tous mes horaires que j'identifierai également de manière unique (à l'aide d'un idHoraire).

    Et c'est là que le bât blesse.

    En effet mes l'attribut horaireDebut qui compose la clé primaire de la relation Séance n'a que 48 valeurs possibles, je trouve dommage de créer une relation uniquement pour cela.
    De même pour les dates même si leur nombres peut être très grand dois-je forcement passer par la création d'une relation Date ?

    Ne puis-je pas plutôt composer la clé primaire de la relation Séance à partir de l'id d'une salle, d'une date et d'un horaire sans que ces deux derniers soit eux-mêmes des clés étrangères.

    Lors de l'ajout d'une séance j'irais alors vérifier à l'aide d'une contrainte d'intégrité qu'aucune séance pour cette salle n'est la même date ET le même horaire de début. (J’occulte ici les vérifications à effectuer concernant le chevauchement des séances)

    Qu'en pensez-vous ?

  2. #2
    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 555
    Points
    38 555
    Billets dans le blog
    9
    Par défaut
    Je n'oserai paraphraser l'excellent article de Fsmrel, article que vous trouverez ici
    http://merise.developpez.com/actu/87...TE-par-fsmrel/
    Je pense que tout y est

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 761
    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 761
    Points : 52 547
    Points
    52 547
    Billets dans le blog
    5
    Par défaut
    D'un point de vue pratique mais aussi pour les performances, il vaudrait mieux que votre séance doit modélisée de la sorte :
    TABLE SEANCE : colonne --> (clef--> (IdSalle, DATHEURE_debut), IdFilm)
    En effet, et comme vous le précisez, la DATEHEURE de fin est calculée par rapport à DATEHEURE_debut + durée, ces données étant connues
    Or un principe fondamentale dans les SGBDR => pas de redondance, même calculée !
    Une vue complémentaire sera là pour vous apporter le confort nécessaire à l'implémentation des applicatifs

    Et donc de créer une entité planning comportant toutes les combinaisons de DATEHEURE_debut depuis l'an 2016 jusqu'à la fin des temps...

    Le fait de créer des entités de type DATE ou DATETIME est classique et impératif. Il vous permettra de simplifier bien des requêtes.
    Un exemple ;
    Trouver les créneaux vacants entre telle et telle date pour un festival.
    Si vous n'avez pas la liste des créneaux disponible, alors une telle requête est extrêmement complex eà établir...

    Ce genre de cas est systématique si vous devez par exemple planifier des RB chez le médecin

    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/ * * * * *

  4. #4
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 149
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 149
    Points : 7 392
    Points
    7 392
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Pour répondre à la question initiale, je dirais qu'il y a deux réponses.

    D'après MERISE (du moins, ce que j'en ai retenu), OUI
    => En effet, dans une table fille par exemple, ou une table de correspondance, on n'a généralement pas d'identifiant à proprement parler dans le MCD, car non utile.

    Exemple avec 3 tables :
    UTILISATEUR (id, nom, prenom)
    GROUPE (id, nom)
    UTIGRP ( ??? lien multiple entre utilisateur et groupe)

    Dans cette table UTIGRP, qui sera une simple relation de type "0,n" dans le MCD, on n'a aucune colonne porteuse de donnée.

    On ne retrouve donc que les clés étrangères :
    id_utilisateur et id_groupe

    Ce couple doit être unique.

    Donc est un parfait candidat à une clé primaire.

    CEPENDANT, si on va plus loin, on se rend compte que si on veut rajouter une relation de type 1,n sur cette relation (par exemple, des horaire d'accès, etc.) on va se retrouve avec des clés étrangères composites, et une clé primaire qui devient mamouth.
    => Et là, la plupart des SGBD vont commencer à ne pas aimer ça, d'un point de vue performances.

    Donc en SQL, une bonne pratique que je met maintenant en place systématiquement, c'est :
    - Une clé ID de type entier d'une taille compatible avec le nombre de lignes estimées (tinyint, smallint, int, bigint)
    - Une ou plusieur clé alternative (contrainte d'unicité) portant sur les tuples de clés étrangères.

    => L'avantage, c'est que tu as une table fille pour l'affectation des groupes, la clé étrangère n'est plus "id_utilisateur, id_groupe" mais "id_utigrp".

    Le second avantage, c'est que aujourd'hui, ce "id_utigrp" ne contient que des couples uniques d'utilisateur/groupe.
    Si demain je dois rajouter une propriété à cette table et que j'ai besoin de faire sauter cette unicité (par exemple, des dates d'application), je n'ai pas besoin de changer la clé primaire de la table (et donc je ne modifie pas les relations entre tables). J'ai juste à faire sauter ou modifier la contrainte d'unicté que j'ai mis en place sur le couple (id_utilisateur, id_groupe) pour inclure la date de début d'application par exemple.
    On ne jouit bien que de ce qu’on partage.

Discussions similaires

  1. Clé primaire composée de clé étrangère
    Par Birzat dans le forum Doctrine2
    Réponses: 2
    Dernier message: 06/11/2014, 09h57
  2. Réponses: 1
    Dernier message: 27/04/2010, 13h36
  3. Réponses: 1
    Dernier message: 21/10/2009, 16h26
  4. Clé primaire composées de plusieurs clés étrangères
    Par 2berte dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 10/02/2009, 16h56
  5. clé primaire composée de 2 clés étrangères
    Par Tigresse dans le forum Installation
    Réponses: 5
    Dernier message: 28/07/2003, 14h38

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