Database/MySQL

MySQL) constraint(무결성) : Primary Key / Unique Key / Foreign Key / check / not null / default 개념 및 쿼리로 이해하기

pogun 2025. 2. 9. 22:07
제약 조건 NULL 허용 중복 허용 특징
PK (기본키) X X 한 테이블에 하나만 가능, 유일한 값 보장
UK (고유키) O X 중복 불가, NULL 가능, 여러 개 선언 가능
FK (외래키) O (옵션) O 다른 테이블의 PK/UK를 참조, 참조 무결성 보장
CHECK O O 특정 조건을 만족하는 값만 허용
NOT NULL X O NULL 값 입력 불가
DEFAULT X X 값이 없을 때 자동으로 기본값 설정

1. Primary Key (PK) - 기본키

: 테이블에서 각 행을 유일하게 식별하는 키

: NULL 값 허용 불가, 중복 불가

: 한 테이블에 하나만 존재 가능

: 기본키는 자동으로 Unique + Not Null 속성 포함

2. Unique Key (UK) – 고유키

: NULL 값 허용 (1개 이상 가능), 하지만 중복 불가

: 한 테이블에 여러 개 존재 가능

: Primary Key와 달리, NULL값을 허용할 수도 있음

3. Foreign Key (FK) – 외래키

: 한 테이블의 컬림이 다른 테이블의 PK 또는 UK를 참조

: 기본적으로 NULL 허용 가능, 하지만 NOT NULL로 설정 가능

: 참조 무결성을 유지하여 데이터 일관성 보장

: 삭제/수정 시 CASCADE, SET NULL, RESTRICT 옵션 사용 가능

4. CHECK – 특정 값만 허용

: 설정(지정값, 범위값)된 값만을 사용할 수 있다.

: NULL 허용 가능

: 특정 컬럼의 값이 정해진 조건을 만족해야 함

: 숫자 범위, 특정 값만 입력되도록 제한 가능

5. NOT NULL – NULL 값 허용 불가

: 컬럼에 반드시 값이 입력되어야 함

: NULL을 허용하지 않는 경우 사용

6. DEFAULT – 기본값 설정

: 값이 입력되지 않으면 자동으로 기본값이 설정됨

: NULL 값이 입력되면 기본값이 적용되지 않음


코드로 이해하기(1 ~ 6)

1. Primary Key (PK) - 기본키

create table tb_primary(
    id varchar(30) primary key,
    name varchar(30)
);

insert into tb_primary(id, name)
values('aaa', '홍길동');

insert into tb_primary(id, name)   -- 다시하면 aaa가 이미 있기때문에 에러발생(PK는 중복 허용 x)
values('aaa', '홍길동');

insert into tb_primary(name)    -- 에러(pk는 반드시 값이 있어야함.)
values('일지매');

insert into tb_primary(id)      -- 이건 됨
values('ccc');

: aaa가 이미 있기 때문에 중복 에러 발생(중복 허용 x)

: 일지매도 id 값이 있어야 하기 때문에 에러 발생(null값 허용 x)

 

Primary Key 추가 설정하는 방법

create table tb_primary(
    id varchar(30),
    name varchar(30)
);
alter table tb_primary  -- 추가하는 방법
add primary key(id);

 

Primary Key 삭제 : not null은 남음

alter table tb_primary
drop primary key;

: MySQL 에디터로 확인해보니 PK는 삭제되는데 NL은 남아있음

 

무결성까지 삭제하는 방법

drop table if exists tb_primary;

: 추가 설정, 삭제, 무결성까지 삭제 모두 동일한 방법으로 UK도 된다고 알고있음

2. Unique Key (UK) – 고유키

create table tb_unique(
    email varchar(30) unique key,
    memo varchar(50)
);

insert into tb_unique(email, memo)
values('abc@naver.com', '약속');
insert into tb_unique(email, memo)  -- 중복 허용 x
values('abc@naver.com', '약속');
insert into tb_unique(memo)     -- null값 허용
values('구경');

: null은 ok, 중복은 no

: 주석문보면 이해가 될것임!

3. Foreign Key (FK) – 외래키

-- 부모 테이블
create table dept(
    department_id int primary key,
    department_name varchar(30)
);
-- 부모 테이블
create table dept(
    department_id int unique key,
    department_name varchar(30)
);

insert into dept(department_id, department_name)
values(10, '기획부');
insert into dept(department_id, department_name)
values(20, '영업팀');
insert into dept(department_id, department_name)
values(30, '개발팀');

: FK나 UK에 참조 가능함

: 둘다 가능하단 걸 보여주기 위해 두 테이블을 만든 것!

-- 자식 테이블
create table emp(
    employee_id int primary key,
    first_name varchar(20),
    department_id int,
    foreign key(department_id) references dept(department_id)
);

insert into emp(employee_id, first_name, department_id)
values(100, '홍길동', 30);
insert into emp(employee_id, first_name, department_id)
values(200, '성춘향', 40);   -- errer(부모테이블에 40이 없음)
insert into emp(employee_id, first_name)
values(200, '성춘향');       -- null값 허용이라 이렇게해도 됨

참조 형식 : foreign key(컬럼명) references 참조할 테이블명(PK or UK 컬럼명)

: 성춘향의 경우 테이블 조회 결과가 아래 그림처럼 나옴

CREATE TABLE users (
    user_id INT PRIMARY KEY,
    name VARCHAR(50)
);

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    user_id INT,  -- users 테이블의 user_id를 참조하는 외래키
    FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE
);

: ON DELETE CASCADE → users 테이블에서 user_id가 삭제되면, orders 테이블의 해당 데이터도 삭제됨

4. CHECK – 특정 값만 허용

create table tb_check(
    name varchar(30),
    fruit varchar(20),
    -- fruit varchar(20) check(fruit in('apple', 'pear', 'banana') 이렇게도 가능 
    num int, 
    constraint check1 check(fruit in('apple', 'pear', 'banana')),
    constraint check2 check(num > 0 and num <= 10)
);

insert into tb_check(name, fruit, num)
values('홍길동', 'apple', 6);
insert into tb_check(name)               -- null 허용
values('성춘향');
insert into tb_check(name, fruit, num)   -- grape는 지정 안해줌
values('일지매', 'grape', 7);
insert into tb_check(name, fruit, num)   -- 33은 지정 안해줌
values('일지매', 'pear', 33);

: null값은 허용

: 지정 안해준 값은 에러

5. NOT NULL – NULL 값 허용 불가

create table tb_test(
    name varchar(30) not null,
    phon varchar(30)
);

insert into tb_test(name, phon)
values('홍길동', '123-2341');
insert into tb_test(name)
values('성춘향');
insert into tb_test(phon)  -- error(name에 null값이 들어가니!)
values('231-3123');
insert into tb_test(name)  -- 빈문자도 들어간다 주의!!
values('');

: null과 빈문자는 다른 의미임! 그러니까 주의!

6. DEFAULT – 기본값 설정

create table orders (
    order_id INT PRIMARY KEY,
    status VARCHAR(20) DEFAULT 'pending'  -- 기본값을 'pending'으로 설정
);

insert into orders(order_id) 
values (1);

: INSERT INTO orders (order_id) VALUES (1); 하면 status 컬럼은 'pending' 자동 입력

: null값 대신에 'pending'으로 설정