JSON и выбор правильного типа
Знакомимся с типом JSON в MySQL и собираем чек-лист, как выбирать тип данных для столбца.
JSON — тип столбца MySQL для хранения структурированных документов; база проверяет валидность JSON и умеет извлекать из него значения функциями.
Зачем нужен тип JSON
Иногда у сущности есть гибкий набор полей, который неудобно раскладывать по столбцам: настройки пользователя, характеристики товара, метаданные. Раньше такое складывали в TEXT как строку, но тогда база не понимала структуру. Тип JSON решает это: он валидирует документ и даёт функции для доступа к полям.
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
settings JSON
);
INSERT INTO users (name, settings)
VALUES ('Анна', '{"theme": "dark", "notifications": true}');
Чтение значений из JSON
Извлечь поле можно функцией JSON_EXTRACT или коротким оператором -> / ->> (последний возвращает значение без кавычек).
SELECT name, settings->>'$.theme' AS theme
FROM users
WHERE settings->>'$.theme' = 'dark';
-- то же через функцию
SELECT JSON_EXTRACT(settings, '$.theme') FROM users;
Это MySQL-специфика, поэтому блоки текстовые: в учебной SQLite-песочнице синтаксис JSON-функций отличается.
Когда JSON, а когда обычные столбцы
JSON удобен, но это не замена нормальной схеме. Правило простое:
- Обычные столбцы — если по полю ищут, фильтруют, сортируют, соединяют. Они индексируются и работают быстро.
- JSON — для редко запрашиваемых, нерегулярных, «дополнительных» данных, структура которых меняется.
Не складывайте в JSON то, по чему постоянно фильтруете: реляционная модель для этого эффективнее.
Чек-лист выбора типа
| Данные | Тип |
| Идентификатор, счётчик | INT UNSIGNED (+ AUTO_INCREMENT для ключа) |
| Деньги | DECIMAL(10,2) |
| Короткая строка (имя, email) | VARCHAR(n) |
| Большой текст (статья) | TEXT |
| Фиксированный набор статусов | ENUM или таблица-справочник |
| Дата создания | DATETIME / TIMESTAMP |
| Флаг да/нет | TINYINT(1) |
| Гибкие метаданные | JSON |
Переносимый пример
Сама идея «храним и выбираем настройки» работает и на обычных столбцах — что часто и лучше:
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT,
theme TEXT,
notifications INTEGER
);
INSERT INTO users (name, theme, notifications) VALUES
('Анна', 'dark', 1),
('Борис', 'light', 0);
SELECT name FROM users WHERE theme = 'dark';
Вывод:
name Анна
Итог
- Тип
JSONвалидирует документы и даёт функции (JSON_EXTRACT,->>) для доступа к полям. - JSON — для гибких, редко запрашиваемых данных, а не для всего подряд.
- То, по чему фильтруете и соединяете, держите в обычных индексируемых столбцах.
- Выбор типа — это про корректность, место и скорость: берите минимально достаточный точный тип.