Екатеринбург

База данных сайта — сущности, связи и целостность бизнес-данных

Опубликовано: 3 августа 2026

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

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

База данных ценна не тем, что всё запоминает, а тем, что не даёт связанным фактам незаметно разойтись.

База данных и СУБД — не одно и то же

В бытовом разговоре оба понятия часто называют «базой». Но различие полезно при постановке задач. Данные — это конкретные записи и их структура. СУБД хранит их, выполняет запросы и предоставляет механизмы доступа, транзакций, резервного копирования и восстановления. Настройка этих механизмов и проверка результата остаются ответственностью команды или managed-провайдера в границах его договора.

PostgreSQL, MySQL, Microsoft SQL Server и другие продукты — СУБД. Конкретный интернет-магазин внутри них имеет собственную базу со схемой товаров и заказов. Переезд с одной СУБД на другую не равен копированию одного файла: могут различаться типы данных, функции, индексы, ограничения и процедуры эксплуатации.

Для бизнеса важнее не название продукта само по себе. CMS или готовая платформа всё равно зависят от понятной модели данных и ответов на вопросы:

  • какие объекты хранит система;
  • кто отвечает за их структуру;
  • что считается источником правды;
  • как предотвращаются противоречия;
  • кто и на каких правах читает или меняет данные;
  • как выполняются обновления и миграции;
  • когда последний раз проверяли восстановление.

Выбор СУБД имеет значение, но универсального победителя нет. Утверждения «NoSQL всегда быстрее SQL» или «для серьёзного проекта подходит только один продукт» бессмысленны без модели данных, нагрузки, требований к согласованности и компетенций команды.

Как представить данные интернет-магазина

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

В упрощённой реляционной модели могут быть таблицы:

ТаблицаЧто означает одна записьВажные поля
productМодель товараидентификатор, название, описание
variantКонкретный продаваемый вариантидентификатор, товар, артикул, цвет, мощность
customerПокупательидентификатор, контакты
orderЗаказ как целоеидентификатор, покупатель, сумма, статус
order_itemОдна позиция заказазаказ, вариант, количество, цена на момент покупки
paymentПопытка или факт оплатызаказ, провайдер, сумма, статус
status_historyИзменение состояниязаказ, старый и новый статус, время, автор

Таблица состоит из строк и столбцов. Строка, или запись, описывает один объект. Столбец, или поле, хранит один тип свойства. Схема задаёт таблицы, поля, типы, связи и ограничения.

Цена в order_item нужна отдельно от текущей цены варианта. Если завтра светильник подорожает, старый заказ должен сохранить сумму, с которой согласился покупатель. Это пример бизнес-правила, превращённого в структуру данных.

Идентификаторы и ключи

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

Внешний ключ указывает на запись другой таблицы. Поле product_id в варианте связывает SKU с моделью товара. order_id в позиции связывает её с заказом. Благодаря этому СУБД может проверять, что ссылка ведёт на существующий объект.

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

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

Иногда повтор нужен намеренно: цена и название в позиции заказа фиксируют состояние сделки на момент покупки, а не дублируют текущую карточку товара по ошибке. Это осознанная денормализация. Её допустимость определяют назначение поля, владелец и правило обновления; копия без этих трёх ответов быстро становится конфликтом.

Ключ — это не технический номер ради программиста. Это способ сохранить идентичность объекта, пока его названия, цены и статусы меняются.

Ограничения защищают бизнес-правила

Тип данных ограничивает допустимые значения: дата, число, текст, логический признак. Ограничение NOT NULL запрещает NULL, но само по себе не доказывает содержательную заполненность строки. Ограничение UNIQUE, часто реализованное СУБД через уникальный индекс, контролирует повтор значений по правилам конкретной СУБД; обработка NULL различается. Внешний ключ проверяет, что ненулевое ссылочное значение соответствует существующей записи, если связь и действия при обновлении или удалении заданы корректно.

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

Часть проверок выполняется в приложении, чтобы показать человеку понятную ошибку. Часть должна дублироваться ограничениями базы, чтобы повреждённый запрос или интеграция не записали невозможное состояние. Если скидка не может быть отрицательной, полагаться только на JavaScript в браузере рискованно.

Целостность означает согласованность данных с правилами системы. Она не гарантирует правду о внешнем мире. База может корректно хранить остаток 20, хотя на складе физически лежат 18 единиц. Это уже проблема обмена, учёта или процесса инвентаризации. Структура помогает заметить противоречие, но не заменяет дисциплину.

Источник правды и интеграции

В одном проекте товары редактируют в CMS, цены рассчитывает ERP, контакты ведёт CRM, а заказы создаёт магазин. Если одинаковое поле можно независимо менять в трёх системах, спор неизбежен.

Источник правды — система, чьё значение считается основным для конкретного объекта или свойства. Необязательно выбирать одну систему для всего. CMS, например OpenCart, может быть главной для описания, ERP — для цены и остатка, платёжный сервис — для подтверждённого статуса транзакции. Важно записать направление обмена и поведение при ошибке.

Интеграция должна отвечать на вопросы:

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

При автоматическом обновлении цен и остатков важны не только скорость и объём. Автоматизация полезна, когда определены источник, идентификаторы и правило обновления. Иначе скрипт лишь быстрее размножает ошибки.

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

Запросы: как приложение получает данные

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

Запрос «покажи все заказы клиента» соединяет таблицы по ключам и отбирает строки. Корректные связи позволяют однозначно сопоставлять записи, но одинаковый результат между запусками требует учитывать изменения данных, снимок транзакции и явный порядок сортировки. Если контакт покупателя хранится только текстом в комментарии, найти историю надёжно не получится.

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

Производительность нельзя оценить по одной цифре. Важны объём, распределение значений, частота чтения и записи, конкуренция запросов и оборудование. Оптимизация начинается с измерения реального медленного пути, а не с добавления индексов на каждое поле.

Индекс ускоряет поиск, но имеет цену

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

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

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

Официальная документация PostgreSQL описывает разные индексные методы, составные, частичные и уникальные индексы. Для статьи важен принцип: индекс выбирают под реальные запросы и ограничения. Фраза «поставим индекс, и база полетит» без плана выполнения и измерения — предположение.

Транзакция объединяет изменения

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

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

У транзакций есть свойства, которые часто обозначают ACID:

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

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

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

Конкурентный доступ: два покупателя и один товар

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

Реляционные СУБД предоставляют блокировки, уровни изоляции и другие механизмы конкурентного доступа, но их значения и уровень по умолчанию различаются. Обычная последовательность «прочитать → вычислить → записать» может потерять параллельное обновление, если приложение не использует подходящую блокировку, условный или атомарный UPDATE, контроль версии либо более строгую изоляцию с корректным повтором транзакции. Конкретное решение зависит от модели: резервировать товар при создании заказа, при оплате или на ограниченное время; допускать отрицательный остаток; подтверждать заказ менеджером. Технический механизм должен следовать бизнес-правилу.

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

Важно различать остаток «на складе», «доступно для продажи» и «зарезервировано». Одно число часто не описывает процесс. База данных должна хранить те состояния, которые бизнес реально использует.

Миграции меняют структуру, но не гарантируют сохранность данных

Проект развивается: к заказу добавляют способ доставки, товар получает новые характеристики, пользователям назначают роли. Изменение схемы называют миграцией. Обычно это версионированный набор операций, который создаёт или меняет таблицы, поля, индексы и ограничения; конкретный инструмент и транзакционность DDL зависят от СУБД.

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

Перед релизом нужны ответы:

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

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

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

Доступы и журнал действий

База содержит коммерческие и персональные данные, поэтому прямой доступ нужен не каждому сотруднику и не каждому модулю. Приложение должно работать от отдельной роли с минимально необходимыми правами. Аналитический отчёт может читать данные, но не обязан удалять заказы. Сервис импорта товаров не должен получать доступ к пользователям.

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

Журналирование помогает понять, кто и когда изменил критичное состояние. История статусов заказа, возвратов и прав пользователя полезна для расследования и поддержки. Но журнал не должен бесконтрольно копировать пароли, токены, строки подключения, платёжные данные и чувствительное содержимое; доступ, целостность и срок хранения журнала тоже требуют отдельной политики.

Владелец бизнеса не обязан иметь ежедневный SQL-доступ. Он обязан контролировать договоры, административные учётные записи, экспорт и процедуру передачи новому подрядчику. База без доступного владельцу пути восстановления превращается в актив подрядчика.

История, удаление и срок хранения

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

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

Резервное копирование и восстановление

Резервная копия базы создаёт возможность вернуться к сохранённому состоянию, но сама по себе не доказывает восстановимость. Документация PostgreSQL описывает три подхода именно для PostgreSQL: логическую выгрузку SQL, копирование файлов и непрерывное архивирование. Это описание нельзя автоматически переносить на другую СУБД или managed-сервис.

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

В PostgreSQL восстановление на момент времени требует согласованной базовой копии и непрерывной доступной последовательности архивных WAL до целевой точки. Наличие переключателя «PITR» в managed-панели не подтверждает фактическое окно, гранулярность и время восстановления: это проверяют по документации тарифа и пробным восстановлением.

Проверка копии и проверка восстановления — разные действия. Файл может существовать, но оказаться повреждённым, неполным или несовместимым. Тест выполняют в изолированной среде: разворачивают базу, запускают подходящую версию приложения, проверяют количество объектов и критичные сценарии.

Копии должны храниться отдельно от основной системы с ограниченными доступами и понятным сроком хранения. Резервная база тоже содержит чувствительные данные; оставлять её в публичном хранилище опасно.

Что проверить у подрядчика

Перед запуском или серьёзной интеграцией соберите ответы:

  • Какая СУБД и версия используются.
  • Где описана схема и кто владеет миграциями.
  • Какие таблицы соответствуют ключевым бизнес-объектам.
  • Какая система считается источником для каждого объекта или свойства и где описаны исключения.
  • Как связаны идентификаторы между сайтом, CRM и ERP.
  • Какие ограничения защищают целостность.
  • Как обрабатываются повторы и частичные ошибки.
  • Кто имеет административный доступ.
  • Где хранятся секреты и как отзываются права.
  • Как часто создаются копии и где они лежат.
  • Когда последний раз выполнялось полное восстановление.
  • Как бизнес получит данные при смене подрядчика.

Если ответ звучит как «база стандартная, там всё само», просите показать схему одного заказа или заявки. Конкретный объект быстро обнаруживает неясные связи.

Резюме от Хлеба

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

Не начинайте разговор с рейтинга СУБД. Сначала нарисуйте бизнес-объекты, источники правды и границы транзакций, затем проверьте запросы, доступы, миграции и восстановление. Если данные уже расходятся между сайтом, CRM и учётом, Xleb может разобрать модель и интеграции, найти места потери состояния и подготовить безопасный план изменений.


Обсудить проект

Елизавета Смерчинская

Менеджер проектов


ОФИС

Екатеринбург
ул. 8 Марта, 12А

РАБОТАЕМ

Пн-пт с 10:00 до 19:00

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