Что такое SQL режим STRICT_ALL_TABLES (strict mode) в MySQL?

«Что такое SQL режим STRICT_ALL_TABLES (strict mode) в MySQL?» — вопрос из категории Базы данных, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В контексте баз данных, strict mode (строгий режим) в MySQL — это настройка сервера SQL, которая заставляет его более строго проверять входящие данные и отклонять недопустимые операции, вместо того чтобы молча их обрезать или подставлять значения по умолчанию.

Основные эффекты включения строгого режима (STRICT_ALL_TABLES или STRICT_TRANS_TABLES):

  1. Ошибка при вставке некорректных данных: Если вы пытаетесь вставить строку, длина которой превышает объявленный VARCHAR(255), операция завершится ошибкой, а не обрежет строку.
  2. Ошибка при вставке NULL в NOT NULL поле: Вместо подстановки значения по умолчанию (например, пустой строки или нуля) произойдёт ошибка.
  3. Ошибка при неверных значениях даты: Некорректные даты (вроде '2023-02-30') вызовут ошибку, а не будут преобразованы в '0000-00-00'.
  4. Ошибка деления на ноль: При обычных настройках результат 1/0 будет NULL. В строгом режиме (с включённой опцией ERROR_FOR_DIVISION_BY_ZERO) это вызовет ошибку.

Как проверить и установить:

-- Показать текущие SQL режимы
SELECT @@GLOBAL.sql_mode, @@SESSION.sql_mode;

-- Установить строгий режим для текущей сессии (рекомендуемый набор)
SET SESSION sql_mode = 'STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

-- Установить глобально (требует привилегий SUPER)
SET GLOBAL sql_mode = 'STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

Практический пример:

CREATE TABLE users (
    id INT PRIMARY KEY,
    email VARCHAR(100) NOT NULL,
    age TINYINT UNSIGNED
);

-- Со строгим режимом ВКЛЮЧЕН:
INSERT INTO users (id, email, age) VALUES (1, NULL, 300);
-- Ошибка: Column 'email' cannot be null. И ошибка: Out of range value for column 'age'.

-- Со строгим режимом ВЫКЛЮЧЕН:
INSERT INTO users (id, email, age) VALUES (1, NULL, 300);
-- Предупреждения. В email попадёт пустая строка, в age — 255 (макс. для TINYINT UNSIGNED).

Зачем это нужно:

  • Целостность данных: Гарантирует, что в БД попадают только корректные данные, соответствующие схеме.
  • Раннее обнаружение ошибок: Проблемы выявляются на этапе записи, а не при последующем анализе "битых" данных.
  • Предсказуемость: Поведение СУБД становится более явным и соответствует ожиданиям разработчика.