SQLite | 테이블 (Table) | ROWID 참조 및 INTEGER PRIMARY KEY와의 관계
SQLite에서 데이터를 추가하게 되면 데이터마다 ROWID 값이 자동으로 할당되어 다른 컬럼의 값과 동일하게 데이터로 저장된다. 여기에서 ROWID의 이용 방법과 INTEGER PRIMARY KEY와의 관계에 대해 설명한다.
ROWID 조회하기
ROWID는 테이블에 존재하는 숨겨진 컬럼이다. 테이블에 데이터를 추가 할 때마다 자동으로 ROWID에 값이 설정된다.
테스트를 위해 다음과 같이 테이블을 만들고 데이터를 2개 추가한다.
create table user (id integer, name text);
insert into user values (3, 'devkuma');
insert into user values (8, 'araikuma');
sqlite> create table user (id integer, name text);
sqlite>
sqlite> insert into user values (3, 'devkuma');
sqlite> insert into user values (8, 'araikuma');
sqlite>
테이블 데이터를 select * from user;
와 같이 조회하게 되면 ROWID의 값은 표시되지 않지만 ROWID를 명시적으로 지정하여 데이터를 조회하면 일반 컬럼과 같은 데이터를 조회를 할 수 있다.
select *, rowid from user;
sqlite> .mode column
sqlite> .header on
sqlite>
sqlite> select * from user;
id name
---------- ----------
3 devkuma
8 araikuma
sqlite>
sqlite> select *, rowid from user;
id name rowid
---------- ---------- ----------
3 devkuma 1
8 araikuma 2
sqlite>
위와 같이 ROWID의 값이 데이터별로 저장되어있는 것을 확인할 수 있다.
데이터를 새로 추가했을 때, 이미 저장되어 있는 데이터 중 ROWID의 값 중에 가장 큰 값을 찾고, 거기에 1을 더한 값이 새로 추가되는 데이터의 ROWID의 값으로 저장된다.
현재 저장되어 있는 데이터 중에 ROWID 값이 가장 큰 값은 2이므로 다음 데이터를 추가하면 데이터의 ROWID의 값은 3이다.
insert into user values (5, 'kimkc');
sqlite> insert into user values (5, 'kimkc');
sqlite>
sqlite> select *, rowid from user;
id name rowid
---------- ---------- ----------
3 devkuma 1
8 araikuma 2
5 kimkc 3
ROWID는 WHERE 절을 조건식으로 사용할 수도 있다.
select *, rowid from user where rowid = 2;
sqlite> select *, rowid from user where rowid = 2;
id name rowid
---------- ---------- ----------
8 araikuma 2
sqlite>
또한 ROWID는 다른 데이터베이스와의 호환성을 유지하기 위해 별칭으로 OID
와 _ROWID_
도 지원한다. 어느 것을 사용하여도 ROWID의 값을 반환된다. 예를 들면 ROWID 대신 _ROWID_
를 사용하여도 된다.
select *, rowid, oid, _rowid_ from user;
sqlite> select *, rowid, oid, _rowid_ from user;
id name rowid rowid rowid
---------- ---------- ---------- ---------- ----------
3 devkuma 1 1 1
8 araikuma 2 2 2
5 kimkc 3 3 3
sqlite>
ROWID 값 설정하기
ROWID의 값은 데이터를 추가 할 때 자동으로 설정되기 때문에 일반적으로 신경쓰지 않아도 되지만, 임의의 값을 지정할 수도 있다. 앞에서 만든 테이블에 다음과 같이 새로운 데이터를 추가 할 수도 있다.
insert into user (id, name, ROWID) values (10, 'happykuma', 8);
sqlite> insert into user (id, name, ROWID) values (10, 'happykuma', 8);
sqlite>
데이터를 조회해보면, 지정된 값이 ROWID에 저장되어있는 것을 확인할 수 있다.
select *, rowid from user;
sqlite> select *, rowid from user;
id name rowid
---------- ---------- ----------
3 devkuma 1
8 araikuma 2
5 kimkc 3
10 happykuma 8
sqlite>
주의할 점은 ROWID는 중복 된 값을 가질 수 없다. 이미 다른 데이터에 설정되어있는 값으로 ROWID로 설정하려고 하면 “Error : UNIQUE constraint failed : user.rowid"라는 오류 메시지가 표시된다.
insert into user (id, name, ROWID) values (9, 'mykuma', 3);
sqlite> insert into user (id, name, ROWID) values (9, 'mykuma', 3);
Error: UNIQUE constraint failed: user.rowid
sqlite>
ROWID 참조 및 INTEGER PRIMARY KEY와의 관계
여기까지의 ROWID의 특징에 대해 알아보았는데, ROWID은 데이터 타입을 INTEGER에 PRIMARY KEY 제약 조건이 설정한 컬럼과 동일한 동작하는 것으로 보인다.
실은 컬럼에 INTEGER PRIMARY KEY를 설정하게 되면 그 컬럼은 ROWID와 같은 값을 참조한다. INTEGER PRIMARY KEY가 설정된 컬럼에 값을 지정하면 ROWID도 같은 값이 되어, ROWID 값을 지정하면 INTEGER PRIMARY KEY가 설정된 컬럼도 같은 값이 된다. 다른 값을 지정하여 데이터를 추가한 경우와 나중에 지정한 값이 모두 포함된다.
테스트를 위해 다음과 같이 테이블을 만들고 데이터를 3개 추가해 보자.
create table user (id integer primary key, name text);
insert into user values (1, 'devkuma');
insert into user values (6, 'kimkc');
insert into user values (3, 'ariakuma');
sqlite> drop table user;
sqlite>
sqlite> create table user (id integer primary key, name text);
sqlite>
sqlite> insert into user values (1, 'devkuma');
sqlite> insert into user values (6, 'kimkc');
sqlite> insert into user values (3, 'ariakuma');
sqlite>
테이블에서 ROWID를 포함하여 데이터를 조회한다.
select *, rowid from user;
sqlite> select *, rowid from user;
id name id
---------- ---------- ----------
1 devkuma 1
3 ariakuma 3
6 kimkc 6
sqlite>
조회한 ROWID를 보면 INTEGER PRIMARY KEY가 설정된 컬럼명 데이터가 표시되어 있다. 정확히 알 수 없기 때문에 추측되어 버립니다 만, INTEGER PRIMARY KEY가 설정된 열이있는 경우에는 ROWID로 그 컬럼이 사용되는지도 모든다.
분명 ROWID를 조회하였지만, 조회한 데이터를 보면 INTEGER PRIMARY KEY가 설정된 컬럼명으로 데이터가 표시되어 있다. 정확히 알 수 없지만 추측해 본다면, INTEGER PRIMARY KEY가 설정된 컬럼이 있는 경우에는 ROWID가 그 컬럼으로 사용되는거 같다.