Информационная архитектура: сущности (практика, vol.2)

Третья часть про сущности в ИА: фиксация свойств, паттерны их моделирования и схематизация итогового результата.

12-15 минут на прочтение
Информационная архитектура: сущности (практика, vol.2)

В прошлой статье мы разобрали первые пять этапов проработки информационных сущностей. Теперь давайте поговорим об оставшихся двух: фиксации свойств и итоговой схематизации.

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

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

1. Паттерны моделирования свойств

Как мы уже знаем, все свойства можно поделить на несколько типов: базовые, ссылочные, составные, вычисляемые, технические и ограничительные. И если с базовыми всё плюс-минус понятно, то что делать с остальными — отнюдь не всегда ясно.

Да и с базовыми, если честно, порой могут возникнуть проблемы. Например, у нас есть свойство «Цвет». Оно простое: ни на кого не ссылается, это не таксономия — это, скорее, словарь, сквозное свойство. Как с ним быть? Или с полем «Описание» — оно тоже простое, но активно участвует в индексации и поиске, об этом тоже нужно подумать.

Давайте разбираться.

1.1. Нормализованные словари

Их ещё называют «справочниками», а разработчики — ENUM, перечислением. Мы их уже касались вскользь. Поля такого типа могут принимать только значения из конкретного, определённого перечня.

Правила:

  • Значения — всегда конечные и контролируемые, добавление новых происходит только по процессу ревью.
  • Поддерживают алиасы/синонимы для поиска, но в БД хранится нормализованное значение (ключ).
  • Если значения словаря локализуются (переводятся на другие языки), то внутренний ключ остаётся неизменным.

Пример:

У товара есть поле brand, которое ссылается на запись из справочника брендов. В справочнике брендов есть конечный перечень записей обо всех брендах, представленных в системе.

Фильтр «Бренд» в каталоге работает по полю brand товара. В текстовом поиске же мы учитываем не только прямое название бренда, но и алиасы/синонимы.

Например, при вводе в поле поиска «Nike», «nike» и «Найк» система понимает, что это одно и то же — и выдаёт одинаковый результат.

Справочник брендов:

КлючАлиасы (в нижнем регистре)
adidasadidas, адидас, addidas, adiddas, adidac, adibas
nikenike, найк, наик, nake, niks, nikee
reebokreebok, рибок, reeboc, reebokk, rebok, ribok

Риски:

  • Избыточная детализация (когда в словаре много синонимов или значений) может привести к «шуму» в фасетах. Например, когда в словаре «Цвет» появляются сотни почти одинаковых значений: алый, бордо, вишнёвый, винный и тп.
  • Из-за отсутствия владельца, ответственного за словарь, повышается риск появления дублей и рассинхронизации.
  • Использование ENUM в БД для часто меняющихся списков почти всегда усложняет разработку и деплой.

1.2. Ссылочные поля

Поля, указывающие на другие сущности через внешние ключи. Главное их отличие от нормализованных словарей в том, что ссылочные поля связывают сущности между собой и с другими объектами (например, с терминами таксономий). Тогда как значения ENUM из предыдущего примера не являются отдельными объектами, они просто строчка в фиксированном списке.

Ссылочные поля — это «мостики» между сущностями: товар связан с категорией, тегами, продавцом, заказами. Благодаря им карточка не живёт в вакууме, а встраивается в общую систему.

Правила:

  • Для «один‑ко‑многим» 1:N (категория → товары) у товара хранится ссылка на свою категорию.
  • Для «многие‑ко‑многим» M:N (товар ↔ тег) связи хранятся отдельно.
  • Важно продумать, что происходит при удалениях: кого переносим, кого архивируем, а где просто убираем связь.

Пример:

У товара есть одна «Категория», но множество «Тегов».

Если удалить тег — товар останется. Если удалить категорию — нужно заранее решить, куда товар переедет.

Риски:

  • Непродуманные правила удаления ведут к потере данных или поломке логики. Я видел случаи, когда при удалении рубрики в CMS, из базы данных удалялись десятки статьей и сотни комментариев.
  • Когда связи между сущностями организованы неэффективно, системе приходится делать много лишних запросов, фильтровать данные или пересчитывать агрегаты на лету. Это замедляет скорость работы продукта.
  • Если связи построены небрежно, при массовых обновлениях могут случиться зависания или сбои. Например, любое изменение категории или продавца может вызвать ошибки в отображении связанных с ними карточках.

1.3. Вычисляемые поля

Это свойства, которые не вводятся вручную, а считаются системой на основе других данных: средний рейтинг, количество просмотров, популярность, конверсия. Они помогают понять, насколько «живой» или успешный объект, не требуя ручного обновления.

Вычисляться такие поля могут «на лету», либо храниться в БД или кэше.

Правила:

  • Нужно договориться, откуда берутся исходные данные и как часто обновляется результат — в реальном времени или каждый час, день, неделю.
  • Исходные данные и вычисленные результаты хранятся отдельно, чтобы не потерять возможность пересчёта.
  • Важно фиксировать формулы расчётов и их владельца — того, кто отвечает, если метрика «поплыла».
  • Полезно также указывать время последнего обновления, чтобы понимать, насколько данные свежие.

Пример:

В карточке показываем «4.6 из 5» и «124 отзыва». Эти значения не вводятся вручную — они считаются из всех отзывов с округлением до одной десятичной. Популярность товара рассчитывается как комбинация просмотров и добавлений в корзину за последние 7 дней.

Риски:

  • «Расползание» цифр: в карточке одно, в отчёте другое. На момент написания статьи такое можно увидеть на Хабре, там два разных счётчика просмотров: один доступный всем, другой — только авторам.
  • Неочевидные формулы, спрятанные в глубинах кода. Показатели меняются, команда не понимает причин.
  • Слишком частые пересчёты. Система вычисляет показатели слишком часто, нагружая серверы без нужды. Или наоборот — слишком редкие обновления, из‑за которых пользователи видят устаревшие данные.

1.4. Диапазоны и интервальные фасеты

Кто-то считает интервальные фасеты лишь подмножеством вычисляемых полей, но я решил выделить их отдельно. Они чаще всего встречаются и имеют несколько специфичных свойств.

Фильтры по числам и датам помогают пользователю быстрее находить подходящие товары. Мы редко ищем вещь за точно 2 570 рублей — обычно хотим что-то «в районе двух‑трёх тысяч». Поэтому интерфейс должен позволять задавать диапазон значений: цену «от-до», вес или рейтинг. Пользователь мыслит не конкретными числами, а удобными «вилками» — например, «до 1000 рублей» или «от 4 звёзд и выше».

Правила:

  • В системе хранится точное значение, а пользователю показываются готовые «умные» интервалы (например, на основе реального распределения цен). Если меняем цену, то принадлежность к интервальным полям изменяется автоматически.
  • Правила границ (включительно/исключительно) и округления задаются явно. Чтобы не было непонятно, входит «1000» в «до 1000» или в «1000-5 000».
  • Должны быть продуманы правила обработки пустых/нулевых значений. Например, «цена не указана» — это отдельная группа, она не попадает в интервалы.

Пример:

Фильтр «Цена» может выглядеть так: готовые варианты «до 999 рублей», «1000–4999 рублей», «5000+», плюс ручной ввод.

Для сортировки и страниц используется точная цена из карточки. При этом явно указано, что «до 999 рублей» — верхняя граница включительно, «1000–4999 рублей» — обе границы включительно, а товары без цены попадают в отдельный блок «цена не указана».

Риски:

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

Важный момент: некоторые фреймворки и базы данных умеют совершать очень быстрые арифметические операции, включая поиск по диапазону. Поэтому зачастую диапазоны и интервальные фасеты могут оказаться излишними. Уточняйте у разработчиков и архитекторов.

1.5. Составные и полуструктурированные поля

Когда у сущности много разнородных характеристик (например, у товара есть изображения, материалы, дополнительные свойства) — удобнее собрать их в «пакеты». То есть не разбивать свойство на десятки отдельных полей, а объединить в один структурированный набор. Это помогает избежать перегруженности данных и сделать архитектуру более гибкой.

Во второй статье цикла я писал о сильной и слабой типизации. Так вот составные поля — отличных пример признака слабой типизации.

Правила:

  • Те свойства, которые часто используются для фильтрации, сравнения или сортировки (ширина, вес, цена), лучше выделить в отдельные простые поля. Остальное можно хранить в составе набора.
  • Важно сразу договориться о едином формате (например, JSON или таблица), чтобы не получилось сотни уникальных схем в разных объектах.
  • Также стоит помнить об ограничении глубины вложенности — чем проще структура, тем меньше ошибок при обновлениях.

Пример:

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

Таким образом, мы не делаем отдельные поля для тех свойств, которые используются только вместе.

Риски:

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

1.6. Поисковые поля

Это поля, которые напрямую влияют на то, как пользователи находят нужный элемент через поиск. Именно они определяют качество и релевантность результатов. Обычно сюда входят: название, краткое описание, артикул и так далее.

Правила:

  • Поиск должен «думать как человек»: учитывать разные формы слов («купить» и «покупка»), синонимы («ноутбук» и «laptop») и популярные опечатки. Именно поисковые поля должны лучше всего индексироваться.
  • Полезно задавать разный «вес» полям — название важнее описания, а описание важнее технических характеристик.
  • Важно поддерживать актуальный словарь синонимов и опечаток: он должен пополняться на основе статистики реальных поисковых запросов.

Пример:

Покупатель вводит «кеды», и поиск показывает ему как «кеды», так и «sneakers», даже если запрашиваемое слово вообще на другом языке.

Название и категория влияют сильнее, чем описание, поэтому карточки с точным совпадением появляются первыми.

Словарь запросов обновляется по статистике — если пользователи всё чаще ищут «скайшуз» или «кроссовки на платформе», система быстро учится понимать эти слова.

Риски:

  • Сложные запросы без ограничений по размеру выдачи запросто могут «положить» поиск, перегрузив систему.
  • Если переусердствовать с синонимами, поиск начинает показывать нерелевантные результаты, будет слишком много «шума».
  • Несвоевременно обновляемый словарь приводит к тому, что люди начнут искать новые термины, которых в базе нет — и, не получив результатов, посчитают, что товара нет вовсе.

1.7. Технические поля

Это служебные поля, которые фиксируют то, что пользователям знать не обязательно. Например: когда и кем запись создана/изменена, какой у неё статус, флаги индексации. Такие данные помогают поддерживать порядок, находить ошибки и понимать, как объект живёт во времени. Без них часто невозможно разобраться, кто и что сделал, особенно если с системой работает большая команда.

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

Правила:

  • Типовые значения указываются в едином формате: например, время — только в UTC+0. Это позволяет потом не путаться при реализации и анализе.
  • Важно заранее договориться о понятных статусах сущностей и допустимых переходах между ними, фиксировать автора, источник и причину изменений.
  • Желательно хранить историю правок хотя бы ключевых сущностей, чтобы при спорных ситуациях можно было восстановить ход событий.

Пример:

У сущности «Товар» есть поле «Статус» в виде нормализованного словаря, ENUM: «черновик → на проверке → опубликован → в архиве».

Система показывает, кто и когда вносил правки, а также из какой системы пришли изменения. Например, если товар был обновлён автоматически из ERP, это видно в истории. А комментарий «обновлены фотографии по новому каталогу» помогает понять контекст изменения.

Риски:

  • «Прыгающие» даты из‑за разных часовых поясов, непонятные или дублирующие статусы, невозможность определить автора изменений.
  • Потеря истории при импорте или миграции: если данные перезаписать без сохранения временных меток, аналитика и отчёты станут недостоверными.

1.8. Ограничительные поля

Это поля, которые определяют рамки доступности сущности: кто может её видеть, с ней взаимодействовать, где и при каких условиях. Они регулируют поведение системы и помогают избегать нарушений — например, продаж алкоголя несовершеннолетним или показ товаров, запрещённых к экспорту в конкретной стране. Также ограничительные поля фиксируют бизнес‑ограничения и ролевую модель вроде «только для админов» или «данные предоставляются по запросу».

Правила:

  • Разделяйте «бизнес‑ограничения» (что показываем и кому) и «технические» (что разрешает система). Должно быть прозрачно, почему сущность или операция скрыта или недоступна.
  • Желательно сопровождать такие поля пояснениями — что именно ограничивает доступ и где отображается уведомление пользователю.
  • Все ограничения должны иметь понятные статусы (например, «активно», «ожидает проверки», «временно снято с продажи») и быть управляемыми, а не жёстко зашитыми в код.

Пример:

В e-com для разных товаров могут быть установлены разные ограничения: «показывать только B2B», «не продавать в определённых странах», «ограничение по возрасту 18+».

В CRM доступ ко всем сделкам может быть доступен только пользователям с отмеченным полем «Полный доступ».

Риски:

  • Скрытые ограничения ломают пользовательский опыт. Если это не предусмотрено специально, всегда сообщайте об ограничениях тем, кого они касаются.
  • Разные правила на фронте и бэкенде почти всегда приводят к несоответствиям. Лучше делать основную логику на сервере, а клиенту (браузеру или приложению) доверять только визуальное отображение.
  • При массовых изменениях может возникнуть путаница. Например, когда правила блокировок не синхронизированы между странами или каналами продаж.

2. Собственно, фиксация

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

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

Ниже я буду рассказывать про каждый аспект фиксации свойств и приводить пример в виде таблицы. Но так как формат блога не способствует созданию больших (и читаемых) таблиц, то я буду приводить только тот фрагмент, который относится к разделу. В конце статьи вы найдёте полные примеры в виде файлов.

Местами кое-что может показаться вам избыточным — и, скорее всего, так оно и есть. То, что может быть полезным в крупных продуктах с множеством ролей и подсистем, в небольших проектах порой только разводит бюрократию.

2.1. Основная информация

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

Пример основной информации о сущности «Товар»:

НазваниеКодТип данныхОбяз.ПримерОписание
IDidintДа10245Уникальный идентификатор записи, обязательное поле, помогает системе отличать товары друг от друга
НазваниеtitletextДаКроссовки Nike Air ZoomОтображает название товара в каталоге, поиске и карточке товара
ЦенаpricefloatДа1499Хранит цену товара для отображения, сортировки и операций
КатегорияcategoryrefДаОбувьОпределяет, к какому разделу относится товар
ЦветcolorenumНетчёрныйХранит название цвета, используется для фильтрации и отображения вариаций

Обратите внимание на тип данных: в различных системах типы данных могут обозначаться по-разному, при работе с IA желательно придерживаться какого-то единого, понятного всем, формата. Конкретно здесь:

  • int — простое целое число;
  • text — текст без явных ограничений в типе данных (не varchar, например);
  • float — число с плавающей точкой (3.23);
  • ref — ссылка на другую сущность, reference;
  • enum — его вы уже знаете, нормализованный словарь.

2.2. Источник и валидация

Откуда берётся значение и как проверяется. Укажите, поступает ли значение от пользователя, из импорта, внешней системы или вычисляется автоматически. Опишите правила проверки (валидации): допустимые диапазоны, форматы, обязательные символы. Также стоит указать, что происходит, если значение не проходит проверку (ошибка, предупреждение, автозамена).

НазваниеИсточникВалидация
IDГенерируется автоматически системойПроверяется на уникальность
НазваниеВводится контент-менеджеромПроверяется на длину (не более 120 символов) и отсутствие запрещённых слов
ЦенаБерётся из каталога поставщикаПроверяется на диапазон 1-999999, если меньше или больше — система выдаёт ошибку
КатегорияВыбирается из справочника категорийЕсли категория не найдена, выводится предупреждение, товар не заводится в систему
ЦветВыбирается из списка доступных цветовПроверяется по справочнику цветов и допустимым синонимам

2.3. Индексация и поиск

Как используется в поиске, фильтрах и аналитике. Опишите, участвует ли поле в поиске или фасетах, влияет ли оно на фильтрацию, сортировку и аналитику. Укажите, какие сценарии зависят от него (поиск по названию, сортировка по цене, фильтр по цвету). Добавьте, нужна ли регулярная переиндексация и как часто.

НазваниеИндексация и поиск
IDНе участвует в поиске, используется для связи записей и аналитики
НазваниеОсновное поисковое поле, влияет на релевантность результатов
ЦенаФасетное поле, используется для сортировки и фильтров «от‑до»
КатегорияУчаствует в навигации и фасетах; влияет на группировку и хлебные крошки
ЦветФасетное поле, помогает пользователям фильтровать товары по цвету

2.4. Владение и контекст

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

НазваниеОтветственныйГде используется
IDОтветственность разработкиИспользуется системой, не отображается пользователям
НазваниеКонтент-редакторОтображается в каталоге, на карточке товара и в результатах поиска
ЦенаКатегорийный менеджерОтображается в каталоге, корзине, аналитических отчётах
КатегорияМаркетолог или контент-менеджерВлияет на навигацию и структуру сайта, отображается в каталоге и карточке товара
ЦветКонтент-менеджерОтображается в фильтрах и карточках товаров

2.5. Жизненный цикл и обновление

Как часто меняется поле. Разделите поля по типу обновления: редактируемые пользователем, автоматически пересчитываемые системой, импортируемые из внешних источников. Укажите частоту проверки актуальности и правила пересмотра.

НазваниеКем и как часто обновляется
IDНе меняется после создания
НазваниеМожет редактироваться контент-редактором при обновлении ассортимента
ЦенаОбновляется автоматически при изменении прайса, раз в сутки
КатегорияИзменяется редко, при реструктуризации каталога
ЦветОбновляется при появлении новых вариаций

2.6. Нормализация и перевод значений

Как поддерживается единообразие. Опишите, как поле очищается и приводится к общему формату: регистр, язык, синонимы, стандарты записи. Если данные многоязычные — уточните правила перевода. Добавьте примеры типичных ошибок и корректного вида.

НазваниеФорматирование
IDФорматируется как число без ведущих нулей
НазваниеОчищается от лишних пробелов и специальных символов
ЦенаХранится как число в одной валюте (например, в рублях)
КатегорияНормализуется по справочнику категорий
ЦветПриводится к единому значению («чёрный» = «black» = «черный»)

2.7. Таблица свойств (Entity Attribute Matrix)

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

Обязательно ведите версионирование: когда и кем изменялась таблица, что именно было изменено. Это позволит, при необходимости, провести трассировку изменений (например, при расхождении информационной архитектуры с программной реализацией).

Ну и напоследок, как и обещал, полная таблица свойств из этой статьи:

Не переключайтесь, в цикле будет ещё как минимум две статьи.

Павел Шерер, продюсер IT-решений

Канал в Telegram

Раньше тут были комментарии, но я решил не плодить сущности. Есть что сказать или спросить — велкам в телеграм-канал:

Обсудить в Telegram