반응형

PRIMARY KEY 제약 조건의 사용법에 대해 설명한다. 컬럼에 PRIMARY KEY 제약 조건을 설정하게 되면 그 컬럼이 기본 키가 된다.

PRIMARY KEY 제약 조건이란?

컬럼에 PRIMARY KEY 제약 조건을 설정하면 그 컬럼이 기본 키(주 키 또는 프라이머리 키)가 된다. 기본 키는 하나 이상의 컬럼의 조합으로 설정되고, 테이블에 하나만 존재한다. 기본 키가 설정된 컬럼에서는 다른 데이터와 중복 된 값을 포함할 수 없다.

컬럼에 PRIMARY KEY 제약 조건을 설정하려면 다음과 같이 작성한다.

CREATE TABLE 테이블명 (컬럼명 PRIMARY KEY, ...);

여러 컬럼의 조합에 대해 PRIMARY KEY 제약 조건을 설정하려면 다음과 같이 작성한다.

CREATE TABLE 테이블명 (컬럼명 1, 컬럼명 2, ...,
  PRIMARY KEY (컬럼명 1, 컬럼명 2, ...));

PRIMARY KEY 제약 조건이 설정된 컬럼에는 중복 된 값을 포함 할 수 없다. 단 SQLite에서 null는 여러 컬럼에 저장이 가능하다. 여러 컬럼을 조합되어 PRIMARY KEY 제약 조건이 설정되어 있는 경우는 여러 컬럼에 저장된 값과 같은 조합의 값을 저장할 수 없다.


그러면 실제로 제약 조건을 설정해 보자. 다음과 같이 테이블을 만든다. id 컬럼에 PRIMARY KEY 제약 조건을 설정한다.

create table user (id int primary key, name text);
sqlite> create table user (id int primary key, name text);
sqlite> 

PRIMARY KEY 제약 조건을 설정하고 id 컬럼에 중복 된 값을 포함 할 수 없다. 이미 다른 데이터에 저장되어 있는 값과 동일한 값의 데이터를 저장하려고 하면 Error : UNIQUE constraint failed : user.id 에러 메세지가 표시된다.

insert into user values (1, 'devkuma');
insert into user values (2, 'araikuma');
insert into user values (1, 'kimkc');
sqlite> insert into user values (1, 'devkuma');
sqlite> insert into user values (2, 'araikuma');
sqlite> insert into user values (1, 'kimkc');
Error: UNIQUE constraint failed: user.id
sqlite>

위와 같이 PRIMARY KEY 제약 조건이 설정된 컬럼에 이미 존재하는 데이터와 동일한 값을 가진 데이터를 추가 할 수 없다.

INTEGER 타입의 컬럼에 PRIMARY KEY 제약 조건을 설정하는 경우

데이터 타입이 INTEGER 컬럼에 PRIMARY KEY 제약 조건을 설정 한 경우, 새로운 데이터를 추가 할 때 해당 컬럼의 값을 생략하면 AUTOINCREMENT 제약을 설정한 경우와 동일하게 자동으로 값이 저장된다.

CREATE TABLE 테이블명 (컬럼명 INTEGER PRIMARY KEY, ...);

컬럼에 저장되는 값은 대상의 컬럼에 현재 저장되어있는 최대 값에 1을 더한 값이다.

주의 사항

컬럼의 데이터 타입은 INT가 포함 된 경우 모든 INTEGER 타입이 되지만, 일련 번호가 자동적으로 부여되는 것은 컬럼에 INTEGER PRIMARY KEY로 작성한 경우일 뿐이다. INT PRIMARY KEY와 같이 작성하면 이런 동작하지 않는다.

실제로 제약 조건을 설정해 보자. 다음과 같이 테이블을 만든다. INTEGER 타입의 id 컬럼에 PRIMARY KEY 제약 조건을 설정한다.

create table user (id integer primary key, name text);
sqlite> drop table user;
sqlite> create table user (id integer primary key, name text);
sqlite> 

다음은 id 컬럼에 값을 지정하지 않고 데이터를 여러개를 저장해 보도록 한다.

insert into user (name) values ('devkuma');
insert into user(name)  values ('araikuma');
insert into user(name)  values ('kimkc');
sqlite> insert into user (name) values ('devkuma');
sqlite> insert into user(name)  values ('araikuma');
sqlite> insert into user(name)  values ('kimkc');
sqlite> 
sqlite> select * from user;
1|devkuma
2|araikuma
3|kimkc

값을 생략하지 않고 PRIMARY KEY 제약 조건이 설정된 컬럼에 임의의 숫자를 저장할 수도 있다. 단, PRIMARY KEY 제약 조건이 설정되어 있기 때문에 중복되는 값은 저장할 수 없다.

insert into user values (8, 'happykuma');
sqlite> insert into user values (8, 'happykuma');
sqlite>
sqlite> select * from user;
1|devkuma
2|araikuma
3|kimkc
8|happykuma

다음은 PRIMARY KEY 제약 조건이 설정된 컬럼에 값을 지정하지 않고 다시 데이터를 추가하면 PRIMARY KEY 제약 조건이 설정된 컬럼에 저장되는 최대 값이 8이므로 추가되는 값은 9가 된다.

insert into user (name) values ('mykuma');
sqlite> insert into user (name) values ('mykuma');
sqlite> select * from user;
1|devkuma
2|araikuma
3|kimkc
8|happykuma
9|mykuma

이 처럼 PRIMARY KEY 제약 조건이 설정된 컬럼에 같은 값을 중복하여 저장할 수 없지만, 데이터를 삭제하면 그 데이터의 컬럼에 저장되어 있던 값은 다른 데이터를 추가 할 때 지정할 수 있게 된다.

예를 들면, 현재 PRIMARY KEY 제약 조건이 설정된 컬럼에 저장되는 값이 9 데이터를 삭제 한 후 새로운 데이터로 PRIMARY KEY 제약 조건이 설정된 컬럼에 9를 사용하여 데이터를 추가 할 수 있다 .

delete from user where id = 9;
insert into user values (9, 'yourkuma');

위와 같이 PRIMARY KEY 제약 조건이 설정된 컬럼에 중복 값을 포함 할 수 없지만, 일단 삭제 해 버리면 다른 데이터를 추가 할 때 삭제 한 것과 같은 값을 컬럼에 저장할 수 있다.


SQLite에서는 테이블 생성시 컬럼에 데이터 타입을 지정된 경우에 다른 데이터 타입으로 저장하더라도 오류가 발생하지 않다. 예를 들어 INTEGER 타입을 설정한 컬럼에 TEXT 타입의 값을 저장 할 수도 있다.

create table numtest1 (id integer);
sqlite> create table numtest1 (id integer);
sqlite> 
sqlite> insert into numtest1 values ('hello');
sqlite>

이에 반해 컬럼에 데이터 타입으로 INTEGER를 지정하고 PRIMARY KEY 제약 조건을 설정한 경우에는 정수외에 값을 저장할 수 없게 된다.

create table numtest2 (id integer primary key);
insert into numtest2 values (10);
insert into numtest2 values ( '7');
insert into numtest2 values ( 'Hello');
sqlite> create table numtest2 (id integer primary key);
sqlite> 
sqlite> insert into numtest2 values (10);
sqlite> insert into numtest2 values ( '7');
sqlite> insert into numtest2 values ( 'Hello');
Error: datatype mismatch
sqlite> 

INTEGER PRIMARY KEY가 지정되어 있는 컬럼에 숫자 10와 '7' 같이 TEXT 타입인 숫자 값이라면 자동으로 INTEGER 타입으로 자동으로 변환되는 데이터는 추가 할 수 있지만, 'Hello' 같이 숫자로 변형이 되지 않는 TEXT 타입의 값을 저장하려고 하면 "Error : datatype mismatch" 오류가 발생한다.

데이터 타입이 설정된 컬럼에 다양한 데이터 타입의 값을 저장했을 때 어떻게 변환되어 저장되는지에 대해서는 "SQLite에서 사용할 수 있는 데이터 타입"을 참조하길 바란다.

반응형
  1. 첫째안전 2020.08.07 18:23 신고

    안녕하세요. 포스팅 너무 잘 보고 공부가 되었습니다.
    다만 궁굼한게 하나 있습니다. primary key를 적용한 데이터에서 만약 중간에 행 하나를 삭제했을때
    중간에 빈 숫자를 앞당겨서 다시 채워넣도록 하려면 어떻게 하면 될까요?

    예) 1, 2, 3 에서 2를 삭제하면 3이 앞당겨져서 2로 > 1, 2
    여기저기 많이 찾아봤지만 아직 감을 못잡아서 여쭤보게됐습니다..

    • 결론 부터 말씀드리면 못합니다. PK는 말 그대로 key 이기에 결코 바뀔수 없는 값입니다. 데이터를 삭제했다면 그 해당 되는 pk는 영구결번이 되는거죠. 바꿀수 있다면 해도 문제가 많이 발생할 것입니다. Fk 등으로 이미 그 pk를 사용한 곳에서 문지가 발생항 수도 있을 것입니다. 데이터의 규모가 작아서 pk 사용처에 다 알고 있다면 다 찾아서 수동 변경하면 되겠지만, 모든 dbms에서 자동으로는 제공하지 않는 기능입니다. 대신 그 pk에 다른 데이터를 넣을 수는 있습니다. 근데 이 방법도 그다지 추천하고 싶지는 않네요. 데이터를 지운 것도 히스토리성 이력이 될테니까요.

+ Recent posts