제약 조건

제약 조건 (Constraints)

SQL에서 테이블에 제약 조건(constraint)을 지정할 수 있어요. 제약 조건은 테이블에 삽입되는 데이터에 대해 특정 속성을 강제해요. 제약 조건은 [CREATE TABLE 문]({% link docs/current/sql/statements/create_table.md %})의 일부로 테이블 스키마와 함께 지정할 수 있어요. 어떤 경우에는 [ALTER TABLE 문]({% link docs/current/sql/statements/alter_table.md %})으로도 테이블에 제약 조건을 추가할 수 있는데, 다만 현재 모든 제약 조건이 지원되는 건 아니에요.

Warning 제약 조건은 성능에 큰 영향을 미쳐요. 로딩과 업데이트는 느려지지만 특정 쿼리는 빨라지죠. 자세한 내용은 [Performance Guide]({% link docs/current/guides/performance/schema.md %}#constraints)를 참고하세요.

출처: 문서

본문

Check 제약 조건

Check 제약 조건을 사용하면 임의의 Boolean 표현식을 지정할 수 있어요. 이 표현식을 만족하지 않는 열은 제약 조건을 위반해요. 예를 들어 다음 CHECK 제약 조건으로 name 열에 공백이 포함되지 않게 강제할 수 있어요.

CREATE TABLE students (name VARCHAR CHECK (NOT contains(name, ' ')));
INSERT INTO students VALUES ('this name contains spaces');
Constraint Error:
CHECK constraint failed on table students with expression CHECK((NOT contains("name", ' ')))

Not Null 제약 조건

not-null 제약 조건은 열에 NULL 값이 포함될 수 없도록 지정해요. 기본적으로 테이블의 모든 열은 nullable이에요. 열 정의에 NOT NULL을 추가하면 그 열에 NULL 값이 포함될 수 없게 강제해요.

CREATE TABLE students (name VARCHAR NOT NULL);
INSERT INTO students VALUES (NULL);
Constraint Error:
NOT NULL constraint failed: students.name

Primary Key와 Unique 제약 조건

Primary key 또는 unique 제약 조건은 테이블에서 행의 고유 식별자가 되는 열(또는 열 집합)을 정의해요. 이 제약 조건은 지정된 열이 테이블 내에서 고유하도록 강제해요. 즉 열 집합에 대해 주어진 값을 가진 행이 최대 하나까지 존재할 수 있어요.

CREATE TABLE students (id INTEGER PRIMARY KEY, name VARCHAR);
INSERT INTO students VALUES (1, 'Student 1');
INSERT INTO students VALUES (1, 'Student 2');
Constraint Error:
Duplicate key "id: 1" violates primary key constraint
CREATE TABLE students (id INTEGER, name VARCHAR, PRIMARY KEY (id, name));
INSERT INTO students VALUES (1, 'Student 1');
INSERT INTO students VALUES (1, 'Student 2');
INSERT INTO students VALUES (1, 'Student 1');
Constraint Error:
Duplicate key "id: 1, name: Student 1" violates primary key constraint

이 속성을 효율적으로 강제하기 위해, 테이블에 정의된 모든 primary key 또는 unique 제약 조건에 대해 [ART 인덱스가 자동으로 생성돼요]({% link docs/current/sql/indexes.md %}).

Primary key 제약 조건과 unique 제약 조건은 두 가지 점을 빼고는 동일해요.

  • 테이블에 primary key 제약 조건은 하나만 정의할 수 있지만 unique 제약 조건은 여러 개 가능해요.
  • primary key 제약 조건은 키가 NULL이 아니도록도 강제해요.
CREATE TABLE students (id INTEGER PRIMARY KEY, name VARCHAR, email VARCHAR UNIQUE);
INSERT INTO students VALUES (1, 'Student 1', '[email protected]');
INSERT INTO students VALUES (2, 'Student 2', '[email protected]');
Constraint Error:
Duplicate key "email: [email protected]" violates unique constraint.
INSERT INTO students (id, name) VALUES (3, 'Student 3');
INSERT INTO students (name, email) VALUES ('Student 3', '[email protected]');
Constraint Error:
NOT NULL constraint failed: students.id

Warning 인덱스에는 제약 조건이 너무 적극적으로 평가되어 violates primary key constraint·violates unique constraint 같은 제약 오류가 생길 수 있는 특정 제한이 있어요. 자세한 내용은 [Indexes 페이지]({% link docs/current/sql/indexes.md %}#limitations-of-art-indexes)를 참고하세요.

여러 열에 유일성 제약 조건을 정의할 수도 있어요.

CREATE TABLE integers (i INTEGER, j INTEGER, k INTEGER, UNIQUE (i, j));
INSERT INTO integers VALUES (1, 2, 3);
INSERT INTO integers VALUES (1, 4, 5);
INSERT INTO integers VALUES (1, 2, 5);
Constraint Error:
Duplicate key "i: 1, j: 2" violates unique constraint.

외래 키 (Foreign Keys)

외래 키는 다른 테이블의 primary key 또는 unique 제약 조건을 참조하는 열(또는 열 집합)을 정의해요. 이 제약 조건은 그 키가 다른 테이블에 존재하도록 강제해요.

CREATE TABLE students (id INTEGER PRIMARY KEY, name VARCHAR);
CREATE TABLE subjects (id INTEGER PRIMARY KEY, name VARCHAR);
CREATE TABLE exams (
    exam_id INTEGER PRIMARY KEY,
    subject_id INTEGER REFERENCES subjects(id),
    student_id INTEGER REFERENCES students(id),
    grade INTEGER
);
INSERT INTO students VALUES (1, 'Student 1');
INSERT INTO subjects VALUES (1, 'CS 101');
INSERT INTO exams VALUES (1, 1, 1, 10);
INSERT INTO exams VALUES (2, 1, 2, 10);
Constraint Error:
Violates foreign key constraint because key "id: 2" does not exist in the referenced table

이 속성을 효율적으로 강제하기 위해, 테이블에 정의된 모든 외래 키 제약 조건에 대해 [ART 인덱스가 자동으로 생성돼요]({% link docs/current/sql/indexes.md %}).

Warning 인덱스에는 제약 조건이 너무 적극적으로 평가되어 violates primary key constraint·violates unique constraint 같은 제약 오류가 생길 수 있는 특정 제한이 있어요. 자세한 내용은 [indexes 섹션]({% link docs/current/sql/indexes.md %}#index-limitations)을 참고하세요.

더 알아보기 (Learn more)