MySQL

(DB)PRIMARY KEY, FOREIGN KEY, UNIQUE 란 뭘까? - 12

mynote6676 2025. 5. 12. 19:01

학습 목표

-MySQL의 PRIMARY KEY, UNIQUE KEY, FORELGN KEY 개념 이해

-각 키의 역할, 차이점, 활용 시나리오 학습

---------------------------------------------------------------------------------------------------------------------------------

1. 키 제약 조건이란?

더보기

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

 

주요 키 제약 조건

- PRIMARY KEY: 테이블의 각 행을 고유하게 식별.

- UNIQUE KEY : 특정 열(또는 열 조합)의 값이 중복되지 않도록 보장.

- FOREIGN KEY : 테이블 간 관계를 형성하고 참조 무결성을 유지.

2. 키 제약 조건 요약

더보기
구분 PRIMARY KEY(기본 키 ) UNIQUE KEY(고유 키) FOREIGEN KEY(외래 키)
역활 행을 고유하게 식별 값의 중복 방지 다른  테이블의 키 참조
중복허용 불가능 불가능 가능
NULL 허용 불가능 가능(MySQL) 가능 
자동 인덱스 생성 생성 X(권장)
예시 id email member_id -> member(id)

3. 각 키에 대한 상세 설명

더보기

PRIMARY KEY(기본 키)

 

역활 : 테이블의 각 행을 고유하게 식별하는 식별자.

특징: 

-중복값과 NULL값 불가.

-테이블당 하나의 PRIMARY KEY 만 가능

-자동으로 고유 인덱스 생성.

예시 : 회원 테이블에서 각 회원을 구분하는 id.

쿼리 예시

 

id INT PRIMARY KEY AUTO_INCREMENT

------------------------------------------------------------------------------------------------------------------

UNIQUE KEY (고유 키)

 

역활: 특정 열(또는 열 조합)의 값이 중복되지 않도록 보장.

특징: 

- 중복값 불가, MySQL에서는 NULL값 여러 개 허용.

-테이블에 여러 UNLQUE KEY 설정 가능

- 자동으로 고유 인덱스 생성.

예시 :회원의 이메일(email)이 중복되지 않도록 설정.

쿼리 예시:

email VARCHAR(100) UNIQUE

------------------------------------------------------------------------------------------------------------------

FOREIGN KEY(외래 키)

역활 : 다른 테이블의 PRIMARY KEY 또는 UNIQUE KEY를 참조하여 테이블 간 관계 형성

특징 

-참조하는 값은 상대 테이블에 존재해야 함.

-NULL 허용 가능 (설정에 따라 다름)

- 참조 무결성 유지(예 : 참조된 행 삭제 시 제약 설정 가능)

-MySQL(lnnoDB)에서 지원, 인덱스 생성 권장.

예시 : 주문 테이블의 member_id가 회원 테이블의 id 를 참조

쿼리 예시;

member_id INT,

FOREIGN KEY (member_id) REGERENCES member(id)

4. 실습해 보기

 

-- member 데이터 설계 (기본키와 고유키 설계)

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

);

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-5--11',5000);

-- 데이터 삽입 불가 : 없는 member_id라서
insert into orders(member_id,order_date, amount)values
(30,'2025-5--11',15000);

insert into orders(member_id,order_date, amount)values
(2,'2025-5--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; 

-- 존재하지 않는 회원을 orders 테이블에 추가 해보자
insert into orders (member_id, order_date, amount)values 
(999, '2023-10-04', 10000);

-- 테스트 코드 작성해보세요 
insert into orders (member_id, order_date, amount) values
(2, '2025-05-12', 3000);

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

insert into orders (member_id, order_date, amount) values
(1, '2025-05-12', 13000);
insert into orders (member_id, order_date, amount) values
(1, '2025-05-12', 23000);

delete from orders where member_id = 2;

 

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

더보기

1.중복 이메일 삽입 시도

INSERT INTO menber (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;

-결과 : order테이블에서 member_id = 1을 참조하므로 오류 발생.

 

4.FOREIGN KEY 동작 설정

ALTER TABLE orders

DROP FOREIGN KEY oreders_ibfk_1; -- 기존 외래 키 삭제

 

ALTER TABLE orders

ADD CONSTARINT 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 COMSTRAINT unique_city_zip UNIQUE (city, zipcode);

 

실습코드

 

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

-- 기존에 있던 외래키 삭제하기
-- 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 table에 회원이 주문한 정보가 있을 때 member table에 회원 정보를 삭제할 때 바로 삭제가 안되었다.
-- 그래서 orders 테이블에 정보를 삭제하고 member 에 회원 정보를 삭제할 수 있었다.
select * from orders;
select * from member;
delete from member where id = 2;

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@naver.com', '유관순', '010-1234-1234', '부산','464-123');

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

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

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

7. 정리