Открыть сервис

Тип данных VARCHAR в системах управления базами данных

VARCHAR (от англ. variable character) — это тип данных в системах управления базами данных (СУБД), предназначенный для хранения строк символов переменной длины. В отличие от фиксированного типа CHAR, VARCHAR сохраняет только фактически введённые символы плюс один или два байта служебной информации для хранения длины строки, что позволяет экономить дисковое пространство при работе с данными, длина которых сильно варьируется.

История и происхождение

Тип VARCHAR появился в ранних реляционных СУБД в 1980-х годах как развитие концепции строковых типов данных. В стандарте SQL-92 тип VARCHAR был официально закреплён как стандартный тип для хранения символьных строк переменной длины. До этого в первых версиях SQL (например, System R от IBM) использовались преимущественно типы с фиксированной длиной, что приводило к неэффективному расходованию памяти при хранении коротких значений в полях, рассчитанных на длинные строки.

Название происходит от слов variable (переменный) и character (символ). В различных СУБД встречаются синонимичные названия: NVARCHAR (для национальных кодировок в Microsoft SQL Server), TEXT (в PostgreSQL и MySQL для очень длинных строк), а также VARCHAR2 — собственная реализация в Oracle Database, которая функционально отличается от стандартного VARCHAR.

Устройство и принцип хранения

При создании столбца с типом VARCHAR(n) задаётся максимальная длина n в символах. Фактическое хранение данных зависит от реализации конкретной СУБД:

  • MySQL: VARCHAR хранит длину строки в 1 байте, если максимальная длина не превышает 255 байт, и в 2 байтах — для больших значений. Сами данные хранятся без дополнения пробелами.
  • PostgreSQL: тип VARCHAR (синоним CHARACTER VARYING) хранит строку с 4-байтовым заголовком, содержащим длину. При этом PostgreSQL не накладывает ограничений на фактический размер, кроме указанного при объявлении.
  • Microsoft SQL Server: VARCHAR хранит длину в 2 байтах и использует кодовую страницу базы данных для однобайтовых символов; NVARCHAR хранит данные в UTF-16 и требует 2 байта на символ.
  • Oracle Database: тип VARCHAR2 хранит длину в 1–2 байтах, а сам тип VARCHAR в современных версиях является синонимом VARCHAR2, хотя исторически имел отличия в обработке пустых строк.

В большинстве СУБД при вставке строки, длина которой превышает объявленную n, возникает ошибка или происходит усечение (в зависимости от настроек режима SQL). Строки меньшей длины не дополняются пробелами до максимального размера, в отличие от типа CHAR, что является ключевым отличием.

Отличия от CHAR и других строковых типов

Основное различие между VARCHAR и CHAR заключается в способе хранения и сравнения:

ХарактеристикаCHAR(n)VARCHAR(n)
ХранениеВсегда n символов, дополняется пробеламиТолько фактическая длина + служебные байты
Максимальная длинаОбычно до 255–2000 символовОбычно до 65 535 байт (зависит от СУБД)
Скорость доступаВыше при фиксированной длинеНиже, так как требуется чтение длины
Использование памятиНеэффективен для коротких значенийЭффективен для варьирующихся значений
Сравнение строкПробелы в конце игнорируютсяПробелы в конце учитываются

Для хранения очень больших текстов (документов, статей) в большинстве СУБД используются типы TEXT, CLOB или LONGTEXT, которые позволяют хранить строки длиной до нескольких гигабайт. VARCHAR обычно ограничен размером одной строки таблицы (например, 65 535 байт в MySQL для всей строки, включая другие столбцы).

Применение и рекомендации по использованию

VARCHAR является наиболее распространённым типом для хранения текстовых данных в реляционных базах данных. Он используется для:

  • имён, фамилий, названий организаций и географических объектов;
  • адресов электронной почты, номеров телефонов и других контактных данных;
  • кодов, артикулов и идентификаторов, содержащих буквы и цифры;
  • коротких описаний, комментариев и примечаний;
  • хранения сериализованных данных небольшого объёма (JSON, XML в некоторых СУБД).

При проектировании схемы базы данных следует выбирать VARCHAR, когда длина значения может существенно варьироваться, и CHAR — когда все значения имеют одинаковую длину (например, коды стран ISO, хеши фиксированной длины). Для полнотекстового поиска по большим текстовым полям VARCHAR подходит ограниченно, так как индексация длинных строк может быть неэффективной.

Особенности в различных СУБД

В MySQL тип VARCHAR имеет ограничение в 65 535 байт на строку таблицы, при этом в зависимости от кодировки (например, UTF-8) максимальное количество символов может быть меньше (до 21 844 символов для utf8mb4). В PostgreSQL VARCHAR практически не отличается от TEXT, за исключением возможности наложить ограничение длины. В SQLite тип VARCHAR вообще не имеет собственного хранилища — SQLite использует динамическую типизацию, и VARCHAR лишь объявляет «родовую принадлежность» значения к текстовому типу. В Oracle использование VARCHAR2 вместо VARCHAR является рекомендацией, так как стандартный VARCHAR может быть изменён в будущих версиях.

Производительность и индексация

Индексы на столбцах VARCHAR создаются по префиксу или по всей длине значения. В MySQL для индексации длинных VARCHAR требуется указание длины префикса. В PostgreSQL и SQL Server можно создавать полноценные индексы B-tree по значениям VARCHAR, однако для длинных строк эффективнее использовать хеш-индексы или полнотекстовые индексы. При сортировке и сравнении VARCHAR учитывается кодировка и collation (правила сравнения), заданные для столбца или базы данных.

Хранение строк переменной длины может приводить к фрагментации страниц данных в СУБД, так как обновление значения на более длинное может потребовать перемещения строки. Для минимизации фрагментации в некоторых СУБД рекомендуется периодически выполнять операции реорганизации таблиц (например, OPTIMIZE TABLE в MySQL или VACUUM в PostgreSQL).

Критика и ограничения

Основным недостатком VARCHAR считается невозможность эффективного хранения очень больших текстов, а также некоторая потеря производительности при частых операциях обновления записей, увеличивающих длину строки. Кроме того, в ряде СУБД (особенно в MySQL) смешение кодировок при использовании VARCHAR может приводить к ошибкам при сравнении строк или к неожиданному усечению данных при конвертации.

В современных СУБД наблюдается тенденция к использованию типа TEXT как универсальной замены VARCHAR, поскольку разница в производительности становится незначительной, а ограничения на длину снимаются полностью.

Источники

  1. Дейт К. Дж. «Введение в системы баз данных», 8-е издание, 2005.
  2. Грофф Дж., Вайнберг П. «SQL: Полное руководство», 3-е издание, 2010.
  3. Официальная документация MySQL 8.0 (раздел «The CHAR and VARCHAR Types»).
  4. Официальная документация PostgreSQL 16 (раздел «Character Types»).
  5. Официальная документация Microsoft SQL Server (раздел «char and varchar (Transact-SQL)»).

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →