RDMS/PostgreSQL

[PostgreSQL] 제약조건에 대해서(PRIMARY KEY, UNIQUE, NOT NULL, CHECK) - 컴도리돌이

컴도리돌이 2024. 8. 29. 09:00
728x90

PostgreSQL에서 제약조건에 대해 글을 남겨보려고 해요. 제약조건은 데이터베이스에서 우리가 입력하는 데이터가 올바르고 일관되도록 도와주는 규칙이라 생각하면 돼요. 예를 들어, 고객의 이메일 주소가 잘못 입력되었을 때 이를 방지할 방법이 없다고 하면 큰일이겠죠? 그래서 제약조건에 대해 아는 것은 매우 중요해요. 그럼 예시 코드를 보면서 자세히 알아보겠습니다 😆

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    age INT CHECK (age >= 0)
);

 

이 예시에는 users라는 테이블을 생성하였는데, 여기서 주목할 부분은 PRIMARY KEY, UNIQUE, NOT NULL, CHECK 같은 키워드들이에요. 각각이 제약조건으로 사용되죠.

 

PRIMARY KEY는 각 행을 유일하게 식별하는 키에요. 중복될 수 없고, NULL 값도 허용되지 않아요 😤 

UNIQUE는 중복을 막아주는 역할을 해요. 예를 들어, email 필드에 제약조건을 설정하면 동일한 이메일이 두 번 생성할 수 없어요 🙅‍♂️

NOT NULL은 필드가 비어있으면 안 된다는 의미를 갖고 있어요. 예를 들어, username이나 email이 없으면 사용자 계정이 의미가 없어지겠죠? 그럴 때는 NOT NULL로 설정하여, 생성할 때 값이 비어있는 것을 막아줍니다

마지막으로 CHECK은 특정 조건을 만족하는지 확인을 해줍니다. 여기서는 age >= 0을 체크하는데, 나이가 음수가 될 수 없다는 것을 의미담아 설정하였습니다. 😊 이제 각각을 조금 더 세세하게 확인 해볼게요.


PRIMARY KEY

PRIMARY KEY는 테이블 내에서 각 행을 고유하게 식별할 수 있도록 하는 제약조건이에요. 테이블을 생성할 때 기본 키를 설정하는 가장 간단한 방법은 다음과 같아요.

CREATE TABLE users (
    user_id SERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL
);

 

여기서 user_id는 자동으로 증가하는 고유 값이 되며, 이 값이 테이블 내에서 유일하다는 것을 보장해줘요. 또한 여러 컬럼을 묶어서 복합 기본 키(Composite Primary Key)로 설정할 수 있어요. 예를 들어, 주문 테이블에서 order_idproduct_id의 조합을 기본 키로 다음과 같이 만들 수 있어요. 

CREATE TABLE order_items (
    order_id INT,
    product_id INT,
    quantity INT NOT NULL,
    PRIMARY KEY (order_id, product_id)
);

NOT NULL

NOT NULL은 특정 컬럼에 NULL 값이 들어가는 것을 막는 제약조건이에요. 필수 값이 필요한 컬럼에 사용됩니다. 

CREATE TABLE employees (
    employee_id SERIAL PRIMARY KEY,
    first_name VARCHAR(50) NOT NULL,
    last_name VARCHAR(50) NOT NULL
);

 

여기서는 first_namelast_naem이 반드시 입력되도록 하는 제약조건을 설정했어요. 또한 이미 존재하는 테이블에 새로운 컬럼을 추가하면서 NOT NULL 제약 조건을 적용하는 방법도 있어요.

ALTER TABLE employees ADD COLUMN email VARCHAR(100) NOT NULL;

 

또한 CHECK와 함께 사용해 특정 조건이 충족되지 않으면 NOT NULL로 설정하는 복합적인 조건을 적용할 수 도 있어요.

ALTER TABLE employees ADD CONSTRAINT check_name 
CHECK (first_name IS NOT NULL AND last_name IS NOT NULL);

 

이 예시에는 두 필드가 모두 NULL이 아닌 경우에만 데이터가 유효하다고 체크를 합니다.


UNIQUE

UNIQUE 제약조건은 특정 컬럼의 값이 테이블 내에서 중복되지 않도록 보장해요. 

CREATE TABLE customers (
    customer_id SERIAL PRIMARY KEY,
    email VARCHAR(100) UNIQUE
);

 

여기서는 email 필드가 테이블 내에서 중복되지 않도록 설정했어요. 또한 여러 컬럼의 조합에 대해 UNIQUE 제약 조건을 설정할 수 있어요. 예를 들어, 동일한 사용자가 동일한 제품을 두 번 이상 리뷰할 수 없도록 하는 제약 조건을 설정하면 다음과 같아요.

CREATE TABLE product_reviews (
    review_id SERIAL PRIMARY KEY,
    product_id INT NOT NULL,
    customer_id INT NOT NULL,
    review_text TEXT,
    CONSTRAINT unique_review UNIQUE (product_id, customer_id)
);

 

이 설정은 product_idcustomer_id의 조합이 고유해야 한다는 것을 보장하며, 동일한 고객이 동일한 제품에 대해 두 번 리뷰를 남기지 못하게 할 수 있습니다. 


CHECK

CHECK 제약 조건은 특정 컬럼의 값이 특정 조건을 만족하는지 검증해요. 가장 간단한 예로, 나이가 음수가 될 수 없도록 하는 조건을 설정해볼게요. 

CREATE TABLE members (
    member_id SERIAL PRIMARY KEY,
    age INT CHECK (age >= 0)
);

 

또는 복잡한 논리적 조건을 사용하여 CHECK 제약 조건을 설정할 수 있어요. 예를 들어, 직원의 월급이 특정 직급에 따라 달라져야 한다는 조건을 걸어볼게요.

CREATE TABLE salaries (
    employee_id SERIAL PRIMARY KEY,
    position VARCHAR(50),
    salary DECIMAL(10, 2),
    CHECK (
        (position = 'Manager' AND salary >= 5000) OR
        (position = 'Developer' AND salary >= 3000) OR
        (position = 'Intern' AND salary >= 1000)
    )
);

 

이 예에서는 직원의 직급에 따라 최소 급여를 달리 설정해줍니다. CHECK 제약조건을 사용하여 이러한 복잡한 비즈니스 로직을 데이터베이스 레벨에서 직접 구현할 수 있어요


졔약 조건에 대해서...

제약 조건은 데이터를 더 안전하게 만드는 설정이지만, 모든 경우에 적용할 필요는 없습니다. 예를 들어, 임시로 데이터를 저장하거나, 아주 유연한 데이터 구조가 필요한 경우라면 제약조건이 오히려 불편할 수 있겠죠? 또한 너무 많은 제약조건을 걸면 데이터베이스의 성능이 떨어질 수 있어요. 특히 대량의 데이터를 삽입하거나 업데이트할 때 제약조건을 모두 검사해야 하니까요 🤔 그래서 필요한 제약조건만 적절히 사용하는 게 중요합니다. 

 

아래는 SQL server에서 Check 제약조건이 성능에 미치는 영향을 다룬 기사를 갖고 왔어요.🙄 제약조건이 데이터 삽입 및 업데이트 시 성능 저하를 일으킬 수 있다고 설명이 되어있으니 궁금하신 분은 들어가 보시면 됩니다. 

 

Performance Impact of SQL Server Check Constraints

This article explores check constraints in SQL Server and the impact they have or don't have on performance.

www.mssqltips.com

 

또한, 데이터베이스 설계 시 제약조건을 너무 많이 사용하면 시스템이 덜 유연해지고 테스트가 어려워질 수 있는 단점도 있습니다. 

 

Database constraints considered harmful?

In relational databases it's common practice to create constraints to lock down the data and its...

dev.to

 

그러면 제약조건을 어떻게 설정해야 잘 썼다고 소문이 날까요? 🥲 

 

적재적소에 제약조건을 사용하는 것이 중요해요. 너무 많지도, 너무 적지도 않게, 딱 필요한 만큼만 설정하는 것이 핵심이죠. 예를 들어 중요한 정보에만 NOT NULL이나 UNIQUE 같은 제약조건을 걸어둔다면, 데이터베이스의 무결성을 자연스럽게 유지할 수 있겠죠? 반면에 불필요하게 복잡한 제약조건을 남발하면 오히려 데이터베이스 관리가 어려워질 수 있어요. 그래서 필요한 곳에 적절하게!라는 원칙을 기억하면 좋겠죠. 다음 포스팅에는 제약조건을 어떻게 알맞게! 설정할지에 대해 글을 작성해 보려고 해요. 그럼 20000 ✋


 

5.4. Constraints

5.4. Constraints # 5.4.1. Check Constraints 5.4.2. Not-Null Constraints 5.4.3. Unique Constraints 5.4.4. Primary Keys 5.4.5. Foreign Keys 5.4.6. Exclusion Constraints …

www.postgresql.org

 

Constraints in PostgreSQL - Postgres With Example

Navigate the world of PostgreSQL Constraints with this overview guide. Learn what constraints are, why they're important, and get introduced to different types of constraints like PRIMARY KEY, FOREIGN KEY, UNIQUE, and CHECK. Practical examples with the tv_

postgreswithexample.com

 

[PostgreSQL] 제약조건 (Constraint) 개념 및 설정 (Primary Keys, Foreign Keys, Unique, Not null, Check)

PostgreSQL 제약조건 (Constrant)란? 데이터베이스는 데이터 타입 외에 제약조건들을 통해 데이터의 무결성을 유지한다. 제약조건에는 여러 가지 종류가 있으며 DMBS에 마다 다양하지만, 이번 포스트는

junhkang.tistory.com