Come implementare relazioni uno a uno, uno a molti e molti a molti durante la progettazione di tabelle?


281

Qualcuno può spiegare come implementare relazioni uno a uno, uno a molti e molti a molti mentre si progettano tabelle con alcuni esempi?


L'implementazione tende a variare in base al RDBMS di destinazione, quindi quale fornitore stai prendendo di mira?
Billinkc

1
non è una domanda da fare a casa ... !! Mi sto preparando per un'intervista .. Quindi ho pensato di chiedere qui ... Ho provato a cercare su Google ma non ho trovato nessun buon articolo in cui ottengo tutti questi spiegati in uno ... !!
arsenale

Sto prendendo di mira il database Oracle. !!
arsenale

Potresti voler leggere anche questo post .... stevencalise.wordpress.com/2010/09/01/… Presterei molta attenzione ai punti 2 e 3.
tsells

3
@tsells A volte ti vengono poste domande che non si applicano a ciò che è nel tuo curriculum o direttamente ai requisiti del lavoro. Mi è stato dato un elenco di persone che mi avrebbero intervistato in una società e una era un esperto di DB. Non avevo SQL sul mio curriculum, ma ho ripassato alcune semplici query SQL. Mi ha aiutato e ho ottenuto il lavoro. Ho scoperto in seguito che il responsabile delle assunzioni era preoccupato del modo in cui i candidati rispondono sotto pressione. Ammettono i loro limiti o fingono di farsi strada? Se ammettono i loro limiti, provano comunque o si arrendono troppo presto?
Doug Cuthbertson,

Risposte:


479

One-to-one: utilizzare una chiave esterna per la tabella di riferimento:

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

È inoltre necessario inserire un vincolo univoco nella colonna chiave esterna ( addess.student_id) per evitare che più righe nella tabella figlio ( address) siano correlate alla stessa riga nella tabella referenziata ( student).

Uno-a-molti : usa una chiave esterna sul lato multiplo della relazione che ricollega al lato "uno":

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

Many-to-many : utilizzare una tabella di giunzione ( esempio ):

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

Query di esempio:

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


1
Qual è un buon esempio di quando il "link back" è utile nella relazione One-to-One? Grazie per la risposta chiara e concisa.
dev_feed,

1
@dev_feed In termini di progettazione del database non vedo il link back come utile, ma usare l'esempio sopra il link back potrebbe semplificare la ricerca di un studentdato address.
edhedges,

@NullUserException dobbiamo aver bisogno di 3 tabelle per la relazione Many-to-many. Non può essere fatta da due tabelle la relazione Many-to-many.

1
@Cody Ogni student_classesriga dovrebbe avere solo una relazione uno a uno. Se studentAè in classAe classB, allora dovrebbero esserci due righe student_classes, una per la quale relazione.
NullUserException il

11
In una relazione uno a uno, il campo di join deve essere univoco in entrambe le tabelle. È probabilmente un PK su una tabella che garantisce l'univocità, ma potrebbe essere necessario un indice univoco sull'altra tabella.
HLGEM,

70

Ecco alcuni esempi reali dei tipi di relazioni:

One-to-one (1: 1)

Una relazione è uno a uno se e solo se un record della tabella A è correlato ad un massimo di un record nella tabella B.

Per stabilire una relazione uno a uno, la chiave primaria della tabella B (senza record orfani) deve essere la chiave secondaria della tabella A (con record orfani).

Per esempio:

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);

Uno-a-molti (1: M)

Una relazione è uno-a-molti se e solo se un record della tabella A è correlato a uno o più record della tabella B. Tuttavia, un record nella tabella B non può essere correlato a più di un record nella tabella A.

Per stabilire una relazione uno-a-molti, la chiave primaria della tabella A (la tabella "one") deve essere la chiave secondaria della tabella B (la tabella "many").

Per esempio:

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
);

Molti a molti (M: M)

Una relazione è molti-a-molti se e solo se un record della tabella A è correlato a uno o più record della tabella B e viceversa.

Per stabilire una relazione molti-a-molti, creare una terza tabella denominata "ClassStudentRelation" che avrà le chiavi primarie sia della tabella A che della tabella 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)
);

1 ° esempio: numero GID (6) e numero SGID (4), perché? SGID non dovrebbe essere anche (6)? E al 2 ° esempio numero (4) e numero (2) ...
obeliksz,

@obeliksz potrebbe essere null?
Moo Cow,

Perché dovresti usare UNIQUE (StudentID, ClassID) alla fine di M: N?
strix25

1
@ strix25 Per imporre di evitare ripetizioni nella creazione della stessa riga ClassStudentRelation più volte, perché se non si è sicuri che entrambe le chiavi esterne StudentID e ClassID siano univoche, cosa interrompe la creazione di una nuova riga con lo stesso StudentID e ClassID? in quanto non sono univoci nel codice sopra. Quindi lo implementi come il codice sopra o aggiungi una chiave primaria che include sia StudentID e ClassID per evitare la ripetizione della creazione della stessa riga in ClassStudentRelation.
Fouad Boukredine,

1
@valik I dati nei database funzionano facendo riferimento a dati esistenti e non creando più volte lo stesso pezzo di dati, perché dovresti farlo? ovviamente non è necessario, altrimenti non è efficiente. Con questo in mente, torniamo al tuo esempio (james ha biologia e biologia ha james), certo che puoi, MA senza creare un altro pezzo di dati che esiste già nel database. Tutto quello che devi fare è fare riferimento a quello già esistente ogni volta che vuoi creare una relazione. Spero che sia d'aiuto :)
Fouad Boukredine,

8

Questa è una domanda molto comune, quindi ho deciso di trasformare questa risposta in un articolo .

Uno-a-molti

La relazione della tabella uno-a-molti ha il seguente aspetto:

Uno-a-molti

In un sistema di database relazionale, una relazione da una a molte tabelle collega due tabelle basate su una Foreign Keycolonna nel figlio che fa riferimento alla Primary Keyriga della tabella padre.

Nel diagramma della tabella sopra, la post_idcolonna nella post_commenttabella ha una Foreign Keyrelazione con la colonna postID tabella Primary Key:

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

Uno a uno

La relazione della tabella uno a uno ha il seguente aspetto:

Uno a uno

In un sistema di database relazionale, una relazione di tabella uno a uno collega due tabelle basate su una Primary Keycolonna nel figlio che fa anche Foreign Keyriferimento alla Primary Keyriga della tabella padre.

Pertanto, possiamo dire che la tabella figlio condivide la Primary Keycon la tabella padre.

Nel diagramma della tabella sopra, la idcolonna nella post_detailstabella ha anche una Foreign Keyrelazione con la colonna della posttabella id Primary Key:

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

Molti-a-molti

La relazione della tabella molti-a si presenta come segue:

Molti-a-molti

In un sistema di database relazionale, una relazione di tabella molti-a-molti collega due tabelle padre tramite una tabella figlio che contiene due Foreign Keycolonne che fanno riferimento alle Primary Keycolonne delle due tabelle padre.

Nel diagramma della tabella sopra, la post_idcolonna nella post_tagtabella ha anche una Foreign Keyrelazione con la colonna postID tabella Primary Key:

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

E, la tag_idcolonna nella post_tagtabella ha una Foreign Keyrelazione con la colonna tagID tabella Primary Key:

ALTER TABLE
    post_tag
ADD CONSTRAINT
    fk_post_tag_tag_id
FOREIGN KEY (tag_id) REFERENCES tag

3

Relazione uno a uno (1-1): questa è la relazione tra chiave primaria ed esterna (chiave primaria relativa alla chiave esterna solo un record). questa è una relazione uno a uno.

Relazione uno-a-molti (1-M): questa è anche una relazione tra relazioni di chiavi primarie ed esterne, ma qui la chiave primaria relativa a più record (ovvero la tabella A contiene informazioni sul libro e la tabella B ha più editori di un libro).

Many to Many (MM): Many to many include due dimensioni, spiegate completamente come di seguito con un campione.

-- 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
)

8
Sarebbe stato migliore e più chiaro se avessi aggiunto anche vincoli di chiave primaria e chiave esterna.
Ashish K Gupta,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.