Строковые типы: VARCHAR, TEXT, CHAR, ENUM

Разбираем строковые типы MySQL и учимся выбирать между VARCHAR, CHAR, TEXT и ENUM.

VARCHAR(n) — строка переменной длины до n символов; занимает столько места, сколько реально нужно тексту.

VARCHAR против CHAR

Оба хранят текст, но по-разному:

  • VARCHAR(255)переменная длина: короткая строка занимает мало места. Подходит для имён, email, заголовков — почти для всего.
  • CHAR(n)фиксированная длина: всегда n символов (короткие добиваются пробелами). Имеет смысл, когда длина действительно постоянна — коды стран (CHAR(2)), хеши фиксированной длины.
name   VARCHAR(100),   -- имя пользователя
country CHAR(2),        -- код страны: 'RU', 'DE'

TEXT для длинного текста

Когда содержимое может быть очень большим (статья, описание, комментарий), берут TEXT. У него есть размерные варианты: TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT. Минус: по TEXT сложнее строить индексы и нельзя задать значение по умолчанию (в большинстве версий).

Практическое правило: если ожидаете до пары сотен символов и нужен поиск/индекс — VARCHAR; если это «полотно» текста — TEXT.

ENUM — список допустимых значений

ENUM — MySQL-специфичный тип: столбец может принимать только значения из заранее заданного списка. Удобно для статусов и категорий.

CREATE TABLE tickets (
  id INT AUTO_INCREMENT PRIMARY KEY,
  status ENUM('new', 'open', 'closed') NOT NULL DEFAULT 'new'
);

Попытка вставить значение не из списка приведёт к ошибке (или к пустой строке в нестрогом режиме). ENUM компактен и самодокументируем, но менять список значений (ALTER TABLE) бывает накладно, поэтому для часто меняющихся наборов чаще заводят отдельную таблицу-справочник.

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

Логика хранения и выборки строк универсальна. Песочница (SQLite) хранит текст как TEXT; в MySQL это были бы VARCHAR/ENUM, но запросы те же:

CREATE TABLE tickets (
  id INTEGER PRIMARY KEY,
  title TEXT,
  status TEXT
);

INSERT INTO tickets (title, status) VALUES
  ('Не грузится страница', 'open'),
  ('Опечатка в тексте', 'closed'),
  ('Ошибка оплаты', 'open');

SELECT status, COUNT(*) AS cnt
FROM tickets
GROUP BY status;

Вывод:

status   cnt
closed   1
open     2

Кодировка и сравнение

Для строк важна кодировка (utf8mb4 — рекомендуемая) и правило сравнения collation. Например, utf8mb4_unicode_ci — регистронезависимое сравнение (ci = case-insensitive), так что 'Иван' и 'иван' при поиске будут равны.

Итог

  • VARCHAR(n) — рабочая лошадка для большинства строк (переменная длина).
  • CHAR(n) — для строго фиксированной длины (коды, хеши).
  • TEXT — для больших «полотен» текста.
  • ENUM — компактный список фиксированных значений (статусы), но менять его список тяжело.
Проверьте себя
1. Чем VARCHAR отличается от CHAR?
AVARCHAR хранит только числа
BVARCHAR — переменная длина, CHAR — фиксированная
CCHAR не поддерживает Unicode
Dмежду ними нет разницы
2. Для чего удобен тип ENUM?
Aдля хранения больших текстов
Bдля столбца с заранее известным фиксированным списком значений
Cдля дат
Dдля денежных сумм
3. Что означает суффикс _ci в collation вроде utf8mb4_unicode_ci?
Aсжатие данных
Bрегистронезависимое сравнение (case-insensitive)
Cтолько латиница
Dобязательную индексацию
Поддержать проект