При проектировании флага состояния выбрали INTEGER вместо BOOLEAN: какую семантическую гарантию теряет такая модель?
Тип BOOLEAN явно выражает логическое назначение значения и ограничивает его значениями TRUE, FALSE и, при разрешённом NULL, состоянием UNKNOWN. При выборе INTEGER столбец сам по себе допускает любые целые числа, поэтому база данных больше не гарантирует, что значение является корректным логическим флагом.
Ограничение CHECK может искусственно разрешить только 0 и 1, но это будет проверка значений, а не полноценная типизация логического атрибута.
Типы данных SQL появились не только для выбора способа хранения, но и для описания допустимого смысла значения. Разделение логических, числовых, строковых и временных типов уменьшает число ошибок при проектировании схемы и позволяет СУБД проверять несоответствие типов до выполнения операции.
Логический тип решает задачу представления результата условия и состояния флага. Использование числа для этой цели возникло как практический компромисс в системах или диалектах SQL, где BOOLEAN отсутствовал либо поддерживался ограниченно.
Если флаг хранится как INTEGER, приложение может записать 2, -1 или другое значение, которое не имеет логического смысла. Ошибка обнаружится не при изменении схемы, а позже — в запросе, отчёте или условии бизнес-логики.
Даже при договорённости, что 0 означает ложь, а 1 — истину, это правило не становится гарантией базы данных без отдельного ограничения. Кроме того, числовой тип допускает арифметические операции, преобразования и сравнения, которые маскируют ошибочное использование значения.
Для логического атрибута следует использовать BOOLEAN. Если отсутствие значения недопустимо, добавляют NOT NULL; тогда столбец принимает только TRUE или FALSE.
BOOLEAN без NOT NULL допускает NULL. В логике SQL это не третья обычная истина, а UNKNOWN: результат сравнения или условия может быть неизвестным. Поэтому BOOLEAN не означает автоматически обязательное наличие значения.
Вариант с INTEGER можно усилить ограничением CHECK, например разрешить только 0 и 1. Это защищает от произвольных чисел, но сохраняет числовую семантику типа; кроме того, нужно отдельно решить, допускается ли NULL.
Поддержка BOOLEAN и правила неявных преобразований могут различаться между СУБД. Поэтому в переносимом проекте важно проверить конкретный диалект, но при наличии стандартного логического типа он обычно точнее отражает модель данных, чем INTEGER.
В системе уведомлений флаг is_enabled сначала хранили как INTEGER. После миграции из внешнего источника в таблице появились значения 2 и -1; приложение трактовало их по-разному, из-за чего часть уведомлений ошибочно считалась включённой.
Рассматривались два варианта. Сохранение INTEGER с CHECK требовало поддерживать соглашение о кодах и не устраняло числовую семантику. Замена на BOOLEAN точнее описывала предметную область, но потребовала преобразовать существующие значения и явно определить судьбу некорректных данных.
Выбрали очистку данных, преобразование 0 в FALSE, 1 в TRUE, отклонение остальных значений и новый столбец BOOLEAN NOT NULL. В результате некорректные значения стали невозможны на уровне схемы, а запросы получили однозначную логическую семантику.
1. Делает ли BOOLEAN столбец обязательным?
Нет. BOOLEAN определяет множество логических значений, но NULL остаётся допустимым, если не указано NOT NULL. Для флага нужно отдельно решить, имеет ли смысл состояние «неизвестно» или должны существовать только два состояния.
2. Полностью ли заменяет BOOLEAN ограничение CHECK на INTEGER?
Нет. CHECK может ограничить INTEGER значениями 0 и 1, но не меняет базовый тип столбца. Остаются числовые операции, числовые преобразования и потенциальные различия в трактовке значений на уровне приложения; BOOLEAN непосредственно сообщает назначение атрибута.
3. Всегда ли TRUE и FALSE ведут себя как обычные значения при проверке условий?
Нет. При наличии NULL действует трёхзначная логика SQL. Например, условие с неизвестным результатом не считается истинным в WHERE, поэтому строка может не попасть в выборку. Это важно учитывать при фильтрации и при проектировании BOOLEAN-столбцов, допускающих NULL.