SQL - 제약 조건: 데이터 통합의 열쇠

안녕하세요, 미래의 데이터 마법사 여러분! SQL 제약 조건의 세계로 인도해드리게 되어 기쁩니다. SQL을 가르쳐온 10년이 넘은 경험을 바탕으로 제약 조건을 이해하는 것은 데이터베이스 관리에서 비밀 슈퍼파워를 풀어주는 것과 같다고 말씀드릴 수 있습니다. 그麼, 시작해보겠습니다!

SQL - Constraints

SQL 제약 조건이란?

빌딩 카드를 쌓는 것을 생각해보세요. 각 카드는 정확하게 배치되지 않으면 전체 구조가 무너질 수 있습니다. SQL 제약 조건은 여러분의 데이터베이스 '빌딩 카드'가 강고하게 서 있는 것을 유지하는 규칙과 같습니다. 그들은 테이블의 데이터가 특정 규칙을 따르도록 보장하여 정확성과 일관성을 유지합니다.

왜 제약 조건이 중요한가요?

quick한 이야기를 나누겠습니다. 제가 가르쳤던 한 학생이 반려동물 가게를 위한 데이터베이스를 제약 조건 없이 만들었던 적이 있습니다. 어느 날, 그들은 실수로 강아지의 가격을 음수로 입력했습니다. 갑자기 사람들이 강아지를 입양하면서 돈을 받게 되었습니다! 혼란스러운 상황이었지만(강아지들은 행복했습니다). 이런 유형의 문제를 방지하기 위해 제약 조건이 필요합니다.

SQL 제약 조건: 라인업

다음은 우리가 탐구할 주요 SQL 제약 조건의 표입니다:

제약 조건 설명
NOT NULL 컬럼이 NULL 값을 가질 수 없도록 보장
UNIQUE 컬럼의 모든 값이 다를 수 있도록 보장
PRIMARY KEY NOT NULL과 UNIQUE의 조합
FOREIGN KEY 테이블 간의 참조 통합을 보장
CHECK 컬럼의 모든 값이 특정 조건을 만족하도록 보장
DEFAULT 컬럼에 기본 값을 설정
INDEX 데이터베이스에서 빠르게 데이터를 생성하고 검색하기 위해 사용

이제 하나씩 이를 분해해보겠습니다.

SQL에서 제약 조건을 생성하는 방법

제약 조건은 테이블을 최초로 만들 때나 ALTER TABLE 문을 사용하여 나중에 추가할 수 있습니다. 우리의 상상 속 반려동물 가게를 위한 간단한 테이블을 만들어 보겠습니다:

CREATE TABLE pets (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(50) NOT NULL,
species VARCHAR(50) NOT NULL,
age INT CHECK (age >= 0),
price DECIMAL(10, 2) NOT NULL CHECK (price > 0),
adoption_date DATE DEFAULT NULL
);

이 간단한 테이블에도 여러 가지 제약 조건이 포함되어 있습니다. 이를 하나씩 분해해보겠습니다:

NOT NULL 제약 조건

NOT NULL 제약 조건은 컬럼이 NULL 값을 가질 수 없도록 보장합니다. 우리의 예제에서 'id', 'name', 'species', 'price'는 모두 NOT NULL입니다. 이는 모든 반려동물이 이 세부 정보를 채우어야 한다는 것을 의미합니다.

name VARCHAR(50) NOT NULL,

UNIQUE 키 제약 조건

우리는 UNIQUE를 명시적으로 사용하지 않았지만, 이를 언급할 가치가 있습니다. UNIQUE 제약 조건은 컬럼의 모든 값이 다를 수 있도록 보장합니다. 예를 들어, 각 반려동물이 고유한 마이크로칩 번호를 가지기를 원한다면:

ALTER TABLE pets
ADD COLUMN microchip_number VARCHAR(20) UNIQUE;

DEFAULT 값 제약 조건

DEFAULT 제약 조건은 컬럼에 기본 값을 제공합니다. 우리의 예제에서 'adoption_date'는 DEFAULT NULL을 가지고 있습니다. 이는 날짜가 지정되지 않으면 NULL이 될 것을 의미합니다.

adoption_date DATE DEFAULT NULL

PRIMARY KEY 제약 조건

PRIMARY KEY 제약 조건은 테이블의 각 레코드를 고유하게 식별합니다. 이는 NOT NULL과 UNIQUE의 조합입니다. 우리 테이블에서 'id'는 주요 키입니다:

id INT NOT NULL PRIMARY KEY,

FOREIGN KEY 제약 조건

FOREIGN KEY 제약 조건은 테이블 간의 참조 통합을 방지하는 작업을 보장합니다. 우리는 주인 테이블을 만들고 이를 우리의 반려동물 테이블과 연결해 보겠습니다:

CREATE TABLE owners (
owner_id INT NOT NULL PRIMARY KEY,
name VARCHAR(100) NOT NULL
);

ALTER TABLE pets
ADD COLUMN owner_id INT,
ADD CONSTRAINT fk_owner
FOREIGN KEY (owner_id) REFERENCES owners(owner_id);

이제 반려동물이 주인 테이블에 존재하지 않는 주인 아이디로 추가될 수 없습니다. 이는 각 반려동물이 진짜 집을 가지도록 보장합니다!

CHECK 값 제약 조건

CHECK 제약 조건은 컬럼의 모든 값이 특정 조건을 만족하도록 보장합니다. 우리의 반려동물 테이블에서는 나이와 가격이 양수인지 확인합니다:

age INT CHECK (age >= 0),
price DECIMAL(10, 2) NOT NULL CHECK (price > 0),

INDEX 제약 조건

INDEX는 정확히 제약 조건이 아니지만, 데이터베이스 성능에 매우 중요합니다. INDEX는 책 뒤쪽의 색인과 같이 SQL이 데이터를 빠르게 찾도록 도와줍니다:

CREATE INDEX idx_species ON pets(species);

이는 종류 컬럼을 기준으로 검색을 더 빠르게 만듭니다.

SQL 제약 조건 제거

occasionally, you might need to remove a constraint. Here's how you can do it:

ALTER TABLE pets
DROP CONSTRAINT check_price;

이는 가격 컬럼의 CHECK 제약 조건을 제거합니다.

데이터 통합 제약 조건: 모두 함께 모음

모든 이 제약 조건은 데이터 통합을 보장하기 위해 함께 작동합니다. 그들은 데이터베이스의 면역 시스템과 같이 나쁜 데이터로부터 보호합니다. 더 복잡한 예제를 보겠습니다:

CREATE TABLE adoptions (
adoption_id INT NOT NULL PRIMARY KEY,
pet_id INT NOT NULL,
owner_id INT NOT NULL,
adoption_date DATE DEFAULT CURRENT_DATE,
adoption_fee DECIMAL(10, 2) CHECK (adoption_fee >= 0),
FOREIGN KEY (pet_id) REFERENCES pets(id),
FOREIGN KEY (owner_id) REFERENCES owners(owner_id),
UNIQUE (pet_id, adoption_date)
);

이 테이블은 다음을 보장합니다:

  1. 각 입양이 고유한 ID를 가지고 있습니다 (PRIMARY KEY)
  2. 각 입양이 유효한 반려동물과 주인과 연결되어 있습니다 (FOREIGN KEY)
  3. 입양료가 음수가 아닙니다 (CHECK)
  4. 입양 날짜가 지정되지 않으면 오늘 날짜를 기본으로 사용합니다 (DEFAULT)
  5. 반려동물이 같은 날에 두 번 입양되지 않습니다 (UNIQUE 조합)

이제 여러분은 데이터베이스를 깨끗하고 일관성 있게 유지하는 데 필요한 SQL 제약 조건을 잘 알고 있습니다. 잘 관리된 데이터베이스는 행복한 데이터베이스입니다. 행복하게 코딩하세요, 미래의 데이터 마에스트로!

Credits: Image by storyset