C.W.K.
Stream
Lesson 04 of 10 · published

PRIMARY KEY 와 Rowid

~14 min · schema, primary-key, rowid

Level 0Scout
0 XP0/80 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

모든 테이블엔 rowid 가 있어 (거의)

기본값으로 모든 SQLite 테이블엔 보이지 않는 rowid 가 있어 — 엔진이 row 마다 부여하는 64-bit 정수. 이게 인덱스 / join 이 row 찾는 내부 메커니즘. 직접 볼 수 있어.

SELECT rowid, * FROM users;

컬럼을 INTEGER PRIMARY KEY 로 선언하면 (정확히 그 표기, INT PRIMARY KEY 아님) SQLite 가 그 컬럼을 rowid 의 alias 로 만들어. 컬럼이 rowid 가 돼 — 추가 저장 X, 추가 인덱스 X, 그냥 SQLite 가 이미 관리하던 정수의 다른 이름.

다른 PK 모양:

  • Composite PK — 여러 컬럼 위 PRIMARY KEY (a, b).
  • WITHOUT ROWID 테이블 — 정수 외 키 (예: UUID) 에 유용. 선언한 컬럼이 실제 storage key 가 됨.
Warning: INT PRIMARY KEYINTEGER PRIMARY KEY. 첫 번째는 평범한 인덱싱된 컬럼, INTEGER 정확히 써야만 rowid-alias 최적화 활성. 쉽게 ship 되는 버그 — insert 는 되지만 큰 테이블에서 silently 성능 회귀.

Code

Rowid alias — 같은 컬럼, 두 이름·sql
CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT);
INSERT INTO users(name) VALUES ('Alice'), ('Bob');

SELECT rowid, id, name FROM users;
-- 1 | 1 | Alice
-- 2 | 2 | Bob

-- 말 그대로 같은 컬럼
SELECT rowid = id FROM users;
-- 1
-- 1
정수 아닌 PK 용 WITHOUT ROWID·sql
CREATE TABLE sessions (
  session_id TEXT PRIMARY KEY,
  user_id    INTEGER NOT NULL,
  created_at TEXT NOT NULL DEFAULT (datetime('now'))
) WITHOUT ROWID;

-- session_id 가 이제 실제 storage key.
-- UUID 류 테이블에선 B-tree level 한 층 절약.

External links

Exercise

테이블 3 개 만들기: INTEGER PRIMARY KEY, INT PRIMARY KEY, TEXT 키 위 WITHOUT ROWID. 각각 row 몇 개 insert, SELECT rowid, * 로 셋 다 확인. 차이 관찰. 그리고 pragma_index_list(table) 로 SQLite 가 만든 내부 인덱스 개수 비교.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.