Не Делайте Лишних Столбцов В Таблицах, Они Вам Не Нужны.

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

Организация и систематизация — мое любимое занятие.

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

Но такой подход отстал от времени, то есть он удобен, если ваша бизнес-логика работает на хранимых процедурах.

Тогда действительно записи таблицы — это готовые объекты вашей бизнес-логики.

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

Сервер базы данных предоставляет данные, а сервер приложений их обрабатывает. Мы, конечно же, говорим об онлайн-обработке транзакций (OLTP).

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

Ниже я расскажу о продвинутом методе хранения данных.



Расширенный формат хранения данных

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

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

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

Что помогает в поиске? Индексы.

То есть наша таблица должна иметь индекс для быстрого поиска и актуальные данные.

Таблица должна состоять из индексных столбцов и столбца с фактическими данными.

Для обеспечения согласованности данных вы можете добавить столбцы внешнего ключа.



Пример реализации

Допустим, перед нами стоит задача обработки неких документов.

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

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

Что мы получили

   

create table document ( id integer not null constraint document_pk primary key, doc_num text not null, status_id integer constraint document_status_id_fk references status, data jsonb ); create unique index document_doc_num_uindex on public.document (doc_num); create index document_status_index on public.document (status);



Откуда берутся уши?

Я не сам пришёл к этой схеме хранения данных; Эту идею я позаимствовал у Филиппа Дельгадо.

Его доклады на конференциях можно посмотреть с тайм-кодами: один раз , два .

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



Метод работы с СУБД

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

Или, как правило, не нужно искать по заказам пользователей, чтобы показать заказы, содержащие определенное количество определенного товара, нужно показать список заказов.

Для аналитики в системах Online Analytical Processing (OLAP) выполняются запросы с пользовательскими выборками по языку интерфейса или со средним чеком заказа; это их хлеб.

Обычно обработка онлайн-транзакций (OLTP) занимается атомарной обработкой одной записи.

Вам необходимо получить данные от пользователя и записать их в таблицу.

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

Эта работа с записью будет продолжаться до полного завершения бизнес-процесса.

После этого вы никогда не вернетесь к этой записи, вы загрузите ее в OLAP и забудете о ней навсегда.

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

Все равно они все будут прочитаны.

При разделении информации на отдельные столбцы и записи в один столбец объем данных, передаваемых из СУБД в приложение, не изменится.

Взять JSON и превратить его в объект — простая задача.

Обратная задача — получение JSON-представления объекта — также является элементарной задачей.

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

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

Для каждой нашей модели мы пишем реализацию сериализации с обновлением значений в индексных столбцах.

Это методы на несколько строк кода, ничего сложного.



Преимущества

Каковы преимущества использования одного столбца для всех данных?
  1. При добавлении нового свойства в сущность не нужно менять схему данных, не нужно писать миграцию.

  2. Теперь миграции нужны только для создания таблицы, а этот код упрощается до пары столбцов.

  3. Меньше миграций — проще развертывание.

  4. Никому и в голову не придет строить аналитические отчеты на Прикладной СУБД; Для этого будет использоваться OLAP.


Недостатки

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

  2. Для каждой модели нужно написать код обновления значений в столбцах индекса.



Когда следует использовать этот подход?

Мой ответ: всегда.

Все, что вам нужно сделать, это преодолеть инерцию своего мышления.

Упрощение развертывания и сокращение количества миграций — серьезное преимущество для по-настоящему промышленных систем.

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

Если вы используете автоматическое создание внешнего интерфейса из схемы базы данных (пример Craftable — генератор CRUD Laravel ), то такой вариант записи данных в один столбец вам будет мешать.

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

Используйте его с удовольствием.

В опросе могут участвовать только зарегистрированные пользователи.

Войти , Пожалуйста.

Использование подхода «столбцы только для индексов» 4,04% был положительный опыт использования этого подхода 4 20,2% был неприятный опыт использования такого подхода к работе с данными 20 15,15% можно попробовать 15 4,04% Не хочу волноваться насчет ORM, я хочу побеспокоиться о миграциях 4 56,57% автор, о чем ты говоришь? Проголосовали 56 99 пользователей.

24 пользователя воздержались.

Теги: #база данных #Анализ и проектирование систем #json #OLTP

Вместе с данным постом часто просматривают: