← Назад к вопросам
В чем разница между char и varchar в SQL?
1.3 Junior🔥 161 комментариев
#Базы данных и SQL
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между CHAR и VARCHAR в SQL: ключевые различия
CHAR и VARCHAR — это оба строковые типы данных в SQL, но они существенно различаются по использованию памяти и производительности. Выбор между ними критичен для эффективного дизайна БД.
Основные различия
CHAR(n) — Fixed Length (фиксированная длина)
CREATE TABLE users (
id INT PRIMARY KEY,
country_code CHAR(2), -- ВСЕГДА 2 символа
phone_code CHAR(3) -- ВСЕГДА 3 символа
);
-- Вставляем данные
INSERT INTO users VALUES (1, 'US', '202'); -- 2 + 3 символа
INSERT INTO users VALUES (2, 'RU', '495'); -- 2 + 3 символа
-- Что происходит в памяти:
-- 'US' -> 'US ' (заполняется пробелами до 2 символов)
-- 'RU' -> 'RU ' (заполняется пробелами до 2 символов)
VARCHAR(n) — Variable Length (переменная длина)
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(255), -- ДО 255 символов
description VARCHAR(1000) -- ДО 1000 символов
);
-- Вставляем данные
INSERT INTO users VALUES (1, 'John', 'Developer'); -- 4 + 9 символов
INSERT INTO users VALUES (2, 'Alice', 'Senior Engineer'); -- 5 + 15 символов
-- Что происходит в памяти:
-- 'John' -> занимает ровно 4 байта
-- 'Alice' -> занимает ровно 5 байт
Сравнение таблица
| Критерий | CHAR(n) | VARCHAR(n) |
|---|---|---|
| Размер | ВСЕГДА n байт | До n байт |
| Память | Фиксированная (потери на пробелы) | Переменная (экономит на пробелах) |
| Performance | Быстрее поиск (выравнивание) | Медленнее (нужно искать длину) |
| Storage | Всегда занимает n байт | Занимает только нужное |
| Использование | Коды, номера (фиксированной длины) | Текст, имена, описания |
| Сравнение | Точное совпадение | С учётом переменной длины |
Практические примеры
Пример 1: Коды (CHAR)
-- ХОРОШО: CHAR для кодов фиксированной длины
CREATE TABLE countries (
code CHAR(2) PRIMARY KEY, -- 'US', 'RU', 'DE' всегда 2
code3 CHAR(3), -- 'USA', 'RUS', 'DEU' всегда 3
name VARCHAR(100) -- Имя переменной длины
);
-- ПЛОХО: VARCHAR для кодов
CREATE TABLE countries (
code VARCHAR(2) PRIMARY KEY, -- Почему? Всегда 2 символа
code3 VARCHAR(3), -- Потеря памяти и производительности
name VARCHAR(100)
);
Пример 2: Текст (VARCHAR)
-- ХОРОШО: VARCHAR для текста
CREATE TABLE posts (
id INT PRIMARY KEY,
title VARCHAR(500), -- Заголовок переменной длины
content VARCHAR(10000), -- Контент переменной длины
author VARCHAR(100) -- Имя автора переменной длины
);
-- ПЛОХО: CHAR для текста
CREATE TABLE posts (
id INT PRIMARY KEY,
title CHAR(500), -- Потеря ОГРОМНОГО объёма памяти
content CHAR(10000), -- Каждый пост займёт 10KB минимум
author CHAR(100) -- Вспомогательные пробелы везде
);
Расчёт памяти
-- Таблица с 1 миллионом пользователей
-- Вариант 1: VARCHAR
CREATE TABLE users_varchar (
id INT, -- 4 байта
name VARCHAR(100), -- В среднем 30 байт
email VARCHAR(255), -- В среднем 50 байт
city VARCHAR(100) -- В среднем 20 байт
);
-- На 1,000,000 пользователей:
-- id: 1,000,000 * 4 = 4 MB
-- name: 1,000,000 * 30 = 30 MB
-- email: 1,000,000 * 50 = 50 MB
-- city: 1,000,000 * 20 = 20 MB
-- ИТОГО: ~104 MB
-- Вариант 2: CHAR (плохо!)
CREATE TABLE users_char (
id INT, -- 4 байта
name CHAR(100), -- ВСЕГДА 100 байт
email CHAR(255), -- ВСЕГДА 255 байт
city CHAR(100) -- ВСЕГДА 100 байт
);
-- На 1,000,000 пользователей:
-- id: 1,000,000 * 4 = 4 MB
-- name: 1,000,000 * 100 = 100 MB
-- email: 1,000,000 * 255 = 255 MB
-- city: 1,000,000 * 100 = 100 MB
-- ИТОГО: ~459 MB
-- Разница: 4.4x больше памяти с CHAR!
Поведение при сравнении
-- CHAR: заполняет пробелами
CREATE TABLE test_char (
code CHAR(3)
);
INSERT INTO test_char VALUES ('US');
INSERT INTO test_char VALUES ('US '); -- Пробел в конце
-- Оба SELECT вернут 2 строки (одинаково сравниваются)
SELECT COUNT(*) FROM test_char WHERE code = 'US';
-- Result: 2 (оба совпадают, пробел игнорируется)
-- VARCHAR: без пробелов
CREATE TABLE test_varchar (
code VARCHAR(3)
);
INSERT INTO test_varchar VALUES ('US');
INSERT INTO test_varchar VALUES ('US '); -- Пробел в конце
-- Вернёт только 1 строку
SELECT COUNT(*) FROM test_varchar WHERE code = 'US';
-- Result: 1 (без пробела не совпадает)
Производительность при поиске
-- CHAR быстрее в поиске (fixed offset)
-- БД знает точное место каждой строки
SELECT * FROM char_table WHERE code = 'US';
-- Прямой access (быстро)
-- VARCHAR медленнее (variable offset)
-- БД нужно считать размер
SELECT * FROM varchar_table WHERE code = 'US';
-- Поиск с расчётом размера (медленнее)
Best Practices
-- 1. CHAR для кодов фиксированной длины
CREATE TABLE countries (
code CHAR(2) PRIMARY KEY, -- Правильно
phone_prefix CHAR(3), -- Правильно
currency_code CHAR(3) -- Правильно
);
-- 2. VARCHAR для текста переменной длины
CREATE TABLE articles (
id INT PRIMARY KEY,
title VARCHAR(500), -- Правильно
content VARCHAR(50000), -- Правильно
tags VARCHAR(1000) -- Правильно
);
-- 3. Не используй CHAR когда unknown длина
CREATE TABLE users (
name VARCHAR(255), -- Правильно (переменная)
email VARCHAR(255), -- Правильно (переменная)
gender CHAR(1) -- Правильно (F/M - фиксированная)
);
-- 4. TEXT для больших объёмов
CREATE TABLE documents (
id INT PRIMARY KEY,
content TEXT -- Неограниченный размер
);
Реальный пример из Java
// Entity с правильными типами
@Entity
@Table(name = "users")
public class User {
@Id
private Long id;
// CHAR для фиксированных кодов
@Column(name = "country_code", length = 2)
private String countryCode; // CHAR(2)
// VARCHAR для текста
@Column(name = "name", length = 255)
private String name; // VARCHAR(255)
// VARCHAR для email
@Column(name = "email", length = 255)
private String email; // VARCHAR(255)
// TEXT для больших текстов
@Column(columnDefinition = "TEXT")
private String bio; // TEXT (неограниченный)
}
Когда использовать
CHAR(n):
- Коды (страны, валюты): CHAR(2), CHAR(3)
- Номера фиксированной длины: CHAR(10) для ИНН
- Статусы: CHAR(1) для F/M/O
- ID формата (всегда одна длина)
VARCHAR(n):
- Имена пользователей
- Email адреса
- Адреса
- Описания
- Заголовки
- Любой текст переменной длины
TEXT:
- Большие документы
- Контент статей
- Неограниченный размер
Итог
- CHAR: фиксированная длина, быстро ищется, потери памяти на пробелы
- VARCHAR: переменная длина, экономит память, медленнее поиск
- Правило: используй VARCHAR по умолчанию, CHAR только для кодов фиксированной длины
- Расчёт: разница в памяти может быть 4-5x для больших таблиц
Правильный выбор типа данных — основа хорошей БД архитектуры.