MySQL

PRIMARY KEY, FOREIGN KEY, UNIQUE KEY 란 뭘까?

whs5758 2025. 5. 12. 18:02

1. 키 제약 조건이란?

키 제약 조건(Key Constraints)은 데이터베이스 테이블에서 데이터 무결성(Integrity)과 일관성 (Consistency)을 보장하기 위해 사용되는 규칙입니다. 각 키는 테이블의 데이터를 어떻게 저장하고 관리할지 정의하며, 잘못된 데이터 입력을 방지합니다.

주요 키 제약 조건

  • PRIMARY KEY: 테이블의 각 행을 고유하게 식별.
  • UNIQUE KEY: 특정 열(또는 열 조합)의 값이 중복되지 않도록 보장.
  • FOREIGN KEY: 테이블 간 관계를 형성하고 참조 무결성을 유지.

2. 키 제약 조건 요약


3. 각 키에 대한 상세 설명

🔹 PRIMARY KEY (기본 키)

  • 역할: 테이블의 각 행을 고유하게 식별하는 식별자.
  • 특징:
    • 중복값과 NULL 값 불가.
    • 테이블당 하나의 PRIMARY KEY만 가능.
    • 자동으로 고유 인덱스 생성.
  • 예시: 회원 테이블에서 각 회원을 구분하는 id.
  • 쿼리 예시:
id INT PRIMARY KEY AUTO_INCREMENT

🔹 UNIQUE KEY (고유 키)

  • 역할: 특정 열(또는 열 조합)의 값이 중복되지 않도록 보장.
  • 특징:
    • 중복값 불가, MySQL에서는 NULL 값 여러 개 허용.
    • 테이블에 여러 UNIQUE KEY 설정 가능.
    • 자동으로 고유 인덱스 생성.
  • 예시: 회원의 이메일(email)이 중복되지 않도록 설정.
  • 쿼리 예시:
email VARCHAR(100) UNIQUE

🔹 FOREIGN KEY (외래 키)

  • 역할: 다른 테이블의 PRIMARY KEY 또는 UNIQUE KEY를 참조하여 테이블 간 관계 형성.
  • 특징:
    • 참조하는 값은 상대 테이블에 존재해야 함.
    • NULL 허용 가능(설정에 따라 다름).
    • 참조 무결성 유지(예: 참조된 행 삭제 시 제약 설정 가능).
    • MySQL(InnoDB)에서 지원, 인덱스 생성 권장.
  • 예시: 주문 테이블의 member_id가 회원 테이블의 id를 참조.
  • 쿼리 예시:
member_id INT,
FOREIGN KEY (member_id) REFERENCES member(id)

 


4. 실습해 보기

member 테이블

-- member 테이블 설계 (기본키와 고유키 설계해 보기) 

create table member(
	id int primary key auto_increment, 
    email varchar(100) unique,
    name varchar(50) not null, 
    phone varchar(20) 
);

select * from member; 

insert into member(email, name, phone) values
('a@naver.com', '홍길동', '010-1111-1111'),
('b@naver.com', '김영희', '010-1111-1111'),
('c@naver.com', '이철수', '010-1111-1111');

-- 중복 이메일 데이터 삽입 실패 - email 유니크 키 제약 되어 있음 
insert into member(email, name, phone) values
('a@naver.com', '이순신', '010-1111-1111');


-- orders 테이블 만들어 보기 
create table orders (
	id int primary key auto_increment, 
    member_id int, 
    order_date date, 
    amount int,
    foreign key(member_id) references member(id)
);

insert into orders(member_id, order_date, amount) values
(3, '2025-05-11', 5000); 

-- 데이터 삽입 불가 : 이유()...
insert into orders(member_id, order_date, amount) values
(30, '2025-05-11', 15000); 

insert into orders(member_id, order_date, amount) values
(2, '2025-05-11', 25000); 


select * from orders;

-- 회원 삭제 시도 
-- 삭제 실패 (orders 테이블 member 테이블 id : 3 번이 주문이 정보가 있다) 
-- delete from member where id = 3;
-- 먼저 orders 테이블에 회원 3번에 이력을 삭제를 다 하고 member 테이블에 3번을 삭제시킬 수 있다. 
delete from orders where member_id = 3; 
delete from member where id = 3;

5. 실습: 키 제약 조건 테스트

1. 중복 이메일 삽입 시도

INSERT INTO member (email, name, phone)
VALUES ('hong@test.com', '홍길동2', '010-4567-8901');
  • 결과: UNIQUE 제약 조건 위반으로 오류 발생

2. 존재하지 않는 회원의 주문 삽입

INSERT INTO orders (member_id, order_date, amount)
VALUES (999, '2023-10-04', 10000);
  • 결과: FOREIGN KEY 제약 조건 위반으로 오류 발생.

3. 회원 삭제 시도 (참조된 데이터)

DELETE FROM member WHERE id = 1;
  • 결과: orders 테이블에서 member_id=1을 참조하므로 오류 발생.

4.FOREIGN KEY 동작 설정

ALTER TABLE orders
DROP FOREIGN KEY orders_ibfk_1; -- 기존 외래 키 삭제

ALTER TABLE orders
ADD CONSTRAINT fk_member
FOREIGN KEY (member_id) REFERENCES member(id)
ON DELETE CASCADE ON UPDATE CASCADE;

  • ON DELETE CASCADE : 참조된 회원 삭제 시 관련 주문도 삭제.
  • ON UPDATE CASCADE : 회원 id 변경 시 주문의 member_id도 업데이트.

6. 복합 UNIQUE 키 추가

ALTER TABLE member
ADD COLUMN city VARCHAR(50),
ADD COLUMN zipcode VARCHAR(10),
ADD CONSTRAINT unique_city_zip UNIQUE (city, zipcode);

 

실습코드 

select * from member;
select * from orders;
-- (현재 상태) 외래키 설정 되어 있음 

-- 기존에 있던 외래키 삭제하기 
-- 1. 테이블을 드랍하고 다시 작성하기 
-- 2. 기존에 있던 외래키만 삭제 가능 

-- 테이블 구조를 변경하는 SQL 3가지 종류 DDL, DML, DCL 
alter table orders 
drop foreign key orders_ibfk_1;

insert into orders(member_id, order_date, amount) 
values(999, '2025-05-11', 10000);

-- 테이블 생성 후 외래키를 설정하는 방법 
alter table orders
add constraint fk_member
foreign key (member_id) references member(id)
on delete cascade on update cascade;


-- cascade 추가해 보기 
-- orders 테이블에 회원이 주문한 정보가 있을 때, member 테이블에 회원 정보를 삭제(업데이트)할 때 바로 삭제가 안됐다. 
-- 그래서 orders 테이블에 정보를 삭제하고 member 에 회원 정보를 삭제할 수 있었다. 
select * from orders; 
select * from member;

delete from orders where member_id = 999;
delete from member where id = 2; 


-- member 테이블이 이미 생성되어 있고 추가로 unique를 설정해 보자. (새로운 컬생 생성가 동시에 추가) 
alter table member 
add column city varchar(50), 
add column zipcode varchar(10), 
add constraint unique_city_zip unique(city, zipcode);

desc member;

select * from member;

insert into member(email, name, phone, city, zipcode)
values('c@nate.com', '유관순', '010-1234-1234', '부산', '464-123');

insert into member(email, name, phone, city, zipcode)
values('d@nate.com', '유관순2', '010-1234-1234', '부산', '464-111');

insert into member(email, name, phone, city, zipcode)
values('t@nate.com', '유관순3', '010-1234-1234', '서울', '464-123');


insert into member(email, name, phone, city, zipcode)
values('t@nate.com', '유관순3', '010-1234-1234', '서울', '464-123');

7. 정리

 

'MySQL' 카테고리의 다른 글

ERD 다이어 그램 만들어 보기  (2) 2025.05.13
관계 차수란?  (0) 2025.05.13
DELETE 연습 예제  (0) 2025.05.09
DELETE 구문과 조건절  (0) 2025.05.09
UPDATE 연습 예제  (0) 2025.05.09