[SQL] 일대다 관계 - PK, FK

준우·2022년 7월 13일
0

SQL

목록 보기
3/4
post-thumbnail

일대다 관계

  • One to Many
  • 1:N Relationship
    (has_many)

일대다 관계는 1개의 데이터가 N개의 데이터를 포함할 수 있는 관계를 말한다. 1명의 회원이 N개의 게시글을 작성하거나, 1개의 게시글에 N개의 댓글이 달릴 수 있는 상황을 예시로 들 수 있다.

일대다 관계는 N개의 입장에서 보면 다대일 관계, 즉 One to Many로 표현할 수도 있다.

PK와 FK

PK(Primary Key) : 레코드를 대표하는 유일한 값
FK(Foreign Key) : 참조 값

일대다 관계에서 1개의 데이터는 PK (Primary Key), N개의 데이터는 FK(Foreign Key)로 연결된다.

1개 계정에 N개의 사진이 게시된다면 유저 계정 id와 사진 id는 PK, 사진이 소속된 유저 계정 즉, user_id는 FK가 된다.

PK는 레코드를 대표하는 유일 한 값이며 보통 id 컬럼으로 통용되고, DB에 의해 자동 생성된다.

PK 생성 예시

CREATE TABLE users (
id SERIAL PRIMARY KEY,
...
);

위 예시에서 SERIAL은 DB에서 자동 생성되는 값, PRIMARY KEY 는 레코드를 대표하는 유일한 값이다.

  • SERIAL : Auto Generated Value
  • PRIMARY KEY : Representative & Unique

FK 생성 예시

CREATE TABLE photos (
...
user_id INTEGER REFERENCES user(id),
);

user_id는 컬럼의 이름, INTEGER은 컬럼의 타입을 지정하는 값이고 REFERENCES 는 FK를 설정하기 위한 예약어, users(id)는 users 테이블의 id 컬럼을 참조하겠다는 타겟 언어다.

  • user_id : Column Name
  • INTEGER : Column Type
  • REFERENCES : Setting Foreign Key
  • users(id) : Target PK

인스타그램 DB 실습

users 테이블

테이블 생성

CREATE TABLE users(
	id SERIAL PRIMARY KEY,
	nickname VARCHAR(50),
	email VARCHAR(100)
);

유저의 id 를 users 테이블을 대표하는, 자동생성되는 고유한 값으로 설정하기 위해 SERIAL, PRIMARY KEY 예약어를 사용했고, nickname은 최대 50자의 문자열, email은 최대 100자의 문자열로 설정한다.

레코드 등록

INSERT INTO 
	users(nickname, email)
VALUES
  ('cloudstudying_kr', 'mail@cloudstudying.kr'),
  ('hongpark_cs',      'sehongpark@cloudstudying.kr'),
  ('haesamq',          'haesamq@naver.com')
;

위에서 만든 users 테이블에 닉네임과 이메일을 설정해준다. 여기서 id 컬럼은 SERIAL 예약어를 통해 DB에서 자동생성되므로 값을 지정하지 않아도 된다.

photos 테이블

테이블 생성

CREATE TABLE photos (
  id       SERIAL        PRIMARY KEY, 
  filename VARCHAR(255),
  user_id  INTEGER       REFERENCES users(id) 
);

SERAIL PRIMARY KEY 예약어로 사진의 id를 PK로 지정하고, REFERENCES users(id)로 user_id를 FK로 지정하며 사진 게시자의 PK로 연결한다.

레코드 등록

INSERT INTO
  photos(filename, user_id)
VALUES
  -- 1번 유저의 사진 업로드
  ('cat-on-road.jpg',           1),
  ('sunset-over-the-ocean.jpg', 1),
  ('andromeda-galaxy.jpg',      1),
  
  -- 2번 유저의 사진 업로드 
  ('white-tiger.jpg',        2),
  ('nero-the-black-cat.jpg', 2);

comments 테이블

테이블 생성

CREATE TABLE comments (
  id       SERIAL         PRIMARY KEY, -- PK
  body     VARCHAR(1000),
  user_id  INTEGER        REFERENCES users(id), -- FK: 댓글 작성자
  photo_id INTEGER        REFERENCES photos(id) -- FK: 댓글이 달린 사진
);

레코드 등록

INSERT INTO
  comments(body, user_id, photo_id)
VALUES
  -- 1번 사진의 댓글들
  ('meow',   1, 1), -- 유저#1
  ('nyaong', 2, 1), -- 유저#2
  ('냐옹',    3, 1), -- 유저#3
  -- 2번 사진의 댓글들
  ('sunset',         1, 2), -- 유저#1
  ('falling slowly', 2, 2), -- 유저#2
  -- 3번 사진의 댓글들
  ('Andromeda galaxy', 1, 3), -- 유저#1
  ('mysteriouse..!',   3, 3)  -- 유저#3
;

관계도

users, photos, comments 세 개 테이블의 각 PK, FK 관계도는 위와 같다.

🙏 Reference

0개의 댓글