테이블을 디자인하면서 일대일, 일대 다 및 다 대다 관계를 구현하는 방법은 무엇입니까?


281

누구나 예제를 사용하여 테이블을 디자인하면서 일대일, 일대 다 및 다 대다 관계를 구현하는 방법을 설명 할 수 있습니까?


대상 RDBMS에 따라 구현이 달라지는 경향이 있으므로 어떤 공급 업체를 타겟팅하고 있습니까?
billinkc

1
숙제 질문이 아닙니다 ... !! 나는 인터뷰를 준비하고있다. 그래서 여기에서 물어볼 생각이있다. 나는 인터넷 검색을 시도했지만 이것들을 모두 설명하는 좋은 기사를 찾지 못했다.
무기고

오라클 데이터베이스를 대상으로합니다 .. !!
무기고

이 글도 읽을 수 있습니다 .... stevencalise.wordpress.com/2010/09/01/… 포인트 2와 3에주의를 기울일 것입니다 .
tsells September

3
@tsells 때로는 이력서의 내용이나 직무 요구 사항에 적용되지 않는 질문을받는 경우가 있습니다. 한 회사에서 저를 인터뷰 할 사람들의 명단을 받았으며 한 명은 DB 전문가였습니다. 나는 이력서에 SQL을 가지고 있지 않았지만 몇 가지 간단한 SQL 쿼리를 작성했습니다. 나중에 채용 관리자가 지원자들이 압력을 받고 어떻게 대응하는지에 대해 우려하는 것을 알게되었습니다. 그들은 한계를 인정하거나 길을 허비합니까? 그들이 한계를 인정하면 어쨌든 시도하거나 너무 빨리 포기합니까?
Doug Cuthbertson

답변:


478

일대일 : 참조 테이블에 외래 키를 사용하십시오.

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

또한 addess.student_id하위 테이블 ( address) 의 여러 행 이 참조 된 테이블 ( student) 의 동일한 행과 관련 되지 않도록 외래 키 열 ( ) 에 고유 제한 조건을 설정해야합니다 .

일대 다 : 관계의 많은 부분에서 외래 키를 "일"쪽으로 다시 연결하십시오.

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

다 대다 : 접합 테이블을 사용하십시오 ( ).

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

쿼리 예 :

 -- 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
"다시 링크"가 일대일 관계에 유용한 경우의 좋은 예는 무엇입니까? 명확하고 간결한 답변에 감사드립니다.
dev_feed

1
@dev_feed 데이터베이스 디자인 측면에서 링크가 유익하다는 것을 알지 못하지만 위의 예를 사용하면 student주어진을 쉽게 찾을 수 address있습니다.
edhedges

@ NullUserException 우리는 다 대 다 관계에 대해 3 개의 테이블이 필요합니다 .2 대 테이블 대 다 관계에 의해 수행 될 수 없습니다.

1
@Cody 각 student_classes행에는 일대일 관계가 있어야합니다. 경우 studentAclassA그리고 classB, 다음에 두 개의 행이 있어야 student_classes어느 하나의 관계.
NullUserException

11
일대일 관계에서 조인 필드는 두 테이블에서 고유해야합니다. 고유성을 보장하는 한 테이블의 PK 일 가능성이 있지만 다른 테이블의 고유 인덱스가 필요할 수 있습니다.
HLGEM

70

다음은 관계 유형에 대한 실제 예입니다.

일대일 (1 : 1)

테이블 A의 하나의 레코드가 테이블 B의 최대 하나의 레코드와 관련되는 경우에만 관계가 일대일입니다.

일대일 관계를 설정하려면 테이블 B의 기본 키 (고아 레코드 없음)가 테이블 A의 보조 키 (고아 레코드 있음) 여야합니다.

예를 들면 다음과 같습니다.

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

일대 다 (1 : M)

테이블 A의 하나의 레코드가 테이블 B의 하나 이상의 레코드와 관련된 경우에만 관계가 일대 다입니다. 그러나 테이블 B의 하나의 레코드가 테이블 A의 하나 이상의 레코드와 관련 될 수는 없습니다.

일대 다 관계를 설정하려면 테이블 A의 기본 키 ( "하나"테이블)는 테이블 B의 보조 키 ( "다") 테이블이어야합니다.

예를 들면 다음과 같습니다.

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

다 대다 (M : M)

테이블 A의 한 레코드가 테이블 B의 하나 이상의 레코드와 관련이 있고 그 반대의 경우에만 관계는 다 대다입니다.

다 대다 관계를 설정하려면 테이블 A와 테이블 B의 기본 키가있는 "ClassStudentRelation"이라는 세 번째 테이블을 작성하십시오.

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

첫 번째 예 : GID 번호 (6) 및 SGID 번호 (4), 왜? SGID도 (6)이 아니어야합니까? 그리고 2 예 번호 (4)와 수 (2) ...에서
obeliksz

@obeliksz는 null 일 수 있습니까?
moo cow

M : N 끝에 UNIQUE (StudentID, ClassID)를 사용하는 이유는 무엇입니까?
strix25

1
@ strix25 동일한 ClassStudentRelation 행을 여러 번 만들 때 반복하지 않도록하려면 외래 키 StudentID와 ClassID를 모두 고유하게하지 않으면 StudentID와 ClassID가 같은 새 행을 만드는 것이 무엇입니까? 위 코드에서 고유하지 않기 때문입니다. 따라서 위의 코드와 같이 구현하거나 ClassStudentRelation에서 동일한 행을 반복하지 않도록 StudentID와 ClassID가 모두 포함 된 기본 키를 추가하십시오.
Fouad Boukredine

1
@valik 데이터베이스의 데이터는 기존 데이터를 참조하여 작동하며 동일한 데이터를 여러 번 만들지 않는 이유는 무엇입니까? 물론 필요하지 않습니다. 그렇지 않으면 효율적이지 않습니다. 이를 염두에두고 예제로 돌아가 봅시다 (제임스에는 생물학이 있고 생물학에는 제임스가 있습니다). 물론 데이터베이스에 이미 존재하는 다른 데이터를 만들지 않고도 가능합니다. 관계를 만들 때마다 기존 관계를 참조하기 만하면됩니다. 그게 :) 도움이되기를 바랍니다
푸 아드 Boukredine

8

이것은 매우 일반적인 질문이므로이 답변을 기사 로 전환하기로 결정했습니다 .

일대 다

일대 다 테이블 관계는 다음과 같습니다.

일대 다

관계형 데이터베이스 시스템에서 일대 다 테이블 관계 는 부모 테이블 행 Foreign Key을 참조하는 자식 의 열을 기준으로 두 테이블을 연결 Primary Key합니다.

위 표 다이어그램에서 post_id에서 열 post_comment테이블이 갖는 Foreign Key와 관계 post테이블 아이디 Primary Key칼럼 :

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

1-1

일대일 테이블 관계는 다음과 같습니다.

1-1

관계형 데이터베이스 시스템에서 일대일 테이블 관계 는 상위 테이블 행 Primary KeyForeign Key참조 를 나타내는 하위 의 열을 기반으로 두 테이블을 연결 Primary Key합니다.

따라서 자식 테이블 Primary Key과 부모 테이블을 공유한다고 말할 수 있습니다 .

위 표 다이어그램에서 id에서 열 post_details테이블도 가지고 Foreign Key와 관계 post테이블 id Primary Key칼럼 :

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

다 대다

다 대다 테이블 관계는 다음과 같습니다.

다 대다

관계형 데이터베이스 시스템에서 다 대다 테이블 관계는 두 개의 상위 테이블의 Foreign Key열을 참조하는 두 개의 열 이 포함 된 하위 테이블을 통해 두 개의 상위 테이블을 연결합니다 Primary Key.

위의 테이블 다이어그램에서 테이블의 post_id열 은 테이블 ID 열과 관계 post_tag가 있습니다 .Foreign KeypostPrimary Key

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

그리고 테이블 의 tag_id열 은 테이블 ID 열과 관계가 있습니다 .post_tagForeign KeytagPrimary Key

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

3

일대일 관계 (1-1) : 기본 키와 외래 키 간의 관계입니다 (외래 키와 관련된 기본 키는 하나의 레코드 만). 이것은 일대일 관계입니다.

일대 다 (1-M) 관계 : 이것은 기본 키와 외래 키 관계 사이의 관계이지만 여기서는 여러 레코드와 관련된 기본 키입니다 (예 : 테이블 A에는 책 정보가 있고 테이블 B에는 한 권의 책이 여러 개 있습니다).

대다 (MM) : 다 대다 (2 대)에는 2 차원이 포함되어 있으며 샘플과 함께 아래에 자세히 설명되어 있습니다.

-- 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
기본 키 및 외래 키 제약 조건을 추가했다면 더 좋고 명확했을 것입니다.
Ashish K Gupta
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.