В чем разница между типами данных CHAR и VARCHAR в SQL?

Ответ

CHAR и VARCHAR — строковые типы данных, различающиеся стратегией хранения и использования памяти.

CHAR(n) — строка фиксированной длины

  • Хранит всегда n символов. Если строка короче, она дополняется пробелами справа.
  • Размер: Всегда занимает n байт (в кодировках типа LATIN1) независимо от содержимого.
  • Скорость: Доступ к данным может быть немного быстрее из-за предсказуемого размера записи.
  • Использование: Для данных строго фиксированной длины (коды, флаги, аббревиатуры).
    -- Для значения 'ABC' в поле CHAR(5) будет храниться 'ABC  ' (2 пробела).
    CREATE TABLE country (country_code CHAR(2)); -- 'US', 'RU'

VARCHAR(n) — строка переменной длины

  • Хранит только фактические символы (до n). Пробелы не дополняются.
  • Размер: Занимает (длина данных + 1-2 байта на служебную информацию о длине).
  • Эффективность: Экономит место на диске и в памяти для коротких строк.
  • Использование: Для данных переменной длины (имена, адреса, описания).
    -- Для значения 'ABC' в поле VARCHAR(5) будет храниться только 'ABC'.
    CREATE TABLE user (username VARCHAR(50), bio VARCHAR(255));

Сравнение на примере

Тип Объявление Значение Хранится как Размер (байт)
CHAR(5) 'Hi' 'Hi' 'Hi ' 5
VARCHAR(5) 'Hi' 'Hi' 'Hi' 2 + overhead

Рекомендация: Используйте CHAR только когда длина данных абсолютно постоянна. В большинстве случаев VARCHAR предпочтительнее.

Ответ 18+ 🔞

Давай разберёмся с этими двумя типами, а то, блядь, у некоторых в голове после них каша, как после хорошей пьянки.

CHAR(n) — это, сука, солдат в строю. Строго по струнке. Сколько ему сказали места занимать — ровно столько и будет стоять, даже если он там нихуя не делает. Объявил ты CHAR(10) — значит, под каждую запись MySQL отгрызёт ровно 10 байт (если кодировка простая). Запишешь ты туда слово "Привет" (6 букв) — оно допишет туда, блядь, четыре пробела, чтобы место не пустовало. Хули зря добру пропадать? Скорость обращения к таким данным может быть чуть выше, потому что база заранее знает, где у неё какая запись начинается — всё ровненько, по линеечке. Используется для всяких кодов, где длина железобетонная: код страны (CHAR(2)), пол (CHAR(1)), всякие флаги.

CREATE TABLE country (country_code CHAR(2)); -- 'RU', 'US'. Никаких 'RUS' или 'USA' — вылезешь за пределы, получишь по ебалу.

VARCHAR(n) — это уже вольный художник, блядь. Хранит ровно столько, сколько ты ему скормил, но не больше лимита n. Запишешь "Привет" — он и сохранит "Привет", без этих вот довесков в виде пробелов. Но за эту вольность надо платить: он тратит 1-2 дополнительных байта на то, чтобы запомнить длину твоей строки. Зато экономия места, ёпта, может быть овердохуищная, особенно если у тебя там в основном короткие тексты.

CREATE TABLE user (username VARCHAR(50), bio VARCHAR(255)); -- Пиши хоть 'Вася', хоть небольшую повесть в био. Главное — в лимит уложись.

Сравнительная таблица, чтобы вообще всё стало ясно

Тип Объявили Что вписали Что на самом деле легло на диск Сколько места сожрало (байт)
CHAR(5) 'Hi' 'Hi' 'Hi ' (с тремя пробелами!) 5
VARCHAR(5) 'Hi' 'Hi' 'Hi' (чистое дело) 2 + служебные 1-2 байта

Итоговая рекомендация, блядь: Не умничай. Если у тебя данные точно, блядь, внатуре, 100% всегда одной длины (как солдаты на параде) — бери CHAR. Во всех остальных, ебать, 99.9% случаев, когда длина плавает (имена, адреса, посты, комменты) — тыкай в VARCHAR и не парься. Экономия места того стоит.