Ограничение значений в колонке Postgres без создания таблицы
Быстрый ответ
Для того чтобы ограничить принимаемые значения столбца в PostgreSQL, можно использовать ограничение CHECK:
ALTER TABLE ваша таблица
ADD CONSTRAINT проверка_статуса
CHECK (статус IN ('активен', 'неактивен', 'в ожидании'));
Этот запрос гарантирует, что столбец статус
может принять только значения 'активен', 'неактивен' или 'в ожидании'.
Еще один способ: использование ENUM типов в PostgreSQL, что придаст вашему коду больше структурированности:
CREATE TYPE статусы AS ENUM ('активен', 'неактивен', 'в ожидании');
ALTER TABLE ваша таблица
ALTER COLUMN статус
TYPE статусы
USING статус::статусы;
Основы ограничений: CHECK и ENUM
Проверка значений посредством Enums
Тип ENUM в PostgreSQL задает строгие правила в виде списка допустимых значений, способствуя тем самым стройности данных:
CREATE TYPE настроение AS ENUM ('веселый', 'средний', 'печальный');
Проверь и следи: чтобы не нанести вред базе данных
Ограничение CHECK отлично справляется не только с базовыми проверками списков, но также способно использовать регулярные выражения для более сложных паттернов:
ALTER TABLE товары
ADD CONSTRAINT проверка_кода_товара
CHECK (код ~ '^P-[0-9]{4}$');
Такое ограничение контролирует, чтобы код товара соответствовал готовому шаблону – буква 'P' и четыре цифры.
Когда средние меры не помогают: триггеры и функции
В случаях, когда ограничения CHECK оказываются недостаточными, триггеры и функции предлагают гибкие возможности контроля за значениями столбцов:
CREATE FUNCTION проверка_цены_товара()
RETURNS trigger AS $$
BEGIN
IF NEW.price < 0 THEN
RAISE EXCEPTION 'Цена не может быть отрицательной';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER проверка_перед_вставкой
BEFORE INSERT OR UPDATE ON товар
FOR EACH ROW
EXECUTE PROCEDURE проверка_цены_товара();
Используйте такие инструменты с осознанием их сложности и потенциальной мощи.
Визуализация
Представьте, что у вас есть набор инструментов (🧰), в который могут попасть только определенные элементы:
Набор инструментов (🧰): [🔨, 🪛, 🧲, 🪚]
Добавив ограничение CHECK
, вы ограничиваете его содержание:
ALTER TABLE ящик_с_инструментами
ADD CONSTRAINT проверка_инструментов
CHECK (инструмент IN ('🔨', '🪛', '🧲', '🪚'));
Теперь только подходящий инструмент может быть добавлен в набор:
Допустимый выбор: 🔨 Открыть 🧰!
Недопустимый выбор: 💣 Недопустимо 🚫!
ENUM против CHECK: выбор стратегии хранения данных
ENUM: стабильные наборы значений
Типы ENUM хороши в ситуациях, когда список значений статичен и меняется редко. Однако при выборе использования их стоит всё взвесить:
CREATE TYPE юридический_статус AS ENUM ('виновен', 'невиновен', 'рассматривается');
CHECK: гибкость для динамичных правил
В ситуациях, когда требуется частое изменение правил, ограничения CHECK обеспечивают необходимую гибкость:
ALTER TABLE ваша таблица
DROP CONSTRAINT if exists проверка_на_изменения;
ALTER TABLE ваша таблица
ADD CONSTRAINT проверка_на_изменения
CHECK (новое_условие_здесь);
Производительность: ENUM в сравнении с ограничением CHECK
С точки зрения производительности, ENUM типы могут быть более предпочтительными, так как они индексируются по целочисленным значениям. Однако на практике разница обычно незначительна.
Полезные материалы
- PostgreSQL: Документация: Ограничения CHECK — подробности про ограничения CHECK в официальной документации PostgreSQL.
- PostgreSQL: Документация: Перечисляемые типы — более детальная информация о ENUM типах в PostgreSQL.
- PostgreSQL: Документация: psql — описание psql, клиентской утилиты для работы с PostgreSQL.
- PostgreSQL: Documentation: ALTER TABLE — команды для изменения таблиц в PostgreSQL.
- PostgreSQL: Документация: Ограничения NOT NULL — руководство по использованию ограничений NOT NULL в PostgreSQL.