본문 바로가기
C.W.K.
Stream
Lesson 02 of 10 · published

Type Affinity — SQLite의 유연한 타이핑

~14 min · schema, type-affinity, typing

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

타입을 눈감아 주는 기능

SQLite는 기본적으로 type affinity로 움직여. INTEGER 컬럼은 정수를 선호할 뿐이라 문자열도 받아주고, TEXT 컬럼은 숫자도 받아. 이건 실수가 아니라 의도야. 데이터 모양이 그때그때 달라지는 자리 — 예를 들면 오래된 CSV를 밀어넣는 자리 —에 SQLite를 끼워넣기 쉽게 하려고 그렇게 만든 거지.

affinity는 다섯 갈래로 나뉘어.

  • INTEGER — 이름에 'INT'가 들어간 타입.
  • TEXT — 이름에 'CHAR'나 'CLOB', 'TEXT'가 들어간 타입.
  • BLOB — affinity가 아예 없는 경우야. 타입을 안 적었거나 'BLOB'이라고 적었을 때.
  • REAL — 이름에 'REAL'이나 'FLOA', 'DOUB'가 들어간 타입.
  • NUMERIC — 나머지 전부. 애매한 'NUMERIC' 자신도 여기 들어가.

affinity 규칙은 꽤 별나. 대개는 신경 안 쓰고 의도한 타입만 선언하면 돼. 그러다 이상한 일이 생기면 — SUM 결과가 문자열로 나오거나, 인덱스가 있어야 할 row를 놓치거나 — 답은 거의 항상 하나야. 엉뚱한 storage class를 가진 값이 끼어든 거지.

Warning: type affinity는 인덱스와 비교 동작에까지 손을 뻗어. id가 TEXT affinity를 갖고 있으면 WHERE id = '42'WHERE id = 42가 서로 다르게 동작해. 해법은 다음 lesson의 STRICT 모드를 쓰거나, Python 쪽에서 타입을 조심해서 넘기는 거야.

Code

Affinity 실전 — 같은 컬럼, 다른 storage class·sql
CREATE TABLE demo (val INTEGER);
INSERT INTO demo(val) VALUES (1);     -- integer 로 저장
INSERT INTO demo(val) VALUES ('two'); -- text 로 저장 — SQLite 받아줌!
INSERT INTO demo(val) VALUES (3.14);  -- real 로 저장

SELECT val, typeof(val) FROM demo;
-- 1   | integer
-- two | text
-- 3.14| real
Affinity가 부리는 장난 막기·sql
-- Option 1: CHECK 제약
CREATE TABLE strict_int (
  v INTEGER NOT NULL CHECK (typeof(v) = 'integer')
);

INSERT INTO strict_int(v) VALUES ('hi');
-- Error: CHECK constraint failed: typeof(v) = 'integer'

-- Option 2: STRICT 테이블 (3.37+) — 다음 lesson
CREATE TABLE really_strict (v INTEGER NOT NULL) STRICT;

External links

Exercise

작은 demo 테이블을 만들고 컬럼 타입에 안 맞는 값을 일부러 넣어봐. SELECT에서 typeof(col)을 찍어 SQLite가 어떤 storage class를 골랐는지 확인해. 그다음 CHECK 제약을 걸어 잘못된 타입을 막고, 다시 넣어보면서 에러를 관찰해. 마지막으로 type affinity가 언제 쓸모 있고 언제 사고인지 네 말로 설명해봐.

Progress

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

댓글 0

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

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