12 июля 2024 1761
Смотрим, как вездесущий PostgreSQL справляется с нестандартными для реляционной системы управления базами данных (СУБД) ролями: хранением и поиском временных рядов, пар «ключ — значение», эмбеддингов для больших языковых моделей и многомерных кубов.

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



Смотрим, как вездесущий PostgreSQL справляется с нестандартными для реляционной системы управления базами данных (СУБД) ролями: хранением и поиском временных рядов, пар «ключ — значение», эмбеддингов для больших языковых моделей и многомерных кубов. Отвечаем на вопрос: действительно ли так нужно строить сложные архитектуры со множеством разнородных систем хранения данных — MongoDB, Redis, InfluxDB, Pinecone, ClickHouse, Apache Cassandra — или можно обойтись одним PostgreSQL?

Привет, Хабр! Меня зовут Александр Брейман, я доцент департамента программной инженерии факультета компьютерных наук НИУ ВШЭ и по совместительству эксперт Учебного центра IBS по управлению данными и архитектуре ПО. В прошлой статье я рассказывал о миграции с Oracle на PostgreSQL, а сегодня разберу, как последний работает с нетипичными видами данных.


Предыстория реляционных СУБД

Начну немного издалека. Разработка первой в истории базы данных началась в США в 1950-е годы. Как водится, заказчиком инновации был военно-промышленный комплекс. В ответ на появление в СССР дальних бомбардировщиков и ядерных бомб Пентагон решил разработать объединенную систему ПВО, в рамках которой актуальные данные обо всем, что происходит в небе, должны были собираться так, чтобы быть сразу доступными для принятия оперативных решений, например, о подъеме истребителей для перехвата цели. Вот это место, куда сразу поступают все имеющиеся данные, и назвали базой данных.



Схема проекта. Источник: http://www.fortwiki.com/File:Sage_Data_Flow.jpg

В основе такой базы данных лежали следующие принципы:

  • одна единая база данных на всю страну;

  • писатели вносят имеющиеся у них данные один раз;

  • читатели видят всегда актуальные данные;

  • для пользователей с разными задачами создаются отдельные представления (view).

Проект под кодовым названием SAGE сначала предложили IBM, но компания отказалась по причине нехватки программистов. На тот момент в IBM работало порядка 200 разработчиков, а проект, по их оценке, требовал привлечения тысяч специалистов. В результате под проект создали отдельную компанию — System Development Corporation. В разное время над SAGE работали до 7 000 человек.

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

Собственно, именно эту проблему и были призваны решить реляционные СУБД (понятие «реляционный» основано на англ. relation — «отношение, зависимость, связь»). Эта концепция, скрывающая физический уровень хранения от разработчиков, которые теперь работают с более высокоуровневым и защищенным логическим представлением, была придумана в IBM в конце 1960-х математиком Эдгаром Коддом. Вместо указателей в реляционной модели — значения в столбцах таблицы. Связь строк идет только через совпадение значений, без каких-либо «физических» указателей.

Эдгар Кодд описал 12 правил, «Codd's 12 rules», которым должна удовлетворять реляционная СУБД. Хотя на самом деле их 13, потому что исчисление начинается с нуля. Вот эти правила:

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

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

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

3. Неизвестные или отсутствующие значения NULL, должны поддерживаться для всех типов данных при выполнении любых операций.

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

5. Система должна поддерживать полноту подмножества языка.

6. Каждое представление (view) должно поддерживать все операции манипулирования данными: выборку, вставку, изменение и удаление.

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

8. Приложения не должны зависеть от используемых способов хранения данных на физических носителях.

9. Представление данных в приложении не должно зависеть от структуры реляционных таблиц.

10. Вся информация, необходимая для поддержания и контроля целостности, должна находиться в словаре данных.

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

12. Разноуровневые языки доступа к данным должны быть согласованы между собой.


Проще говоря, мы видим следующие ключевые принципы:

  • разделение логической и физической структуры базы данных;

  • логическая структура: никаких указателей и ссылок;

  • только таблицы, строки которых имеют одинаковую структуру;

  • связь строк в разных таблицах: одинаковое значение в соответствующих столбцах;

  • язык, позволяющий выразить сложные составные запросы;

  • физическая структура — НЕ копия логической структуры, может быть очень сложной.

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

Главная проблема реляционных СУБД

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

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

Шардирование

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




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

Репликация

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




Репликация повышает отказоустойчивость системы и обеспечивает параллельное чтение данных. Ограничения подхода возникают в том случае, если запрашиваемый узел, на который планируется копирование данных, по какой-то причине не отвечает. Тогда другой узел может либо пытаться «достучаться» до него, и тогда время выполнения записи удлиняется на длительность такого ожидания, либо сохранить данные у себя и отрапортовать об успехе операции, рискуя несогласованностью реплик. Более строго и подробно эта идея описана в виде CAP-теоремы.

Шардирование и репликация

Обычно используются вместе:



Сделать кластер из реляционных баз данных c шардированием и репликацией — не такая уж сложная задача, но ее приходилось реализовывать каждой компании самостоятельно. Например, Google с середины 1990-х годов хранил все свои данные — и поисковый индекс, и почту, и карты — в кластерах MySQL и полностью перешел на собственные технологии типа Spanner только после 2013 года. Сами реляционные системы стали предоставлять эти механизмы «из коробки» совсем недавно. Например, в Oracle шардирование появилось только в 2018 году, а в PostgreSQL оно полноценно реализовано только в платном Postgres Pro Shardman.

Альтернативные системы хранения данных

А до тех пор разработчики пытались найти замену «несовершенной» реляционной модели. Так, в конце 2000-х годов на арену вышли другие системы управления базами данных класса NoSQL, например MongoDB. Ее разработчики предложили автоматическое шардирование с репликацией, пусть и с предварительной настройкой, прямо «из коробки».

В класс NoSQL входят такие распространенные типы систем, как «ключ — значение», документные, графовые и объектно ориентированные системы. Все эти СУБД, а также временные ряды, поисковые движки и векторные базы данных были придуманы в свое время как способ нивелировать недостатки реляционных СУБД, в первую очередь — плохо выявляемые сбои в больших кластерах при использовании consumer-grade оборудования и открытого ПО без специальных требований к надежности, а также ошибки в архитектуре систем, использующих высоконормализованные реляционные модели данных.


Нетипичные данные и способы расширения PostgreSQL

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


Как хранить и искать документы

В упомянутой выше модели «ключ — значение» часть данных мы считаем ключом, по которому можно искать и записывать определенный массив байтов. У такой модели максимально простой API с тремя базовыми операциями: put, get и delete.

Документ — это, по сути, вариант значения в модели «ключ — значение», но с дополнительными возможностями. К документу можно обращаться по его частям — полям, можно использовать специальные функции, например XPath для XML, автоматически валидировать данные, строить индексы по полям, а не только осуществлять поиск по ключу, и проводить специальные операции. Подобные возможности реализованы в том же MongoDB.

В PostgreSQL похожие вещи пытались сделать еще в конце 1990-х, но приличный результат получился только в 2014 году за счет реализации типа JSON. Сегодня Postgres предлагает для работы с документами JSONB и JSONPATH.

JSONB — это тип данных, он позволяет разобрать текстовый документ при записи и затем хранить его в бинарном формате. Примитивные типы при этом отображаются в типы PostgreSQL: text, numeric и boolean. JSONB предоставляет множество функций для создания и обработки документов, дополнительные операторы для обращения к ключам и вложенным элементам, а также возможность индексирования по всему документу или по отдельным ключам.

Что касается JSONPATH, это язык выборки частей документов, созданный по мотивам языка выделения частей XML-документов XPath, позволяющий декларативно описать маршрут внутри документа, по которому нужно пройти, чтобы получить нужные элементы. Например, можно выбрать поле с некоторым именем, не зная заранее, на каком уровне вложенности оно находится.

Первые релизы JSONB обладали некоторыми ограничениями, но в 2021 году схему хранения ощутимо улучшили, и операции теперь выполняются заметно быстрее. На сегодняшний день JSONB — полноценная рабочая замена MongoDB. Пожалуй, единственное преимущество MongoDB в данном случае — простота масштабирования, в первую очередь за счет шардирования. Если вы берете Postgres Pro Shardman, то для вас смысл работы с MongoDB пропадает совсем. Если же вы «сидите» на бесплатной версии PostgreSQL, то вопрос с документами «из коробки» получится решить только локально.

Как хранить и работать с временными рядами

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

В PostgreSQL для работы с временными рядами применяется опенсорсное решение TimescaleDB. Суть подхода в том, что создается так называемая гипертаблица, то есть таблица, автоматически секционированная по столбцу с меткой времени в соответствии с заданным интервалом, например по часу на секцию. Каждая секция при этом хранится и индексируется отдельно, а по истечении заданного периода «холодные» секции, в которые уже больше не будут добавляться записи, сжимаются для более компактного хранения. Среди других удобных особенностей решения — политика автоматического удаления устаревших данных, распределенное хранение секций с репликацией и наличие специализированных гиперфункций.

Выглядит это примерно так:

CREATE TABLE conditions(

 tstamp timestamptz NOT NULL,

 device VARCHAR(32) NOT NULL,

 temperature FLOAT NOT NULL);

SELECT create_hypertable(

 'conditions', 'tstamp',

 chunk_time_interval => INTERVAL '1 day'

);

SELECT create_hypertable(

 'conditions', 'tstamp',

 partitioning_column => 'device',

 number_partitions => 8,

 chunk_time_interval => INTERVAL '1 day');

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

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

Как хранить эмбеддинги и быстро их искать

Еще один тип данных, плохо приспособленных для реляционных СУБД, — это векторы. Каждая запись в векторной базе данных — это большой массив из чисел, или вектор в многомерном пространстве. Типичный запрос к такой базе: по заданному вектору найти векторы, наиболее близкие к нему. Определить близость векторов можно разными способами, например через косинусную меру или евклидово расстояние. Полноценный ответ на запрос в неспециализированных системах требует перебора всех хранящихся векторов, поскольку традиционные индексы — B-tree и Bitmap — не в силах эффективно ускорить решение такой задачи.

Сама по себе история с векторами сейчас предельно популярна, поскольку она используется при работе с большими языковыми моделями типа ChatGPT в рамках подхода retrieval augmented generation (RAG). В больших языковых моделях заложено кодирование текста/токенов в такие вектора — эмбеддинги. Мы можем закодировать все документы в виде эмбеддингов и сохранить их в базе данных, а затем так же закодировать запрос и найти ближайшие к нему эмбеддинги. После извлечения ближайших по смыслу документов, мы добавляем их к промпту для обогащения контекста запроса и передаем его в большую языковую модель. На подходе RAG сейчас строится много расширений нейронных сетей, что привело к всплеску популярности векторных баз данных. Таким же образом, кстати, в векторных базах можно искать изображения или звуки, строить рекомендации, а также находить аномалии, то есть обнаруживать отсутствие достаточно близких векторов.

В PostgreSQL для всего этого есть простое расширение pgvector. Оно работает с типом данных vector и предоставляет два алгоритма поиска — IVFlat и HNSW, — из которых нужно выбрать при создании таблицы. Один из них более быстрый, менее требовательный к памяти, но менее точный, а другой — точнее, но медленнее и ресурсозатратнее. По сути, они кластеризируют вектора, а затем осуществляют перебор в небольших кластерах.

Синтаксически это выглядит так:

select text, embedding <=> (

 select embedding from t where text = ‘??'

 ) distance

from t

order by distance;

Стоит сказать, что векторных баз сегодня представлено множество, включая такие многомиллионные стартапы, как Pinecone и Qdrant. PostgreSQL с расширением pgvector, — вполне достойный вариант. Основным ограничением будет все то же масштабирование.

Как строить многомерные кубы

Последняя специфическая история, не предназначенная для реляционных баз данных, — это многомерные кубы. Они были придуманы как инструмент для построения отчетов в хранилище данных, рассчитанный на НЕпрограммистов. Чтобы непрограммисты не напортачили в базе данных, им предоставили специальные витрины на многомерных кубах. Технология интерактивной аналитической обработки данных OLAP (online analytical processing) заключается в подготовке агрегированной информации на основе больших массивов данных, структурированных по многомерному принципу. Витрины данных позволяют пользователям самостоятельно описывать запросы и вид отчетов с помощью простого интерфейса и снижают риск перегрузки базы неоптимальными запросами

В языке SQL для реализации OLAP-сценариев в реляционных базах данных стандартные расширения были добавлены уже четверть века назад. Это GROUP BY ROLLUP, GROUP BY CUBE и GROUP BY GROUPING SETS. Расширения позволяют построить витрину по исходным данным и дальше сделать интерфейс.


Вердикт

Реляционные базы были ответом на очень важную потребность индустрии — отвязать физический уровень хранения от логического и набрать сотрудников, которые смогут писать запросы к базе данных на логическом уровне, не рискуя ее поломать. Эту простоту логики нам и подарили реляционные базы, и отказываться от нее на сегодняшний день было бы странно. Добавление NoSQL-решений, которые справлялись с нетипичными для реляционных баз данными, но не отличались простотой языка, имело смысл в нулевых годах. Но сегодня реляционные СУБД, включая PostgreSQL, уже откликнулись на волну NoSQL и внедрили ряд инструментов, которые позволяют справляться с большинством задач, включая полнотекстовый поиск, работу с временными рядами и даже векторными данными. Конечно, в устройстве этих инструментов придется сначала разобраться, но это определенно проще, чем использовать новую СУБД под каждый тип задачи и нанимать штат специалистов, разбирающихся в их устройстве. Оригинал статьи размещен на ХАБРе.





Последние статьи в блоге

Разбор задачи: UML-диаграмма классов для системы регистрации на курсы

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

22 мая 2025

Бизнес-аналитик и системный аналитик в ИТ: кто есть кто и в чем разница

Современные ИТ-проекты — будь то корпоративные решения, мобильные приложения или интеграционные платформы — требуют точного понимания как бизнес-целей, так и технических ограничений. На пересечении этих задач появляются две ключевые роли: бизнес-аналитик (БА) и системный аналитик (СА). Несмотря на схожесть направлений деятельности, эти специалисты действуют на разных уровнях и выполняют разные функции. Рассмотрим, кто они, каковы их зоны ответственности, чем они похожи, а чем принципиально отличаются.

21 мая 2025

5 распространенных ошибок в работе системных аналитиков

Ошибки системных аналитиков редко видны сразу, но последствия могут быть весьма заметными. Срыв сроков, недовольство заказчика, бесконечные правки требований, ощущение, что проект «расползается» — это часто не проблема менеджмента, а не выявленные вовремя аналитические ошибки и риски. Мы регулярно анализируем дипломные проекты выпускников курса «Системный аналитик» — не ради оценок, а чтобы понять, какие трудности реально возникают на практике, и обозначить направления для дальнейшего развития навыков. Даже у мотивированных специалистов с практическим опытом есть «слепые» зоны. Где-то не хватает чёткости в декомпозиции, где-то — качества проработки связей между сущностями, понимания архитектуры. Даже отсутствие умения аргументировать выбор решений перед бизнесом может негативно повлиять на проект. Мы вместе с Екатериной Тихомировой — практикующим аналитиком с более чем десятилетним опытом — разобрали некоторые типичные ошибки и риски, и способы, как их предотвратить.

20 мая 2025

Итоги работы Центра сертификации IBS

Центр сертификации IBS начал свою работу в апреле 2023 года, поэтому мы традиционно подводим итоги работы в апреле-мае. Прошедший год стал для нас периодом важных изменений. В 2024 году произошло несколько знаковых событий: наша команда обновила программы сертификации системных аналитиков и Java-разработчиков, подготовила к запуску сертификацию бизнес-аналитиков, получила аккредитацию от АПКИТ и стала обладателем Гран-при премии «Смарт пирамида». Рассказываем подробнее, каких результатов мы достигли в уходящем году и как это отразилось на нашей работе.

Новости
19 мая 2025

Какой метод тестирования выбрать: черный, белый или серый ящики?

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

14 мая 2025

Удостоверение, диплом и сертификат: в чем разница и что выбрать

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

12 мая 2025

Выгодный май — на курсы залетай!

Друзья, спешим поделиться отличной новостью — вы можете получить скидки до 40% на наши популярные курсы. Это отличная возможность улучшить навыки и инвестировать в профессиональное развитие по более выгодной цене. Выбирайте направление и подавайте заявку прямо сейчас!

05 мая 2025

Кейс: кастомизация курса по Jira

Кейс по проведению кастомизированного курса «Основы Jira» для крупной российской компании, занимающейся производством цифровой техники.

05 мая 2025

Зачем специалистам по 1С изучать системный анализ и архитектуру ПО

Как системный анализ и архитектура ПО помогают эффективнее работать в 1С.

29 апреля 2025

Банка Nutella, IT, ESG — что общего?

Когда вы читали этикетку на продукте не из-за состава, а из-за ESG-маркировки?

25 апреля 2025

Каковы плюсы и минусы монолитной и микросервисной архитектуры при разработке ИТ-продуктов?

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

25 апреля 2025

Станьте архитектором ПО с выгодой! Только в апреле сэкономьте 20 000 ₽ и получите новый модуль по микросервисам в подарок

24 апреля стартует обучение на комплексной программе «Архитектор ПО. Путь к мастерству в проектировании систем»*.

14 апреля 2025

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

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

Новости
10 апреля 2025

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

Мы адаптировали курс по управлению проектами под запрос команды крупной промышленной компании и провели обучение. Вот что из этого вышло.

27 марта 2025

Кейс: Обучение сотрудников крупной компании работе с ClickHouse

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

19 марта 2025

Платформа сертификации IBS получила аккредитацию АПКИТ

Ассоциация предприятий компьютерных и информационных технологий (АПКИТ) приняла новый регламент сертификации ИТ-специалистов.

Новости
10 марта 2025

Специальные акции на учебные программы

У нас отличная новость для всех, кто стремится развивать свои навыки в мире ИТ.

06 марта 2025

Как остановить спам-атаку

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

06 марта 2025

Учебный центр IBS подписал партнерское соглашение с ООО «РусБИТех-Астра», разработчиком российской операционной системы Astra Linux.

Теперь мы можем проводить авторизованное обучение по работе с Astra Linux для специалистов в области информационной безопасности.

17 февраля 2025

Двойная выгода: покупай один курс — получай второй за 50% стоимости!

Воспользуйтесь возможностью изучить более глубокие аспекты одной области — например, при покупке курса по Java, архитектуре ПО, управлению проектами, системному и бизнес-анализу, тестированию ПО и Big Data вы можете получить второй курс этой же тематики за полцены! Не упустите шанс развить свои навыки и поднять свою карьеру на новый уровень. 

29 января 2025

Не нашли, что искали? — Просто напишите, и мы поможем

Корпоративное обучение Оценка персонала Сертификация О нас Стань тренером Блог
Пользователь только что записался на курс ""
Спасибо!
Форма отправлена успешно.