Làm thế nào để thực hiện các mối quan hệ một-một, một-nhiều và nhiều-nhiều trong khi thiết kế bảng?


281

Bất cứ ai cũng có thể giải thích làm thế nào để thực hiện các mối quan hệ một-một, một-nhiều và nhiều-nhiều trong khi thiết kế các bảng với một số ví dụ?


Việc triển khai có xu hướng thay đổi dựa trên RDBMS mục tiêu, vậy bạn đang nhắm mục tiêu vào nhà cung cấp nào?
billinkc

1
đó không phải là một câu hỏi bài tập về nhà ... !! Tôi đang chuẩn bị cho một cuộc phỏng vấn .. Vì vậy, tôi đã nghĩ rằng hãy hỏi ở đây ... Tôi đã thử googling nhưng không tìm thấy bất kỳ bài viết hay nào mà tôi nhận được tất cả những điều này được giải thích trong một ... !!
kho vũ khí

Tôi đang nhắm mục tiêu cơ sở dữ liệu oracle .. !!
kho vũ khí

Bạn cũng có thể muốn đọc bài đăng này .... stevencalise.wordpress.com/2010/09/01/ Tôi sẽ rất chú ý đến điểm 2 và 3.
tsells

3
@tsells Đôi khi bạn được hỏi những câu hỏi không áp dụng cho những gì trong sơ yếu lý lịch của bạn hoặc trực tiếp cho các yêu cầu công việc. Tôi đã được đưa ra một danh sách những người sẽ phỏng vấn tôi tại một công ty và một người là chuyên gia DB. Tôi không có SQL trong sơ yếu lý lịch của mình, nhưng tôi đã xem qua một vài truy vấn SQL đơn giản. Nó đã giúp tôi và tôi đã có được công việc. Tôi phát hiện ra sau đó, người quản lý tuyển dụng quan tâm đến cách các ứng viên phản ứng dưới áp lực. Họ có thừa nhận giới hạn của họ hoặc giả mạo theo cách của họ thông qua? Nếu họ thừa nhận giới hạn của mình, dù sao họ cũng cố gắng hoặc từ bỏ quá sớm?
Doug Cuthbertson

Câu trả lời:


478

Một đối một: Sử dụng khóa ngoại cho bảng được tham chiếu:

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

Bạn cũng phải đặt một ràng buộc duy nhất trên cột khóa ngoài ( addess.student_id) để ngăn nhiều hàng trong bảng con ( address) liên quan đến cùng một hàng trong bảng được tham chiếu ( student).

Một-nhiều : Sử dụng khóa ngoại ở nhiều phía của mối quan hệ liên kết lại với phía "một":

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

Nhiều-nhiều : Sử dụng bảng nối ( ví dụ ):

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

Các truy vấn mẫu:

 -- 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
Một ví dụ điển hình khi "liên kết trở lại" là hữu ích trong mối quan hệ Một-Một? Cảm ơn câu trả lời rõ ràng và súc tích.
dev_feed

1
@dev_feed Xét về thiết kế cơ sở dữ liệu Tôi không thấy liên kết lại để có lợi, nhưng sử dụng các ví dụ trên các liên kết trở lại có thể đơn giản hóa việc tìm kiếm một studentcho một address.
edhedges

@NullUserException chúng ta phải cần 3 bảng cho mối quan hệ Nhiều-nhiều. Nó không được thực hiện bằng hai bảng Mối quan hệ Nhiều-nhiều.

1
@Cody Mỗi student_classeshàng chỉ nên có một mối quan hệ một đối một. Nếu studentAở trong classAclassB, thì nên có hai hàng trong student_classes, một hàng cho mối quan hệ.
NullUserException 6/07/2015

11
Trong mối quan hệ 1-1, trường tham gia phải là duy nhất trong cả hai bảng. Nó có khả năng là PK trên một bảng đảm bảo tính duy nhất, nhưng nó có thể cần một chỉ mục duy nhất trên bảng khác.
HLGEM

70

Dưới đây là một số ví dụ thực tế về các loại mối quan hệ:

Một-một (1: 1)

Mối quan hệ là một đối một khi và chỉ khi một bản ghi từ bảng A có liên quan đến tối đa một bản ghi trong bảng B.

Để thiết lập mối quan hệ một đối một, khóa chính của bảng B (không có bản ghi mồ côi) phải là khóa phụ của bảng A (có bản ghi mồ côi).

Ví dụ:

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

Một-nhiều (1: M)

Mối quan hệ là một-nhiều nếu và chỉ khi một bản ghi từ bảng A có liên quan đến một hoặc nhiều bản ghi trong bảng B. Tuy nhiên, một bản ghi trong bảng B không thể liên quan đến nhiều hơn một bản ghi trong bảng A.

Để thiết lập mối quan hệ một-nhiều, khóa chính của bảng A (bảng "một") phải là khóa phụ của bảng B (bảng "nhiều").

Ví dụ:

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

Nhiều-nhiều (M: M)

Một mối quan hệ là nhiều-nhiều nếu và chỉ khi một bản ghi từ bảng A có liên quan đến một hoặc nhiều bản ghi trong bảng B và ngược lại.

Để thiết lập mối quan hệ nhiều-nhiều, hãy tạo một bảng thứ ba có tên "ClassStudentRelation" sẽ có các khóa chính của cả bảng A và bảng 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)
);

Ví dụ 1: Số GID (6) và Số SGID (4), tại sao? Không nên SGID cũng được (6)? Và ở số ví dụ thứ 2 (4) và số (2) ...
obeliksz

@obeliksz có thể là null?
moo bò

Tại sao bạn lại sử dụng UNIQUE (StudentID, ClassID) vào cuối M: N?
strix25

1
@ strix25 Để thực thi tránh lặp lại trong việc tạo cùng một hàng ClassStudentRelation, bởi vì nếu bạn không đảm bảo cả hai khóa ngoại StudentID và ClassID là duy nhất, điều gì sẽ dừng tạo một hàng mới với cùng StudentID và ClassID? vì chúng không phải là duy nhất trong mã ở trên. Vì vậy, bạn có thể triển khai nó như mã ở trên hoặc thêm khóa chính bao gồm cả StudentID và ClassID để tránh lặp lại việc tạo cùng một hàng trong ClassStudentRelation.
Fouad Boukredine

1
@valik Dữ liệu trong cơ sở dữ liệu hoạt động bằng cách tham chiếu dữ liệu hiện có và không tạo cùng một dữ liệu nhiều lần, tại sao bạn lại làm vậy? tất nhiên bạn không phải làm thế, nếu không nó không hiệu quả. Với ý nghĩ đó, hãy quay trở lại ví dụ của bạn (james có sinh học và sinh học có james), Tất nhiên bạn có thể, NHƯNG mà không cần tạo một phần dữ liệu khác đã tồn tại trong cơ sở dữ liệu. Tất cả những gì bạn cần làm là chỉ tham khảo cái đã có sẵn bất cứ khi nào bạn muốn tạo bất kỳ mối quan hệ nào. Tôi hy vọng điều đó có ích :)
Fouad Boukredine 11/07/19

8

Đây là một câu hỏi rất phổ biến, vì vậy tôi quyết định biến câu trả lời này thành một bài viết .

Một-nhiều

Mối quan hệ một-nhiều bảng trông như sau:

Một-nhiều

Trong một hệ thống cơ sở dữ liệu quan hệ, mối quan hệ một-nhiều bảng liên kết hai bảng dựa trên một Foreign Keycột trong con tham chiếu đến hàng Primary Keycủa bảng cha.

Trong sơ đồ bảng ở trên, post_idcột trong post_commentbảng có Foreign Keymối quan hệ với cột postid bảng Primary Key:

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

Một chọi một

Mối quan hệ một-một-bảng trông như sau:

Một chọi một

Trong một hệ thống cơ sở dữ liệu quan hệ, mối quan hệ một-một liên kết hai bảng dựa trên một Primary Keycột trong con cũng là Foreign Keytham chiếu Primary Keycủa hàng của bảng cha.

Do đó, chúng ta có thể nói rằng bảng con chia sẻ Primary Keyvới bảng cha.

Trong sơ đồ bảng trên, idcột trong post_detailsbảng cũng có Foreign Keymối quan hệ với cột postbảng id Primary Key:

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

Nhiều nhiều

Mối quan hệ nhiều-nhiều-bảng trông như sau:

Nhiều nhiều

Trong một hệ thống cơ sở dữ liệu quan hệ, mối quan hệ nhiều-nhiều bảng liên kết hai bảng cha thông qua một bảng con chứa hai Foreign Keycột tham chiếu các Primary Keycột của hai bảng cha.

Trong sơ đồ bảng ở trên, post_idcột trong post_tagbảng cũng có Foreign Keymối quan hệ với cột postid bảng Primary Key:

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

Và, tag_idcột trong post_tagbảng có Foreign Keymối quan hệ với cột tagid bảng Primary Key:

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

3

Mối quan hệ 1-1 (1-1): Đây là mối quan hệ giữa khóa chính & khóa ngoài (khóa chính liên quan đến khóa ngoài chỉ có một bản ghi). đây là một mối quan hệ

Mối quan hệ Một đến Nhiều (1-M): Đây cũng là mối quan hệ giữa các mối quan hệ khóa chính & khóa ngoài nhưng ở đây khóa chính liên quan đến nhiều bản ghi (ví dụ Bảng A có thông tin sách và Bảng B có nhiều nhà xuất bản của một cuốn sách).

Nhiều đến nhiều (MM): Nhiều đến nhiều bao gồm hai chiều, được giải thích đầy đủ như dưới đây với mẫu.

-- 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
Sẽ tốt hơn và rõ ràng hơn nếu bạn cũng đã thêm các ràng buộc khóa chính và khóa ngoài.
Ashish K Gupta
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.