🎯 Осталось несколько дней до конца месяца Поддержите SQLTest.online и помогите нам сохранить практику SQL бесплатной для всех. Пожертвовать сегодня →
SQL код скопирован в буфер обмена

Урок 1.5 · Время чтения: ~7 мин

Кроме чисел, текста и дат, в базах данных есть сложные типы данных для значений со внутренней структурой: документов, списков, файлов, уникальных идентификаторов, координат и векторов для AI-поиска. Этот урок — короткая экскурсия: что хранит каждый тип, пример значения и какие СУБД его поддерживают. Запоминать синтаксис не нужно — цель в том, чтобы узнавать эти типы, когда встретите их в таблице.

Сложные типы данных в SQL

В предыдущем уроке каждый столбец хранил одно простое значение: число, строку или дату. Некоторые данные так не укладываются: набор характеристик товара, скан договора, точка на карте. Для таких данных у баз есть специальные типы.

Сложные типы данных SQL: JSON-документы, массивы, списки ENUM, файлы BLOB, идентификаторы UUID, точки на карте и векторы VECTOR

JSON: документы

Столбец JSON хранит целый документ с ключами, значениями, вложенными объектами и списками. В базе University исследовательский проект хранит свои гранты в одном JSON-столбце:

[{ "source": "Private Foundation", "amount": 244542.96, "year": 2020}]

  • В MySQL и MariaDB есть тип JSON; в PostgreSQL — json и более быстрый двоичный jsonb; SQL Server и SQLite хранят JSON как текст и читают его JSON-функциями.
  • JSON подходит для атрибутов, которые отличаются от строки к строке или приходят из другой системы готовым документом.

XML — более старый формат документов с тем же назначением; для него в PostgreSQL и SQL Server есть тип xml.

Массивы и вложенные структуры

Массив — это список значений в одной ячейке, например [1, 2, 3]. PostgreSQL поддерживает массивы любого типа (integer[], text[]), а аналитические СУБД вроде DuckDB добавляют LIST, STRUCT и MAP. В MySQL, MariaDB, SQL Server и SQLite массивов нет: список кладут в JSON или, чаще, в отдельную таблицу, по строке на элемент.

ENUM и SET: фиксированный список значений

ENUM допускает ровно одно значение из списка, объявленного вместе со столбцом. В Sakila столбец film.rating имеет тип ENUM('G', 'PG', 'PG-13', 'R', 'NC-17'), поэтому фильм не может получить рейтинг вне этого списка. SET, тип MySQL и MariaDB, допускает любое сочетание значений из списка: film.special_features хранит значения вроде Trailers,Deleted Scenes.

В PostgreSQL перечисления создают отдельно (CREATE TYPE ... AS ENUM); в других СУБД используют обычный столбец с проверкой или справочную таблицу.

BLOB: двоичные данные

BLOB (Binary Large Object) хранит байты: изображения, PDF-файлы, архивы. В Sakila столбец staff.picture имеет тип MEDIUMBLOB и хранит фото сотрудника. Тип называется BLOB в MySQL, MariaDB и SQLite, bytea в PostgreSQL и VARBINARY(MAX) в SQL Server.

Большие файлы утяжеляют резервные копии и замедляют копирование базы, поэтому приложения часто хранят файлы в файловом хранилище, а в базе — только путь или URL в текстовом столбце.

UUID: уникальные идентификаторы

UUID — 128-битный идентификатор вида a1c7abde-ccc7-11f1-92da-da8de233f452, уникальный между таблицами, серверами и системами. Его используют, когда строки создаются во многих местах одновременно и общий счётчик завести нельзя. В PostgreSQL и MariaDB есть тип uuid, в SQL Server он называется UNIQUEIDENTIFIER, MySQL хранит UUID в CHAR(36) или BINARY(16).

Пространственные типы: точки и фигуры

Пространственные типы хранят геометрию: точки, линии и многоугольники. В базе Bookings у каждого аэропорта есть координаты coordinates типа point, например (129.77, 62.09) у Якутска. В MySQL и MariaDB есть GEOMETRY и POINT, в SQL Server — geometry и geography, а PostgreSQL получает полную поддержку от расширения PostGIS. Пространственные функции измеряют расстояния, находят, что лежит внутри области и какие объекты ближе всего.

VECTOR: эмбеддинги для AI-поиска

VECTOR — это список чисел фиксированной длины, например [0.1, 0.2, 0.3]. AI-модели превращают тексты, изображения и товары в такие векторы (эмбеддинги), так что похожие объекты получают близкие векторы. После этого база может найти строки, чьи векторы ближе всего к вектору запроса: «документы, похожие на этот вопрос». На этом построены семантический поиск и RAG-приложения.

  • В MariaDB есть VECTOR(n) начиная с версии 11.7, с функциями вроде VEC_DISTANCE_COSINE.
  • MySQL добавил VECTOR в версии 9, SQL Server — в версии 2025.
  • PostgreSQL получает векторы от расширения pgvector.

Сложные типы в разных СУБД

ДанныеMySQLMariaDBPostgreSQLSQL ServerSQLite
ДокументJSONJSONjson, jsonb, xmlтекст, xmlтекст
Список——массивы (integer[])——
Фиксированный список значенийENUM, SETENUM, SETCREATE TYPE ... AS ENUM——
Двоичные данныеBLOBBLOBbyteaVARBINARY(MAX)BLOB
Уникальный идентификаторCHAR(36), BINARY(16)UUIDuuidUNIQUEIDENTIFIERтекст
КоординатыGEOMETRY, POINTGEOMETRY, POINTpoint, PostGISgeometry, geography—
ВекторVECTOR (9.0+)VECTOR (11.7+)pgvectorVECTOR (2025)—

Когда использовать сложный тип

Сложный тип хорош, когда значение используется целиком или требует особого поиска: документ, который хранят и возвращают как есть, фотография, эмбеддинг для поиска похожих. Если вы часто фильтруете, соединяете или считаете по части значения — ключу внутри JSON, элементу массива, — этой части обычно место в отдельном столбце или таблице. Так запросы остаются простыми, а база может использовать обычные индексы.


Ключевые выводы:

  • Сложные типы хранят значения со внутренней структурой: документы, списки, файлы, идентификаторы, координаты и векторы.
  • JSON хранит документы; в PostgreSQL есть ещё jsonb, массивы и xml.
  • ENUM и SET ограничивают столбец объявленным списком значений.
  • BLOB, bytea и VARBINARY хранят двоичные файлы; большие файлы часто держат вне базы.
  • UUID даёт идентификаторы, уникальные между системами; пространственные типы хранят точки и фигуры.
  • VECTOR хранит AI-эмбеддинги для поиска похожих; поддержка зависит от СУБД и её версии.

Часто задаваемые вопросы

Стоит ли хранить изображения в столбце BLOB?

Небольшие изображения — можно, но большие файлы раздувают базу и замедляют резервное копирование. Обычно файлы держат в файловом хранилище, а в базе сохраняют путь к ним.

Что лучше: JSON или отдельные столбцы?

Отдельные столбцы — для данных, которые есть в каждой строке и по которым фильтруют или соединяют. JSON — для атрибутов, которые отличаются от строки к строке или приходят готовым документом.

Что такое вектор в базе данных?

Список чисел фиксированной длины, который представляет смысл текста, изображения или другого объекта. У похожих объектов векторы близки, поэтому база может найти ближайшие к запросу.

Вопросы на собеседовании

Какие сложные типы данных вы знаете и когда их использовать?

JSON — для полуструктурированных документов, массивы — для списков в PostgreSQL, ENUM — для фиксированного набора значений, BLOB — для двоичных файлов, UUID — для глобально уникальных идентификаторов, пространственные типы — для координат, VECTOR — для эмбеддингов при поиске похожих. Каждый нужен, когда значение используется целиком или требует своих особых операций.

Чем плохо хранить данные в JSON вместо столбцов?

Значения внутри JSON труднее проверять, ограничивать, соединять и индексировать; запросы становятся длиннее, а ошибки типов обнаруживаются только при чтении данных.

Почему векторные базы данных важны для AI-приложений?

AI-модели представляют тексты и изображения в виде эмбеддингов. База с векторным типом и поиском ближайших соседей быстро находит самые похожие объекты — на этом построены семантический поиск и генерация с дополнением выборкой (RAG).

Попробуйте решить следующие задачи, чтобы закрепить материал этого урока.

  1. Какой тип для эмбеддинга?
  2. Какой тип подходит для данных?