HOWTO · SQLite
SQLite 데이터베이스의 부울 데이터 유형
SQLite 데이터베이스의 부울 데이터 유형에 대해 알아보세요.
이 페이지의 내용
SQLite에는 별도의 Boolean 저장 클래스가 없습니다. 그래도 Boolean 값은 표현할 수 있습니다. 일반적으로 정수 열에 false는 0, true는 1로 저장합니다. 애플리케이션이나 데이터를 주고받는 인터페이스에 더 적합하다면 일관된 텍스트 규칙을 사용해도 됩니다.
SQLite 데이터베이스의 부울 데이터 형식
SQLite에는 네이티브 Boolean 저장 클래스가 없습니다. 표현 방식을 정한 뒤 스키마, 삽입하는 값, 쿼리에서 일관되게 사용하세요. 정수 값이 실용적인 기본 선택입니다. 선언한 형식만으로는 값이 제한되지 않으므로 CHECK 제약 조건을 사용해 열에 허용할 두 상태를 제한할 수 있습니다.
부울 데이터 형식을 정수로 표현하기
두 가지 상태를 나타내는 플래그에는 false를 0, true를 1로 저장하는 정수 규칙을 사용할 수 있습니다. 열의 용도를 분명히 하도록 INTEGER로 선언한 다음 CHECK (flag IN (0, 1))를 추가해 저장되는 값을 이 두 값으로 제한하세요. SQLite는 유연한 형식 시스템을 사용하므로 열 선언만으로는 저장되는 모든 값이 둘 중 하나라고 보장할 수 없습니다. 제약 조건은 데이터베이스에 규칙을 설정하므로, 어떤 클라이언트가 삽입하거나 업데이트하더라도 SQLite가 이를 강제합니다. 이 강제에는 분명히 밝혀 둘 한 가지 한계가 있습니다. CHECK 식은 평가 결과가 거짓일 때만 실패합니다. NULL IN (0, 1)은 거짓이 아니라 NULL로 평가되므로, 제약 조건만으로는 NULL을 여전히 허용합니다. NULL을 막는 것은 다음에 설명하는 NOT NULL의 별도 역할입니다.
NOT NULL은 각 행에 플래그 값이 반드시 있어야 하는지를 별도로 정합니다. 이 제약 조건이 없으면 행에 false가 아니라 알 수 없거나 제공되지 않았음을 뜻하는 NULL이 들어갈 수 있습니다. 각 레코드에 확정된 답이 필요하다면 두 제약 조건을 모두 사용하세요. 애플리케이션에서 미응답 플래그를 허용한다면 NOT NULL은 생략하고 쿼리에서 NULL을 명시적으로 처리하세요.
숫자 0과 1을 삽입하고, 애플리케이션 코드에서는 가능하면 바인딩 매개변수를 사용하세요. true인 행은 WHERE flag = 1, false인 행은 WHERE flag = 0으로 조회하세요. 이 비교에 'true' 같은 문자열을 섞어 사용하지 마세요. 이렇게 하면 각 계층에서 규칙을 분명히 알 수 있고 애플리케이션의 서로 다른 부분이 같은 열을 다르게 해석하는 일을 피할 수 있습니다. 예제에서는 학생 테이블을 만들고 다섯 행을 삽입한 뒤 각 플래그 값을 읽습니다. 두 규칙을 직접 비교할 수 있도록 텍스트 레이블을 사용하는 별도의 테이블도 만듭니다.
import sqlite3
connection = sqlite3.connect(":memory:")
connection.execute("""
CREATE TABLE students (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
age INTEGER NOT NULL,
international_student INTEGER NOT NULL
CHECK (international_student IN (0, 1))
)
""")
connection.executemany(
"INSERT INTO students (id, name, age, international_student) VALUES (?, ?, ?, ?)",
[
(1, "Stefan", 13, 1),
(2, "Damon", 14, 0),
(3, "Elena", 12, 1),
(4, "Caroline", 12, 1),
(5, "Bonnie", 13, 0),
],
)
integer_rows = connection.execute(
"SELECT name, international_student FROM students ORDER BY id"
).fetchall()
connection.execute("""
CREATE TABLE student_flags (
student_id INTEGER PRIMARY KEY,
international_student TEXT NOT NULL
CHECK (international_student IN ('true', 'false'))
)
""")
connection.executemany(
"INSERT INTO student_flags VALUES (?, ?)",
[(1, "true"), (2, "false"), (3, "true"), (4, "true"), (5, "false")],
)
text_rows = connection.execute(
"SELECT student_id, international_student FROM student_flags ORDER BY student_id"
).fetchall()
print("Integer convention:", integer_rows)
print("Text convention:", text_rows)
Integer convention: [('Stefan', 1), ('Damon', 0), ('Elena', 1), ('Caroline', 1), ('Bonnie', 0)]
Text convention: [(1, 'true'), (2, 'false'), (3, 'true'), (4, 'true'), (5, 'false')]
표시된 행에는 첫 번째 테이블의 정수 값과 두 번째 테이블의 텍스트 레이블이 그대로 나타납니다. 예제는 저장된 표현을 확인할 수 있도록 모든 행을 조회합니다. 애플리케이션 쿼리에서 정수 테이블의 행을 필터링하려면 WHERE international_student = 1과 같은 조건을 추가하세요. 선택한 리터럴 형식은 열에 적용한 규칙과 일치시켜야 합니다.
부울 데이터 형식을 문자열로 표현하기
외부 형식에서 이미 true, false 같은 레이블을 사용하거나 저장된 값을 쉽게 확인할 수 있도록 해당 레이블을 표시하려는 경우 텍스트가 유용합니다. 열을 TEXT로 선언하고 표기와 대소문자 규칙을 하나로 정한 뒤, 위의 student_flags와 같이 CHECK 제약 조건으로 유효성을 검사하세요. 쿼리는 텍스트 레이블을 그대로 반환하며, 값을 읽고 쓸 때 애플리케이션 코드도 같은 규칙을 사용해야 합니다. SQLite의 형식 선호도는 어느 선언도 Boolean 형식으로 만들지 않으며, 열에 두 값만 허용하도록 제한하지도 않습니다.
이 규칙을 사용하면 삽입할 때 정한 텍스트 레이블을 사용하고, 쿼리에서도 같은 레이블과 비교해야 합니다. 예를 들어 WHERE international_student = 'true'와 같이 조회합니다. CHECK 목록은 표기가 일관되도록 보호하고, NOT NULL은 각 행에 레이블이 반드시 있도록 합니다. 이미 단어를 주고받는 인터페이스나 파일 형식에는 텍스트가 잘 맞을 수 있지만, 값을 쓰고 읽는 모든 쪽이 해당 규칙을 따라야 합니다. 1, TRUE, true처럼 여러 표현을 섞어 저장하면 비교와 애플리케이션 파싱에 추가 규칙이 필요하므로 피하세요.
데이터베이스 안에서 플래그를 두 상태 값으로 사용하는 대부분의 테이블에는 0과 1을 쓰는 INTEGER를 선택하세요. 각 행에 확정된 값이 있어야 하고 허용 값도 제한해야 한다면 NOT NULL과 CHECK를 함께 사용하세요. 이미 정해진 텍스트 인터페이스와 맞추는 것이 실용적일 때는 텍스트를 선택할 수 있습니다. 어느 표현을 사용할지 결정하기 전에 기존 데이터와 클라이언트가 해당 필드를 어떻게 인코딩하는지 확인하세요. 매핑 규칙을 문서화하고 스키마에서 강제하며, 같은 표현으로 값을 바인딩하고 모든 쿼리에서 일치하는 비교 방식을 사용하세요. SQLite에서는 형식 선호도를 나타내는 이름으로 BOOLEAN을 선언할 수도 있지만, 이 이름이 별도의 Boolean 저장 클래스를 만들지는 않으며 애플리케이션 규칙을 강제하는 제약 조건을 대신하지도 않습니다.