콘텐츠로 건너뛰기
Home » SQLite – STRICT 테이블

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

태그: