JavaRush /Курсы /SQL SELF /Работа с ограничением CHECK для проверки да...

Работа с ограничением CHECK для проверки данных

SQL SELF
17 уровень , 3 лекция
Открыта

Ограничение CHECK — это в каком-то смысле охранник на входе вашей таблицы. Оно гарантирует, что данные, которые вы добавляете в таблицу, соответствуют определённым условиям. Если передать в таблицу данные, которые нарушают эти условия, база данных откажется принимать такие данные.

Представьте, что вы хотите открыть магазин в Германии. Но по закону воскресенье — выходной, и торговля в этот день запрещена. Это ограничение — аналог CHECK в базе данных. Вы пытаетесь указать расписание магазина: открыт 7 дней в неделю, но система тут же отвечает: "Nein, nein, воскресенье — это нарушение. Такой график не пройдёт проверку!"

Так и в базе данных: если вы задаёте значение, которое нарушает правило CHECK, система блокирует его, чтобы не допустить "логическую ошибку" в данных.

Зачем нужен CHECK?

  1. Поддержка качества данных: CHECK предотвращает попадание в таблицу некорректной или несоответствующей логике информации.
  2. Снижение вероятности ошибок: вместо того чтобы вручную проверять данные перед вставкой, вы можете доверить эту задачу базе данных.
  3. Автономность логики: правила проверки можно встроить в структуру базы данных, а не возлагать эту задачу на уровень прикладного кода.

Как работает CHECK?

Ограничение CHECK задается в момент создания таблицы или может быть добавлено позднее с помощью команды ALTER TABLE. Вот базовый синтаксис:

CREATE TABLE таблица (
    колонка тип_данных CHECK (условие)
);

условие — это логическое выражение, которое должно выполняться для каждого значения в указанном столбце. Если условие нарушается, база данных выдаёт ошибку.

Пример 1: Проверка диапазона значений

Давайте создадим таблицу students, где возраст студентов (age) должен быть в пределах от 16 до 100:

CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    age INTEGER CHECK (age >= 16 AND age <= 100)
);

Теперь, если вы попробуете вставить студента с возрастом 12, база данных вас "поймает за руку":

INSERT INTO students (name, age)
VALUES ('Maria Chi', 12);

Ошибка:

ERROR:  new row for relation "students" violates check constraint "students_age_check"
DETAIL:  Failing row contains (1, Maria Chi, 12).

Да, база данных тут — суровый привратник. Нет 16 — не суйся.

Пример 2: Проверка формата данных

Допустим, у нас есть таблица emails, где хранится список адресов электронной почты. Мы хотим убедиться, что адреса содержат символ @ (это упрощённый способ проверки):

CREATE TABLE emails (
    id SERIAL PRIMARY KEY,
    email VARCHAR(255) CHECK (email LIKE '%@%')
);

Попробуем добавить некорректный адрес, который не соответствует условию:

INSERT INTO emails (email)
VALUES ('notanemail.com');

Ошибка:

ERROR:  new row for relation "emails" violates check constraint "emails_email_check"
DETAIL:  Failing row contains (1, notanemail.com).

Ошибки можно избежать, если все данные содержат символ @:

INSERT INTO emails (email) 
VALUES ('example@student.com');

Запрос выполнится успешно.

Пример 3: Проверка условий для нескольких столбцов

Ограничения CHECK могут проверять не только один столбец, но и логическое выражение, завязанное на несколько столбцов. Давайте рассмотрим пример с таблицей employees, где зарплата (salary) должна быть больше, чем бонусы (bonus):

CREATE TABLE employees (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    salary NUMERIC CHECK (salary > 0),
    bonus NUMERIC CHECK (bonus >= 0),
    CHECK (salary > bonus)
);

Теперь, если кто-то попытается добавить сотрудника, у которого бонус больше зарплаты, база данных это не позволит:

INSERT INTO employees (name, salary, bonus)
VALUES ('Otto Lin', 3000, 4000);

Ошибка:

ERROR:  new row for relation "employees" violates check constraint "employees_salary_bonus_check"
DETAIL:  Failing row contains (1, Otto Lin, 3000, 4000).

Практическое применение

Ограничение CHECK помогает в тех случаях, когда ваш бизнес-логика тесно связана с ограничениями на данные. Например:

  1. Интернет-магазины: запрет на добавление товаров с отрицательной ценой.
  2. Образовательные платформы: проверка на возраст участников курсов.
  3. Медицинские системы: уверенность, что температура тела пациента лежит в допустимых пределах.

Эти проверки — не просто дополнительный слой безопасности, они экономят время и нервы разработчиков и пользователей.

Особенности и типичные ошибки

Когда работаете с CHECK, учтите следующие моменты:

  • Логические выражения в CHECK должны быть истинными для всех строк таблицы. Если хотя бы одна строка нарушает правило, перед добавлением ограничения эту строку нужно скорректировать.

  • Проверка не будет выполняться, если вставляемое значение равно NULL. Иными словами, CHECK (age >= 18) не выдаст ошибку для age = NULL. Это потому, что любое выражение, включающее NULL, автоматически становится неопределённым. Если вы хотите запретить NULL, добавьте NOT NULL.

  • Сложные условия в CHECK могут ухудшить производительность при вставке и обновлении данных, особенно в больших таблицах.

2
Задача
SQL SELF, 17 уровень, 3 лекция
Недоступна
Проверка диапазона значений с использованием `CHECK`
Проверка диапазона значений с использованием `CHECK`
2
Задача
SQL SELF, 17 уровень, 3 лекция
Недоступна
Проверка условий для нескольких столбцов
Проверка условий для нескольких столбцов
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ