SQLite STRICT 테이블 옹호론, HN서 "기본값이었어야" 공감 확산
- SQLite의 STRICT 키워드를 테이블 정의에 붙이면 INTEGER 컬럼에 텍스트 삽입 같은 타입 불일치를 막아줌
- 비strict 테이블은 GARBAGE, DATETIME, JSON, UUID 같은 존재하지 않는 컬럼 타입도 생성 시 허용하지만 STRICT를 붙이면 오류 발생함, 허용되는 타입은 INT INTEGER REAL TEXT BLOB ANY뿐임
- ANY 타입을 쓰면 strict 테이블 안에서도 정수 텍스트 실수 blob 등 모든 값을 자유롭게 저장 가능함
- 기존 비strict 테이블을 ALTER로 strict화할 방법은 없고 새 strict 테이블 생성 후 데이터 복사, 기존 테이블 삭제, 이름 변경의 3단계 마이그레이션이 필요함
- SQLite 개발자는 "The Advantages Of Flexible Typing" 문서에서 유연한 타이핑을 옹호하며 키밸류 저장소나 지저분한 CSV 임포트 같은 경우 flexible 타입이 유용하다고 주장함
Hacker News opinions
STRICT가 기본값이어야 한다고 생각함, 근데 하위 호환성 때문에 안 바꾸는 거 같음
이게 default인 줄 알았는데 아니었네
ANY 타입은 audit 테이블에서 필드별 변경 추적할 때 쓰기 딱 좋더라
STRICT를 default로 하자는 거 말고는 SQLite 개발자랑 딱히 다른 의견 없음, 진짜 대단한 툴 만든 사람인데
왜 DB가 잘못된 타입 넣는 걸 그냥 허용하는지 이해 안 됨, boolean 컬럼에 문자열 '1'이랑 '0' 들어가서 수천 대 장비에 배포된 코드 정리해야 했던 적 있음, timestamp 타입도 없어서 ISO 형식도 아니고 그냥 UTC라고 가정하라는 식의 문자열로 저장하는 것도 별로임
SQLite는 하위 호환성에 워낙 신경 쓰니까 3.53에서 3.54로 올릴 때 갑자기 CREATE TABLE이 strict가 돼서 기존 소프트웨어 깨지는 거 원하지 않는 거임
foreign key 제약조건도 비슷하게 기본적으로 꺼져 있는 등 이런 사례가 더 있음, 예전엔 FK 문법만 있고 실제 기능은 구현 안 됐었나 싶음
새 버전부터는 STRICT를 유일한 모드로 만드는 게 나을 듯
foreign key도 기본적으로 꺼져 있어서 PRAGMA foreign_keys = ON 해줘야 함, strict는 그런 pragma조차 없어서 매 CREATE TABLE마다 비표준 STRICT 붙여야 하는 게 더 큰 문제임, 전역 STRICT pragma는 논의됐지만 구현 안 됐음
숫자 필드는 읽을 때마다 검증해야 함, 안 그러면 앱이 잘못된 데이터로 터질 위험 있음
strict 테이블의 단점은 Date 같은 일부 타입을 못 쓴다는 거임, DB를 여러 앱이 공유하면 선언된 타입을 믿을 수 있어야 하는데 한 앱이 숫자 컬럼에 문자열 넣으면 다른 앱들 다 깨짐, 근데 SQLite는 임베디드용이라 한 앱만 쓰는 경우가 많아서 스키마 유연하게 진화시키는 게 장점일 수도 있음
SQLite에는 Date 데이터 타입 자체가 없고 임의 SELECT 쿼리에 대해 EXPLAIN으로 타입 이름 얻을 방법도 없어서 추론도 안 됨
Date는 타입이 아니라 그냥 numeric affinity 컬럼일 뿐임
SQLite에는 딱 5개 타입만 있음, INTEGER TEXT BLOB REAL NUMERIC뿐임
오래된 SQLite 버전 쓰거나 기존 테이블에 STRICT 새로 테이블 만들어서 복사하기 싫으면 CHECK 제약조건으로 signedness, int 크기, char 길이 같은 걸 강제할 수 있음, 근데 결국 뒤에서는 다 text나 integer 컬럼일 뿐이라 이런 잔재주 부려야 하는 게 좀 짜증남
SQLite에서 유일하게 별로인 건 마이그레이션임
ALTER TABLE 문서 보면 12단계나 되고 데이터 손실 위험 경고까지 있어서 진짜 위험함, 왜 이 과정을 좀 쉽게 안 만드는지 아쉬움
UUID가 08123으로 시작하니까 octal로 파싱돼서 숫자로 잘못 변환된 적 있었음, strict로 바꾸고 테이블 전체 재구성해서 해결함
그건 SQLite 문제가 아니라 언어 드라이버가 멋대로 도와준 거임, SQLite 자체엔 octal 타입 없음
요즘 소프트웨어들이 다 이런 카프카스크한 괴물로 변해서 제일 간단한 일 하는데도 100개 관문을 거치게 만드는 트렌드 싫음, LLM한테는 좋겠지만 사람 입장에서는 짜증남, 쓰레기 데이터 넣어도 최선을 다해 처리해주는 SQLite가 오히려 좋았음
내 DB만큼은 strict 타입이었으면 좋겠음, RPC도 마찬가지, 근데 SQLite는 좀 다른 용도라 flextypegood 문서 보면 이해는 됨, SQLite용으로 안 만든 스크립트가 우연히 잘 돌아가는 것도 다른 DBMS에선 신경 안 쓰는 포인트임