Comment implémenter des relations un-à-un, un-à-plusieurs et plusieurs-à-plusieurs lors de la conception des tables?

281

Quelqu'un peut-il expliquer comment implémenter des relations un-à-un, un-à-plusieurs et plusieurs-à-plusieurs lors de la conception de tableaux avec quelques exemples?

arsenal
la source
L'implémentation a tendance à varier en fonction du SGBDR cible, alors quel fournisseur visez-vous?
billinkc
1
ce n'est pas une question de devoirs ... !! Je me prépare pour une interview .. Alors j'ai pensé à demander ici ... J'ai essayé de googler mais je n'ai pas trouvé de bon article où j'obtiens tout cela expliqué en un ... !!
arsenal
Je cible la base de données Oracle .. !!
arsenal
Vous pouvez également lire cet article .... stevencalise.wordpress.com/2010/09/01/… Je porterais une attention particulière aux points 2 et 3.
tsells
3
@tsells Parfois, on vous pose des questions qui ne s'appliquent pas à ce qui est sur votre CV ou directement aux exigences du poste. On m'a donné une liste de personnes qui m'intervieweraient dans une entreprise, et l'une était un expert DB. Je n'avais pas de SQL dans mon CV, mais j'ai revu quelques requêtes SQL simples. Cela a aidé et j'ai obtenu le poste. J'ai découvert plus tard que le responsable du recrutement s'inquiétait de la façon dont les candidats réagissent sous pression. Admettent-ils leurs limites ou truquent-ils leur chemin? S'ils admettent leurs limites, essayent-ils quand même ou abandonnent-ils trop tôt?
Doug Cuthbertson

Réponses:

479

Un à un: utilisez une clé étrangère pour la table référencée:

student: student_id, first_name, last_name, address_id
address: address_id, address, city, zipcode, student_id # you can have a
                                                        # "link back" if you need

Vous devez également placer une contrainte unique sur la colonne de clé étrangère ( addess.student_id) pour empêcher que plusieurs lignes de la table enfant ( address) ne soient liées à la même ligne de la table référencée ( student).

Un-à-plusieurs : utilisez une clé étrangère du côté plusieurs de la relation qui renvoie au côté "un":

teachers: teacher_id, first_name, last_name # the "one" side
classes:  class_id, class_name, teacher_id  # the "many" side

Plusieurs à plusieurs : utilisez une table de jonction ( exemple ):

student: student_id, first_name, last_name
classes: class_id, name, teacher_id
student_classes: class_id, student_id     # the junction table

Exemples de requêtes:

 -- Getting all students for a class:

    SELECT s.student_id, last_name
      FROM student_classes sc 
INNER JOIN students s ON s.student_id = sc.student_id
     WHERE sc.class_id = X

 -- Getting all classes for a student: 

    SELECT c.class_id, name
      FROM student_classes sc 
INNER JOIN classes c ON c.class_id = sc.class_id
     WHERE sc.student_id = Y

NullUserException
la source
1
Quel est un bon exemple de cas où le «lien de retour» est utile dans la relation un à un? Merci pour la réponse claire et concise.
dev_feed
1
@dev_feed En termes de conception de base de données, je ne pense pas que le lien soit bénéfique, mais en utilisant l'exemple ci-dessus, le lien pourrait simplifier la recherche d'un studentdonné address.
edhedges
@NullUserException devons-nous avoir besoin de 3 tables pour la relation plusieurs-à-plusieurs. Cela ne peut-il pas être fait par deux tables la relation plusieurs-à-plusieurs.
1
@Cody Chaque student_classesligne ne doit avoir qu'une seule relation un à un. Si studentAest dans classAet classB, alors il devrait y avoir deux lignes student_classes, une pour quelle relation.
NullUserException
11
Dans une relation un à un, le champ de jointure doit être unique dans les deux tables. Il s'agit probablement d'un PK sur une table qui garantit l'unicité, mais il peut avoir besoin d'un index unique sur l'autre table.
HLGEM
70

Voici quelques exemples concrets des types de relations:

Un à un (1: 1)

Une relation est biunivoque si et seulement si un enregistrement du tableau A est lié à un maximum d'un enregistrement dans le tableau B.

Pour établir une relation un-à-un, la clé primaire de la table B (sans enregistrement orphelin) doit être la clé secondaire de la table A (avec enregistrements orphelins).

Par exemple:

CREATE TABLE Gov(
    GID number(6) PRIMARY KEY, 
    Name varchar2(25), 
    Address varchar2(30), 
    TermBegin date,
    TermEnd date
); 

CREATE TABLE State(
    SID number(3) PRIMARY KEY,
    StateName varchar2(15),
    Population number(10),
    SGID Number(4) REFERENCES Gov(GID), 
    CONSTRAINT GOV_SDID UNIQUE (SGID)
);

INSERT INTO gov(GID, Name, Address, TermBegin) 
values(110, 'Bob', '123 Any St', '1-Jan-2009');

INSERT INTO STATE values(111, 'Virginia', 2000000, 110);

Un à plusieurs (1: M)

Une relation est un-à-plusieurs si et seulement si un enregistrement du tableau A est lié à un ou plusieurs enregistrements du tableau B. Cependant, un enregistrement du tableau B ne peut pas être lié à plusieurs enregistrements du tableau A.

Pour établir une relation un-à-plusieurs, la clé primaire de la table A (la table "un") doit être la clé secondaire de la table B (la table "plusieurs").

Par exemple:

CREATE TABLE Vendor(
    VendorNumber number(4) PRIMARY KEY,
    Name varchar2(20),
    Address varchar2(20),
    City varchar2(15),
    Street varchar2(2),
    ZipCode varchar2(10),
    Contact varchar2(16),
    PhoneNumber varchar2(12),
    Status varchar2(8),
    StampDate date
);

CREATE TABLE Inventory(
    Item varchar2(6) PRIMARY KEY,
    Description varchar2(30),
    CurrentQuantity number(4) NOT NULL,
    VendorNumber number(2) REFERENCES Vendor(VendorNumber),
    ReorderQuantity number(3) NOT NULL
);

Plusieurs-à-plusieurs (M: M)

Une relation est plusieurs-à-plusieurs si et seulement si un enregistrement de la table A est lié à un ou plusieurs enregistrements de la table B et vice versa.

Pour établir une relation plusieurs-à-plusieurs, créez une troisième table appelée "ClassStudentRelation" qui aura les clés primaires de la table A et de la table B.

CREATE TABLE Class(
    ClassID varchar2(10) PRIMARY KEY, 
    Title varchar2(30),
    Instructor varchar2(30), 
    Day varchar2(15), 
    Time varchar2(10)
);

CREATE TABLE Student(
    StudentID varchar2(15) PRIMARY KEY, 
    Name varchar2(35),
    Major varchar2(35), 
    ClassYear varchar2(10), 
    Status varchar2(10)
);  

CREATE TABLE ClassStudentRelation(
    StudentID varchar2(15) NOT NULL,
    ClassID varchar2(14) NOT NULL,
    FOREIGN KEY (StudentID) REFERENCES Student(StudentID), 
    FOREIGN KEY (ClassID) REFERENCES Class(ClassID),
    UNIQUE (StudentID, ClassID)
);
Arabinda Banik
la source
1er exemple: numéro GID (6) et numéro SGID (4), pourquoi? Le SGID ne devrait-il pas également être (6)? Et au 2e exemple numéro (4) et numéro (2) ...
obeliksz
@obeliksz pourrait être nul?
moo cow
Pourquoi utiliseriez-vous UNIQUE (StudentID, ClassID) à la fin de M: N?
strix25
1
@ strix25 Pour imposer d'éviter la répétition en créant plusieurs fois la même ligne ClassStudentRelation, car si vous ne vous assurez pas que les deux clés étrangères StudentID et ClassID sont uniques, qu'est-ce qui arrête de créer une nouvelle ligne avec les mêmes StudentID et ClassID? car ils ne sont pas uniques dans le code ci-dessus. Donc, soit vous l'implémentez comme le code ci-dessus, soit vous ajoutez une clé primaire qui inclut à la fois StudentID et ClassID pour éviter la répétition de la création de la même ligne dans ClassStudentRelation.
Fouad Boukredine
1
@valik Les données dans les bases de données fonctionnent en référençant les données existantes, et en ne créant pas le même morceau de données plusieurs fois, pourquoi feriez-vous cela? bien sûr, vous n'êtes pas obligé, sinon ce n'est pas efficace. Dans cet esprit, revenons à votre exemple (james a la biologie et la biologie a james), bien sûr que vous pouvez, MAIS sans créer une autre donnée qui existe déjà dans la base de données. Tout ce que vous devez faire est de simplement référencer celle qui existe déjà chaque fois que vous souhaitez créer une relation. J'espère que ça aide :)
Fouad Boukredine
8

C'est une question très courante, j'ai donc décidé de transformer cette réponse en un article .

Un à plusieurs

La relation de table un-à-plusieurs se présente comme suit:

Un à plusieurs

Dans un système de base de données relationnelle, une relation de table un-à-plusieurs relie deux tables en fonction d'une Foreign Keycolonne dans l'enfant qui fait référence à la ligne Primary Keyde la table parent.

Dans le diagramme de tableau ci-dessus, la post_idcolonne du post_commenttableau a une Foreign Keyrelation avec la colonne postid de la table Primary Key:

ALTER TABLE
    post_comment
ADD CONSTRAINT
    fk_post_comment_post_id
FOREIGN KEY (post_id) REFERENCES post

Un par un

La relation de table un-à-un se présente comme suit:

Un par un

Dans un système de base de données relationnelle, une relation de table un-à-un relie deux tables en fonction d'une Primary Keycolonne dans l'enfant qui fait également Foreign Keyréférence à la ligne Primary Keyde la table parent.

Par conséquent, nous pouvons dire que la table enfant partage la Primary Keyavec la table parent.

Dans le diagramme de tableau ci-dessus, la idcolonne du post_detailstableau a également une Foreign Keyrelation avec la colonne du posttableau id Primary Key:

ALTER TABLE
    post_details
ADD CONSTRAINT
    fk_post_details_id
FOREIGN KEY (id) REFERENCES post

Plusieurs à plusieurs

La relation table plusieurs à plusieurs se présente comme suit:

Plusieurs à plusieurs

Dans un système de base de données relationnelle, une relation table plusieurs-à-plusieurs relie deux tables parent via une table enfant qui contient deux Foreign Keycolonnes référençant les Primary Keycolonnes des deux tables parent.

Dans le diagramme de tableau ci-dessus, la post_idcolonne du post_tagtableau a également une Foreign Keyrelation avec la colonne postid de la table Primary Key:

ALTER TABLE
    post_tag
ADD CONSTRAINT
    fk_post_tag_post_id
FOREIGN KEY (post_id) REFERENCES post

Et, la tag_idcolonne de la post_tagtable a une Foreign Keyrelation avec la colonne tagid de la table Primary Key:

ALTER TABLE
    post_tag
ADD CONSTRAINT
    fk_post_tag_tag_id
FOREIGN KEY (tag_id) REFERENCES tag
Vlad Mihalcea
la source
3

Relation un à un (1-1): Il s'agit de la relation entre la clé primaire et la clé étrangère (la clé primaire relative à la clé étrangère un seul enregistrement). c'est une relation un à un.

Relation un à plusieurs (1-M): Il s'agit également d'une relation entre les relations de clés primaires et étrangères, mais ici, la clé primaire se rapporte à plusieurs enregistrements (par exemple, le tableau A contient des informations sur le livre et le tableau B a plusieurs éditeurs d'un livre).

Plusieurs à plusieurs (MM): plusieurs à plusieurs comprennent deux dimensions, expliquées en détail ci-dessous avec l'exemple.

-- This table will hold our phone calls.
CREATE TABLE dbo.PhoneCalls
(
   ID INT IDENTITY(1, 1) NOT NULL,
   CallTime DATETIME NOT NULL DEFAULT GETDATE(),
   CallerPhoneNumber CHAR(10) NOT NULL
)
-- This table will hold our "tickets" (or cases).
CREATE TABLE dbo.Tickets
(
   ID INT IDENTITY(1, 1) NOT NULL,
   CreatedTime DATETIME NOT NULL DEFAULT GETDATE(),
   Subject VARCHAR(250) NOT NULL,
   Notes VARCHAR(8000) NOT NULL,
   Completed BIT NOT NULL DEFAULT 0
)
-- This table will link a phone call with a ticket.
CREATE TABLE dbo.PhoneCalls_Tickets
(
   PhoneCallID INT NOT NULL,
   TicketID INT NOT NULL
)
Anjan Kant
la source
8
Cela aurait été mieux et plus clair si vous aviez également ajouté des contraintes de clé primaire et de clé étrangère.
Ashish K Gupta