Bagaimana menerapkan hubungan satu-ke-satu, satu-ke-banyak dan banyak-ke-banyak saat merancang tabel?


281

Adakah yang bisa menjelaskan bagaimana menerapkan hubungan satu-ke-satu, satu-ke-banyak dan banyak-ke-banyak sambil merancang tabel dengan beberapa contoh?


Implementasinya cenderung bervariasi berdasarkan pada RDBMS target, jadi vendor apa yang Anda targetkan?
billinkc

1
itu bukan pertanyaan pekerjaan rumah ... !! Saya sedang mempersiapkan untuk wawancara .. Jadi saya pikir untuk bertanya di sini ... Saya mencoba googling tetapi belum menemukan artikel yang bagus di mana saya menjelaskan semua ini dalam satu ... !!
arsenal

Saya menargetkan basis data oracle .. !!
arsenal

Anda mungkin ingin membaca posting ini juga .... stevencalise.wordpress.com/2010/09/01/ ... Saya akan memperhatikan poin 2 dan 3.
tsells

3
@sells Terkadang Anda mengajukan pertanyaan yang tidak berlaku untuk apa yang ada di resume Anda atau langsung ke persyaratan pekerjaan. Saya diberi daftar orang yang akan mewawancarai saya di satu perusahaan, dan satu lagi adalah pakar DB. Saya tidak punya SQL di resume saya, tapi saya memoles beberapa pertanyaan SQL sederhana. Itu membantu, dan saya mendapatkan pekerjaan itu. Saya tahu kemudian, manajer perekrutan khawatir bagaimana para kandidat merespons di bawah tekanan. Apakah mereka mengakui batasan mereka atau berpura-pura masuk? Jika mereka mengakui batasan mereka, apakah mereka tetap mencoba atau menyerah terlalu cepat?
Doug Cuthbertson

Jawaban:


479

Satu-ke-satu: Gunakan kunci asing ke tabel yang dirujuk:

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

Anda juga harus meletakkan batasan unik pada kolom kunci asing ( addess.student_id) untuk mencegah beberapa baris dalam tabel anak ( address) terkait dengan baris yang sama dalam tabel yang direferensikan ( student).

Satu-ke-banyak : Gunakan kunci asing di banyak sisi hubungan yang menghubungkan kembali ke sisi "satu":

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

Banyak ke banyak : Gunakan tabel persimpangan ( contoh ):

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

Contoh pertanyaan:

 -- 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
Apa contoh yang baik ketika "tautan balik" berguna dalam hubungan Satu-ke-Satu? Terima kasih atas jawaban yang jelas dan ringkas.
dev_feed

1
@dev_feed Dalam hal desain basis data, saya tidak melihat tautan kembali bermanfaat, tetapi menggunakan contoh di atas tautan balik dapat menyederhanakan menemukan yang studentdiberikan address.
edhedges

@NullUserException kita harus membutuhkan 3 tabel untuk hubungan Many-to-many. Tidak dapat dilakukan dengan dua tabel Hubungan Banyak-ke-banyak.

1
@Cody Setiap student_classesbaris seharusnya hanya memiliki hubungan satu-ke-satu. Jika studentAada di classAdan classB, maka harus ada dua baris student_classes, satu untuk hubungan mana.
NullUserException

11
Dalam hubungan satu lawan satu, bidang gabungan harus unik di kedua tabel. Kemungkinan PK di satu meja yang menjamin keunikan, tetapi mungkin perlu indeks unik di meja lainnya.
HLGEM

70

Berikut adalah beberapa contoh dunia nyata dari jenis hubungan:

Satu lawan satu (1: 1)

Hubungan adalah satu-ke-satu jika dan hanya jika satu catatan dari tabel A terkait dengan maksimum satu catatan dalam tabel B.

Untuk membangun hubungan satu-ke-satu, kunci utama dari tabel B (tanpa catatan anak yatim) harus menjadi kunci sekunder dari tabel A (dengan catatan anak yatim).

Sebagai contoh:

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

Satu-ke-banyak (1: M)

Hubungan adalah satu-ke-banyak jika dan hanya jika satu catatan dari tabel A terkait dengan satu atau lebih catatan di tabel B. Namun, satu catatan di tabel B tidak dapat dikaitkan dengan lebih dari satu catatan di tabel A.

Untuk membangun hubungan satu-ke-banyak, kunci utama tabel A (tabel "satu") harus menjadi kunci sekunder tabel B (tabel "banyak").

Sebagai contoh:

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

Banyak ke banyak (M: M)

Hubungan adalah banyak-ke-banyak jika dan hanya jika satu catatan dari tabel A terkait dengan satu atau lebih catatan di tabel B dan sebaliknya.

Untuk membangun hubungan banyak-ke-banyak, buat tabel ketiga yang disebut "ClassStudentRelation" yang akan memiliki kunci utama dari tabel A dan tabel 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)
);

Contoh pertama: nomor GID (6) dan Nomor SGID (4), mengapa? Bukankah seharusnya SGID juga (6)? Dan pada contoh nomor 2 (4) dan angka (2) ...
obeliksz

@obeliksz bisa jadi nol?
moo cow

Mengapa Anda menggunakan UNIK (StudentID, ClassID) pada akhir M: N?
strix25

1
@ strix25 Untuk memaksakan menghindari pengulangan dalam membuat baris ClassStudentRelation yang sama beberapa kali, karena jika Anda tidak memastikan kunci asing StudentID dan ClassID unik, apa yang berhenti membuat baris baru dengan StudentID dan ClassID yang sama? karena mereka tidak unik dalam kode di atas. Jadi Anda bisa mengimplementasikannya seperti kode di atas, atau menambahkan kunci utama yang menyertakan StudentID dan ClassID untuk menghindari pengulangan membuat baris yang sama di ClassStudentRelation.
Fouad Boukredine

1
@valik Data dalam basis data bekerja dengan merujuk data yang ada, dan tidak membuat bagian data yang sama beberapa kali, mengapa Anda melakukan itu? tentu saja Anda tidak perlu, kalau tidak itu tidak efisien. Dengan mengingat hal itu, mari kita kembali ke contoh Anda (james memiliki biologi dan biologi memiliki james), Tentu saja Anda bisa, TETAPI tanpa membuat data lain yang sudah ada dalam database. Yang perlu Anda lakukan hanyalah merujuk yang sudah ada kapan pun Anda ingin membuat hubungan apa pun. Saya harap itu membantu :)
Fouad Boukredine

8

Ini adalah pertanyaan yang sangat umum, jadi saya memutuskan untuk mengubah jawaban ini menjadi sebuah artikel .

Satu-ke-banyak

Hubungan tabel satu-ke-banyak terlihat sebagai berikut:

Satu-ke-banyak

Dalam sistem database relasional, hubungan tabel satu-ke-banyak menghubungkan dua tabel berdasarkan Foreign Keykolom pada anak yang mereferensikan Primary Keybaris tabel induk.

Dalam diagram tabel di atas, post_idkolom dalam post_commenttabel memiliki Foreign Keyhubungan dengan kolom postid tabel Primary Key:

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

Satu-ke-satu

Hubungan tabel satu-ke-satu terlihat sebagai berikut:

Satu-ke-satu

Dalam sistem basis data relasional, hubungan tabel satu-ke-satu menghubungkan dua tabel berdasarkan Primary Keykolom pada anak yang juga merupakan Foreign Keyreferensi Primary Keydari baris tabel induk.

Oleh karena itu, kita dapat mengatakan bahwa tabel anak berbagi Primary Keydengan tabel induk.

Dalam diagram tabel di atas, idkolom dalam post_detailstabel juga memiliki Foreign Keyhubungan dengan kolom posttabel id Primary Key:

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

Banyak ke banyak

Hubungan tabel banyak-ke-banyak terlihat sebagai berikut:

Banyak ke banyak

Dalam sistem basis data relasional, hubungan banyak-ke-banyak tabel menghubungkan dua tabel induk melalui tabel anak yang berisi dua Foreign Keykolom referensi Primary Keykolom dari dua tabel induk.

Dalam diagram tabel di atas, post_idkolom dalam post_tagtabel juga memiliki Foreign Keyhubungan dengan kolom postid tabel Primary Key:

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

Dan, tag_idkolom dalam post_tagtabel memiliki Foreign Keyhubungan dengan kolom tagid tabel Primary Key:

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

3

Hubungan satu ke satu (1-1): Ini adalah hubungan antara kunci utama & kunci asing (kunci utama yang terkait dengan kunci asing hanya satu catatan). ini adalah hubungan satu lawan satu.

Hubungan Satu ke Banyak (1-M): Ini juga hubungan antara hubungan kunci primer & asing tetapi di sini kunci utama terkait dengan beberapa catatan (mis. Tabel A memiliki info buku dan Tabel B memiliki beberapa penerbit satu buku).

Many to Many (MM): Banyak ke banyak mencakup dua dimensi, dijelaskan sepenuhnya seperti di bawah ini dengan sampel.

-- 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
Akan lebih baik & lebih jelas jika Anda telah menambahkan batasan kunci utama dan kunci asing juga.
Ashish K Gupta
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.