Что такое схема данных, зачем она нужна, какие форматы файлов предусматривают наличие схемы и как это связано с сериализацией. Смотрим на примере JSON, XML, YAML и Protobuf.
Как связаны форматы и схемы данных и при чем здесь сериализация
При разработке требований к ПО или в рамках проектов интеграции информационных систем у аналитика возникают вопросы про схему данных и формат файлов. Это связанные понятия, однако не одно и тоже. Формат файла, отображаемый в его расширении, говорит о том, каким образом сообщение сериализуется, т.е. переводится в двоичный код, последовательность битов из 1 и 0, для передачи по сети или сохранения в постоянной памяти (на диске). Обратный процесс восстановления сообщения, имеющего практический смысл, из битовой последовательности, называется десериализацией.
За сериализацию и десериализацию отвечают приложения-источники и приемники сообщений, реализуя программный код работы с объектами и структурами данных. Этот код выполняет нужное преобразование данных каждого типа (числовые, символьные, дата и время, логические и пр.), которые встречаются в сообщении. На практике разработчик не часто пишет собственные сериализаторы и десериализаторы, а, в основном, пользуется готовыми библиотеками или встроенными во фреймворк классами.
Таким образом, формат файла описывает правила сериализации данных, которые есть в сообщении. Однако, этого недостаточно для верификации сообщения, пришедшего в систему-приемник из системы-источника. Например, необходимо проверить, что пришли все нужные данные, и их тип соответствует ожидаемому. За это отвечает схема данных, которая задает структуру сообщения: набор полей и их типы данных, а также обязательность каждого поля. В зависимости от используемого формата сериализации, схема данных может быть встроена в само сообщения или представлена отдельным файлом. Например, бинарный формат Protobuf, который используется в технологии gRPC, включает описание схемы в само сообщение, а JSON, XML и YAML предполагают описание схемы в отдельном файле аналогичных форматов.
Чтобы стало понятнее, далее посмотрим пример представления одного и того же по смыслу сообщения в разных форматах (JSON, XML, YAML и Protobuf), а также сгенерируем схему для них.
Основы архитектуры и интеграции информационных систем
Код курса
OAIS
Ближайшая дата курса
17 ноября, 2025
Продолжительность
25 ак.часов
Стоимость обучения
56 000 руб.
Представление сообщений в форматах JSON, XML, YAML и Protobuf со схемами данных
В качестве примера возьмем ранее рассмотренные в этой статье данные по клиентским заявкам. Сперва представим их в формате JSON как массив объектов, заключив в квадратные скобки.
{ "apps":
[
{
"course": "TTIS",
"name": "Анна",
"email": "anna@email.ru",
"phone": "123456789",
"corp": true,
"wishes": {
"city": "Казань",
"online": true,
"group ": true,
"number_of_students": 20
}
},
{
"course": "MODP",
"name": "Борис",
"email": "boris@email.ru",
"corp": false,
"wishes": {
"online": true,
"group ": false
}
},
{
"course": "OAIS",
"name": "Лиза",
"phone": "987654321",
"corp": false,
"wishes": {
"country": "Россия",
"online": true,
"group ": true,
"info": "Прошу связаться со мной в телеграм"
}
},
{
"course": "BAMP",
"name": "Никита",
"phone": "1122334455",
"email": "nikita@email.bank",
"corp": true,
"wishes": {
"country": "Казахстан",
"city": "Астана",
"online": false,
"group ": true,
"company": "Банк"
}
},
{
"course": "MODP",
"name": "Алексей",
"phone": "998887766",
"corp": false,
"wishes": {
"country": "Россия",
"city": "Москва",
"online": false,
"group ": false,
"info": "Позвоните мне для уточнения деталей"
}
}
]
}
Сгенерируем схему данных для этого сообщения в формате JSON, используя онлайн-редактор https://extendsclass.com/json-schema-validator.html. Результат будет следующим:
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://example.com/object1672485649.json",
"title": "Root",
"type": "object",
"required": [
"apps"
],
"properties": {
"apps": {
"$id": "#root/apps",
"title": "Apps",
"type": "array",
"default": [],
"items":{
"$id": "#root/apps/items",
"title": "Items",
"type": "object",
"required": [
"course",
"name",
"email",
"phone",
"corp",
"wishes"
],
"properties": {
"course": {
"$id": "#root/apps/items/course",
"title": "Course",
"type": "string",
"default": "",
"examples": [
"TTIS"
],
"pattern": "^.*$"
},
"name": {
"$id": "#root/apps/items/name",
"title": "Name",
"type": "string",
"default": "",
"examples": [
"Анна"
],
"pattern": "^.*$"
},
"email": {
"$id": "#root/apps/items/email",
"title": "Email",
"type": "string",
"default": "",
"examples": [
"anna@email.ru"
],
"pattern": "^.*$"
},
"phone": {
"$id": "#root/apps/items/phone",
"title": "Phone",
"type": "string",
"default": "",
"examples": [
"123456789"
],
"pattern": "^.*$"
},
"corp": {
"$id": "#root/apps/items/corp",
"title": "Corp",
"type": "boolean",
"examples": [
true
],
"default": true
},
"wishes": {
"$id": "#root/apps/items/wishes",
"title": "Wishes",
"type": "object",
"required": [
"city",
"online",
"group ",
"number_of_students"
],
"properties": {
"city": {
"$id": "#root/apps/items/wishes/city",
"title": "City",
"type": "string",
"default": "",
"examples": [
"Казань"
],
"pattern": "^.*$"
},
"online": {
"$id": "#root/apps/items/wishes/online",
"title": "Online",
"type": "boolean",
"examples": [
true
],
"default": true
},
"group ": {
"$id": "#root/apps/items/wishes/group ",
"title": "Group ",
"type": "boolean",
"examples": [
true
],
"default": true
},
"number_of_students": {
"$id": "#root/apps/items/wishes/number_of_students",
"title": "Number_of_students",
"type": "integer",
"examples": [
20
],
"default": 0
}
}
}
}
}
}
}
Получили файл формата JSON, который перечисляет поля данных, обозначенные в исходном сообщении, с указанием их типов и обязательности. По умолчанию все найденные поля отмечены как обязательные (required). А строка «$schema»: http://json-schema.org/draft-07/schema# означает, что при генерации этой схемы данных редактор опирался на 7-ю версию черновика стандарта JSON-схемы. В отличие от XML, схема данных для формата JSON до сих пор находится в статусе черновика. Дополнительно этот редактор позволяет включить в описание схемы примеры значений.

<root>
<apps>
<appsItem>
<wishes>
<info>Позвоните мне для уточнения деталей</info>
<group >false</group >
<online>false</online>
<city>Москва</city>
<country>Россия</country>
</wishes>
<corp>false</corp>
<phone>998887766</phone>
<name>Алексей</name>
<course>MODP</course>
</appsItem>
<appsItem>
<wishes>
<company>Банк</company>
<group >true</group >
<online>false</online>
<city>Астана</city>
<country>Казахстан</country>
</wishes>
<corp>true</corp>
<email>nikita@email.bank</email>
<phone>1122334455</phone>
<name>Никита</name>
<course>BAMP</course>
</appsItem>
<appsItem>
<wishes>
<info>Прошу связаться со мной в телеграм</info>
<group >true</group >
<online>true</online>
<country>Россия</country>
</wishes>
<corp>false</corp>
<phone>987654321</phone>
<name>Лиза</name>
<course>OAIS</course>
</appsItem>
<appsItem>
<wishes>
<group >false</group >
<online>true</online>
</wishes>
<corp>false</corp>
<email>boris@email.ru</email>
<name>Борис</name>
<course>MODP</course>
</appsItem>
<appsItem>
<wishes>
<number_of_students>20</number_of_students>
<group >true</group >
<online>true</online>
<city>Казань</city>
</wishes>
<corp>true</corp>
<phone>123456789</phone>
<email>anna@email.ru</email>
<name>Анна</name>
<course>TTIS</course>
</appsItem>
</apps>
</root>

Сгенерируем 2-ой вариант, используя атрибуты:
<root>
<apps>
<appsItem course="MODP" name="Алексей" phone="998887766" corp="false">
<wishes country="Россия" city="Москва" online="false" group ="false" info="Позвоните мне для уточнения деталей">
</wishes>
</appsItem>
<appsItem course="BAMP" name="Никита" phone="1122334455" email="nikita@email.bank" corp="true">
<wishes country="Казахстан" city="Астана" online="false" group ="true" company="Банк">
</wishes>
</appsItem>
<appsItem course="OAIS" name="Лиза" phone="987654321" corp="false">
<wishes country="Россия" online="true" group ="true" info="Прошу связаться со мной в телеграм">
</wishes>
</appsItem>
<appsItem course="MODP" name="Борис" email="boris@email.ru" corp="false">
<wishes online="true" group ="false">
</wishes>
</appsItem>
<appsItem course="TTIS" name="Анна" email="anna@email.ru" phone="123456789" corp="true">
<wishes city="Казань" online="true" group ="true" number_of_students="20">
</wishes>
</appsItem>
</apps>
</root>

За счет «склейки» нескольких элементов в один с разными атрибутами, выходное сообщение получилось чуть лаконичнее. Однако, рекомендуется хранить данные в элементах, а не в атрибутах из-за ограничений последний. В частности, атрибуты не могут содержать множественные значения, их сложнее расширять для последующих изменений и они не могут описывать сложные объекты, т.е. структуры. Поэтому для описания данных лучше использовать элементы, а в атрибуты записывать атрибутивную информацию, например, метаданные или специфическое описание объекта, такое идентификатор элемента XML.
Сгенерируем схему XML – файл XSD (XML Schema Definition) с помощью онлайн-генератора https://www.convertsimple.com/convert-xml-to-xsd-xml-schema/.
Для варианта с элементами результат будет следующим:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="apps">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="appsItem">
<xs:complexType>
<xs:sequence>
<xs:element name="wishes">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="info"/>
<xs:element type="xs:boolean" name="group"/>
<xs:element type="xs:boolean" name="online"/>
<xs:element type="xs:string" name="city"/>
<xs:element type="xs:string" name="country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element type="xs:boolean" name="corp"/>
<xs:element type="xs:integer" name="phone"/>
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:string" name="course"/>
<xs:element type="xs:string" name="email">
<xs:complexType>
<xs:simpleContent>
<xs:extension></xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Для XML с атрибутами получим такую схему XSD:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="apps">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="appsItem">
<xs:complexType>
<xs:sequence>
<xs:element name="wishes">
<xs:complexType>
<xs:sequence></xs:sequence>
<xs:attribute name="country" type="xs:string"/>
<xs:attribute name="city" type="xs:string"/>
<xs:attribute name="online" type="xs:string"/>
<xs:attribute name="group" type="xs:string"/>
<xs:attribute name="info" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="course" type="xs:string"/>
<xs:attribute name="name" type="xs:string"/>
<xs:attribute name="phone" type="xs:string"/>
<xs:attribute name="corp" type="xs:string"/>
<xs:attribute name="email" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Если сравнить JSON и XML-документы, можно сделать очевидный вывод о тяжеловесности XML-формата. Впрочем, текстовый человеко-читаемый JSON, применяемый в GraphQL и REST API, далеко не самый легковесный формат сериализации. Есть еще YAML, который занимает меньше места за счет структурирования данных не с помощью специальных символов {} и [], как в JSON, а через отступы. Сегодня именно этот формат часто используется для представления конфигурации приложений, а также для спецификации Open API (Swagger). Для примера конвертируем рассматриваемое JSON-сообщение в YAML-формат с помощью онлайн-конвертера https://www.json2yaml.com/ и получим следующий документ:
---
apps:
- course: TTIS
name: Анна
email: anna@email.ru
phone: '123456789'
corp: true
wishes:
city: Казань
online: true
'group ': true
number_of_students: 20
- course: MODP
name: Борис
email: boris@email.ru
corp: false
wishes:
online: true
'group ': false
- course: OAIS
name: Лиза
phone: '987654321'
corp: false
wishes:
country: Россия
online: true
'group ': true
info: Прошу связаться со мной в телеграм
- course: BAMP
name: Никита
phone: '1122334455'
email: nikita@email.bank
corp: true
wishes:
country: Казахстан
city: Астана
online: false
'group ': true
company: Банк
- course: MODP
name: Алексей
phone: '998887766'
corp: false
wishes:
country: Россия
city: Москва
online: false
'group ': false
info: Позвоните мне для уточнения деталей

К сожалению, мне не удалось найти онлайн-генератора для YAML-файла, зато обнаружила интересный инструмент для генерации классов на разных языках программирования из YAML-описания. Например, здесь https://jsonformatter.org/yaml-to-python можно сгенерировать из YAML-документа классы на Python, а здесь https://jsonformatter.org/yaml-to-java – на Java. Также конвертер поддерживает генерацию классов на других языках программирования, полный перечень можно посмотреть здесь: https://jsonformatter.org/yaml-tools-online. Пример практического использования этого инструмента я описываю в новой статье.

В заключение посмотрим, как выглядит это же самое сообщение в бинарном формате Protobuf, который используется в технологии gRPC. Конвертируем исходное JSON-сообщение в формат Protobuf с помощью онлайн-конвертера https://json2pb.vercel.app/ и получим следующий документ:
message AutoGenerate {
message Apps {
string course = 1;
string name = 2;
string email = 3;
string phone = 4;
bool corp = 5;
message Wishes {
string city = 1;
bool online = 2;
bool group = 3;
uint32 number_of_students = 4;
}
Wishes wishes = 6;
}
repeated Apps apps = 1;
}

Как видно из примера, Protobuf-сообщение включает схему данных, т.е. название полей и их тип, однако, человеку понять значение того или иного поля невозможно из-за их преобразования. При сериализации данных, т.е. переводе их в бинарный вид из нулей и единиц, сохраняются не имена полей, а их уникальные номера. Это делает процесс передачи данных более эффективным по сравнению с текстовыми форматами, такими как JSON или XML. Впрочем, Protobuf не предназначен для чтения человеком, главное преимущество этого формата – высокая скорость передачи данных по сети.
Резюмируя рассмотренные форматы сериализации данных, следует подчеркнуть, что все они имеют разную скорость преобразования данных в битовую последовательность и обратно, а также размер выходного сообщения. Помимо этих критериев нужно учитывать также удобство использования формата и возможность эволюции схемы. Впрочем, выбор формата данных чаще всего относится к области ответственности ИТ-архитектора или ведущего разработчика, а не аналитика. Однако, аналитику важно понимать основные характеристики наиболее популярных форматов сериализации данных, чтобы представлять в них примеры входящих и исходящих сообщений при интеграции информационных систем, а также схемы данных для их верификации.
Разработка ТЗ на информационную систему по ГОСТ и SRS
Код курса
TTIS
Ближайшая дата курса
10 ноября, 2025
Продолжительность
22 ак.часов
Стоимость обучения
48 000 руб.
Подробнее познакомиться с этими темами, а также другими основами архитектуры и интеграции информационных систем вам помогут курсы Школы прикладного бизнес-анализа в нашем лицензированном учебном центре обучения и повышения квалификации системных и бизнес-аналитиков в Москве:
- Основы архитектуры и интеграции информационных систем
- Разработка ТЗ на информационную систему по ГОСТ и SRS


