SQLite - STRICT 테이블

얼마전 SQLite의 새 버전인 3.37.0이 릴리즈되었습니다. 주로 안정성이나 성능 개선 위주의 업데이트만 있다가, 이번 버전에서는 STRICT 테이블이라는 새로운 기능이 추가되었습니다. 이 기능은 다른 DBMS 처럼 테이블 칼럼의 형식에 맞는 값만 저장하도록 제한하는 기능으로, 새로 생성하는 테이블의 옵션 형태로 설정하게 됩니다.

SQLite3는 다른 DBMS와 달리 자료의 형(type)에 대해서 유연한 편입니다. 예를 들어 INTEGER 타입으로 정의된 칼럼에 “123” 같은 문자열을 저장하려 한다면 SQLite는 자동으로 이 문자열을 정수형태로 변환을 시도합니다. 따라서 저장되는 값은 문자열이 아닌 정수값 123이 저장됩니다. 만약 “xyz” 같은 변환이 불가능하거나, 변환 시에 원래 정보값이 손실되는 경우는 칼럼은 INTEGER 타입으로 정의되었지만, 원래의 문자열 데이터가 저장됩니다.

이러한 유연성은 사용하기 쉽다는 장점으로 받아들일 수도 있지만, 다른 DBMS와 같이 엄격한 타입 시스템을 선호하는 사람들도 있습니다. (사실 요즘은 동적 타입 프로그래밍 언어에서도 고정된 타입을 흉내내어 사전에 오류를 검출하려는 노력을 더하는 등 타입에 대한 엄격함이 일종의 트렌드로 자리잡는 분위기도 있습니다.) 이에 SQLite 3.37.0부터는 엄격한 타이핑 모드를 지원하여, 각각의 테이블에서 이를 사용할 수 있게 합니다.

Strict 테이블의 생성

테이블 생성 구문(CREATE TABLE)에서 맨 마지막에 STRICT 라는 테이블 옵션 키워드를 추가하여 실행하면, 테이블을 엄격한 타입 모드로 생성할 수 있게 됩니다. 엄격한 타입모드는 기본적인 동작은 일반적인 테이블과 거의 비슷하며, 다음의 차이점을 가집니다.

  1. 모든 칼럼 선언은 타입을 생략할 수 없으며, 칼럼의 타입은 다음 6가지만 지원됩니다: INT, INTEGER, REAL, TEXT, BLOB, ANY
  2. 그외 다른 타입은 허용되지 않으며, 추후 버전에서 추가될 수 있다고 합니다.
  3. ANY 외의 타입으로 선언된 칼럼에 대해서는 NULL 이나 해당 타입의 값만 저장될 수 있습니다. 대신, 다른 타입의 값을 저장하려 시도할 때에는 칼럼의 타입으로 변환을 시도합니다. 성공적으로 변환되면 변환된 값을 저장하지만, 변환에 실패하면 SQLITE_CONSTRAINT_DATATYPE 에러를 일으킵니다.
  4. ANY 타입 칼럼에는 어떤 형식의 데이터라도 저장될 수 있으며, 어떠한 자동 변환되 일어나지 않습니다.
  5. PRIMARY KEY로 지정된 칼럼들은 암묵적으로 NOT NULL 입니다. 하지만 암묵적 NOT NULL 칼럼에는 실제로 NULL 값을 넣을 수 있는데, 이 경우 NULL 대신 임의의 고유한 정수값이 저장됩니다.
  6. PRAGMA integrity_check 명령이나 PRAGMA quick_check 명령은 엄격 모드 테이블의 모든 칼럼의 값을 검사하며, 규격외의 값이 있는 경우에 에러를 표시합니다.

ANY

하지만 어떤 칼럼에 타입에 구애받지 않고 다양한 값을 저장할 수 있는 기능의 편리함은 여러 해 동안 장점으로 평가되었습니다. 이 기능을 엄격 모드 테이블에도 여전히 계승하기 위해 ANY 라는 이름의 데이터형이 새로 도입되었습니다. 어떤 컬럼의 타입이 “ANY”라면 정수, 실수, 문자열, 이진 블롭 등 어떤 타입의 데이터도 저장될 수 있다는 뜻입니다.

ANY의 동작은 이전의 일반적인 sqlite 테이블과 조금 다릅니다. 엄격 모드 테이블에서는 항상 삽입되는 데이터를 원형 그대로 저장합니다. 이전의 일반 sqlite 테이블은 문자열이 숫자값으로 변환이 가능하다면 변환해서 저장했습니다. 예를들어 ‘000123’ 이라는 문자를 ANY 칼럼에 삽입하면 엄격 모드에서는 ‘000123’이라는 원래 문자열이 저장되지만, 일반 모드 테이블에서 ANY 칼럼에는 123이라는 정수값이 저장됩니다.

하위 호환성

CREATE TABLE 구문에서의 STRICT 키워드는 SQLite 3.37.0 (2021년 11월 27일 릴리즈) 이상에서부터 인식됩니다. 만약 그 이전 버전의 SQLite에서 엄격 옵션이 적용된 테이블을 포함한 데이터베이스를 열게되면 이를 인식하지 못하고 에러를 내게 됩니다. 하지만 STRICT 키워드를 제외한 나머지 파일의 구조는 이전 버전과 동일합니다.

이 말은 1개 이상의 STRICT 테이블을 포함한 데이터베이스는 3.37.0 이상 버전의 SQLite에서만 열 수 있지만, STRICT 테이블을 포함하지 않았다면, 이전 버전의 SQLite에서도 이 데이터베이스를 열어서 사용하는 것은 문제가 되지 않습니다. 사실, STRICT 테이블을 포함한 파일을 열었다하더라도 바로 에러가 나는 것은 아니기 때문에, 데이터베이스를 연 직후 다른 명령을 실행하기 전에 PRAGMA writable_schema=ON 명령을 실행하면 이전 버전에서 만든 데이터베이스인 것처럼 사용하는 것은 가능합니다.

STRICT 테이블 옵션 이전에는 WITHOUT ROWID 테이블 옵션이 있었습니다. 두 옵션을 동시에 지정할 수 있으며, 각각의 옵션은 콤마로 구분하여 입력하면 됩니다.

https://www.sqlite.org/stricttables.html

Read more

워드프레스에서 고스트로 이전

워드프레스에서 고스트로 이전

이 글을 쓰면서도 믿기 힘든 사실인데, 블로그라는 걸 처음 시작한지가 20년이 되었습니다. 이글루스에서 처음 시작했다가, SK컴즈가 인수한다고 발표함과 동시에 워드프레스로 플랫폼을 옮겼죠. 워드프레스오 옮긴 이후에는 호스팅 환경을 이리 저리 옮기긴 했지만 거의 18년 가까이 워드프레스를 사용해온 것 같습니다. 그 동안 워드프레스는 블로깅 툴에서 명실상부한 범용CMS로 발전했습니다. 사실 웬만한 홈페이지들은 이제

By sooop
띄어쓰기에 대한 생각

띄어쓰기에 대한 생각

업무 메일을 쓸 때 가장 많이 쓰는 말 중에 하나가 메일 말미에 ‘업무에 참고 부탁 드립니다.‘인데요, 어느 날부터 아웃룩에서 이 ‘부탁 드립니다’가 틀렸다고 맞춤법 지적을 하기 시작했습니다. 맞는 말은 ‘부탁드립니다’라고 붙여 쓰는 거라고. 사실 아래아한글 시절부터 이전의 MS워드까지, 워드프로세서들의 한국어 맞춤법 검사 실력은 거의 있으나 마나 한

By sooop

구글 포토에서 아이클라우드로 탈출한 후기

한 때 구글 포토가 백업 용량을 무제한으로 제공해 주겠다고해서, 구글 포토를 사용해서 사진을 백업해왔습니다. 물론 이 이야기의 결말은 저나 이 글을 읽고 있는 여러분이나 모두 알고 있습니다. 사실 AI에게 학습 시킬 이미지 데이터를 모으기 위한 것일 뿐이라거나 하는 이야기는 그 당시에도 있었습니다만, 에이 그래도 구글인데 용량은 넉넉하게 주겠지…하는 순진한

By sooop

Julia의 함수 사용팁

연산자의 함수적 표기 Julia의 연산자는 기본적으로 함수이며, 함수 호출 표기와 같은 방식으로 호출하는 것이 가능합니다. 또한 그 자체로 함수이기 때문에 filter(), map() 과 같이 함수를 인자로 받는 함수에도 연산자를 그대로 적용하는 것이 가능합니다. 특히 + 연산자는 sum() 함수와 같이 여러 인자를 받아 인자들의 합을 구할 수 있습니다. 2 + 3 # = 5 +(2,

By sooop