Как хранить граф в базе данных
Перейти к содержимому

Как хранить граф в базе данных

  • автор:

Как хранить граф в реляционной БД?

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

P.S. Основная база — PostgreSQL. Хотелось бы оставить все данные в ней.

wyldrodney ☆
07.12.13 14:00:12 MSK

В одной таблице хранить узлы, а в другой — связи между узлами?

POLTER ★★
( 07.12.13 14:02:39 MSK )

Смотря какие операции нужны. Хранить можно много как, хоть в JSON засунуть и заgzipовать в BLOB-поле.

Legioner ★★★★★
( 07.12.13 14:04:33 MSK )
Ответ на: комментарий от POLTER 07.12.13 14:02:39 MSK

А как обходить граф? Имеет ли смысл хранить во второй таблице смежные вершины? Если понадобится писать свойства рёбер?

wyldrodney ☆
( 07.12.13 14:13:06 MSK ) автор топика
Ответ на: комментарий от wyldrodney 07.12.13 14:13:06 MSK

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

POLTER ★★
( 07.12.13 20:24:03 MSK )

У этого модуля есть ограничение на 65 килобайт на поле. Стало интересно: сколько пользователей «влезет».

У меня соц. сеть с реферальной регистрацией. Пусть, каждый пользователь приводит в среднем 1.001 пользователя (реферала).

Так, если корневой пользователь наберёт 50 000 потомков, а это 9 999 552 пользователей, запись пути от корневого родителя до любого предка будет не более 58 995 симолов. Масштаб! 🙂

P.S. В документации говорится о 65Kb. Хочется верить, что это байты, но никак не биты: привык что байты обозначаются большой «B».

wyldrodney ☆
( 08.12.13 07:36:43 MSK ) автор топика

Охренеть, Вылдротень вернулсо!

Как твоя игра поживает? Как секс-зависимость? Велком бек он боард 🙂

anonymous
( 08.12.13 07:40:28 MSK )
Ответ на: комментарий от anonymous 08.12.13 07:40:28 MSK

Жена вчера пообещала уйти. Хе-хе, куда она с Бали денется?

wyldrodney ☆
( 08.12.13 07:43:29 MSK ) автор топика
Ответ на: комментарий от wyldrodney 08.12.13 07:43:29 MSK

Ты её заэтосамое штоле? 🙂 А чё на Бали, отдыхаешь аль дауншифтишь?

anonymous
( 08.12.13 07:49:42 MSK )
Ответ на: комментарий от anonymous 08.12.13 07:49:42 MSK

Если откровенно, она недолюбливает ЛОР, и в этом корень разногласий.

Отдыха тут нет: пива нет, водки нет, мяса нет, бляди страшные, местные — быдло, ни одного театра. Тут — фрилансю 🙂

wyldrodney ☆
( 08.12.13 07:55:50 MSK ) автор топика
Ответ на: комментарий от wyldrodney 08.12.13 07:55:50 MSK

Если откровенно, она недолюбливает ЛОР, и в этом корень разногласий.

Охренеть! =-O Ты же в последнее время почти не заходишь. Да и мало ли ты где сидишь. Похоже просто на попытку дое*ться на пустом месте, сорри 🙁

Отдыха тут нет: пива нет, водки нет, мяса нет, бляди страшные, местные — быдло, ни одного театра. Тут — фрилансю 🙂

Вали оттуда поскорее, у этой страны нет будущего, гореть ей в клоаке огненной! Чо, неужели нет стран с похожим климатом, но без вышеописанных critical bug’ов?

anonymous
( 08.12.13 07:59:43 MSK )
Ответ на: комментарий от anonymous 08.12.13 07:59:43 MSK

На Тенерифе мне понравилось, +23..+25 круглый год, правда, дожди всего пять дней в году. Пива хоть залейся. Девки отличные. Жрачка вкусная. Народ цивильный, университет даже есть, джазовые фестивали проводятся.

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

Yii Framework

Узел 7 ссылается на узел 1.
Насколько я понимаю это граф. У меня возникла проблема как его лутше сохранять в БД ? И потом обходить его.
Все что нашел ето для каждого узла отдельно хранить в список всех соседних узлов к примеру в json. Или вде таблици в первшой все узлы во второй все переходы.
Есть ли какие то готовые поведения для этого? Все что нарыл это nested set но он не подходит так как листя у меня могут ссылатся на верхнее уровни. вплоть до корня.
Есть какие то идеи по етому поводу?

как хранить в БД граф value object

Как видно из названия классов — объекты типа EntityA являются сущностями(в терминах DDD), а объекты типов ValueObjectA и ValueObjectB — объектами значениями. Нужно определить каким образом хранить в БД данный граф объектов. Что вызвало у меня трудности: связь между EntityA и ValueObjectA — один-ко-многим, между ValueObjectA и ValueObjectB тоже один-ко-многим. В этом случае логично для каждого класса создать отдельную таблицу в БД и связать эти таблицы между собой. Проблема возникает в связывании этих таблиц. Я не хочу добавлять в классы ValueObjectA и ValueObjectB идентификаторы, хочу чтобы они остались полноценными value object. В этом случае связать таблицы EntityA и ValueObjectA очень просто, а вот как связать таблицы ValueObjectA и ValueObjectB — я ума не приложу.

Хранение графовых данных в БД Vertica

В одном из проектов возникла необходимость работы с графовыми данными.

Сначала поискали готовые решения в сети.

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

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

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

У нас стояла задача выявления деструктивных участков в цепочках перемещения продуктовых партий. Один из модулей так и назывался: «Компонент выявления лишних посредников». Сырые данные были в виде полусотни таблиц и справочников, объем таблиц с данными от сотен млн. до десятков млрд. строк. Инструмент для работы — БД Vertica из 3 нод, поднятых в виртуалке.

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

Существует 3 основных способа укладки графовых данных в таблицу.

Матрица смежности

Данный способ на большинстве интернет ресурсов позиционируется как единственный. Пригоден для ограниченного количества ситуаций, когда число уникальных вершин не более ограничений на максимальное число колонок в базе данных. Например, при вычислении логистики между городами. Сами значения можно заполнить не только бинарными данными (True, False), но и одной из характеристик взаимосвязи. К примеру, в случае расчета оптимальной логистики это будет реальное время прохождения участка с учетом погодных условий, пробок, ДТП, ремонтов. Но значение можно сунуть только одно, или придется дублировать таблицу.

Список смежности

a: b: c: d: e: f:

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

Список ребер (таблица ребер)

a b a e b c b e b f c d c f d e

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

Данные представляли собой деревья.

Для предобработки сырых данных использовался алгоритм «Обход графа в ширину». То есть за один проход формировался «этаж» записей, добавлялся номер level, соответствующий «этажу», звено цепочки в path2FATHER и число ветвлений в count_branch. В сырых данных отсутствовали прямые связи между вершинами, для их связи использовались совпадающие id записей в журнал.

Из служебной информации были добавлены колонки:

  • FATHER — корень каждой цепочки, вершина из которой начинается ветвление,
  • level — удаленность от корня, «этаж»,
  • maxlevel — максимальная величина level при ветвлении из данной точки,
  • path2FATHER — разделенные запятыми ID в цепочке между данной вершиной и FATHER,
  • count_branch — число ветвлений в каждой точке цепочки между данной вершиной и FATHER.

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

Таблица ребер со служебными полями.

Распарсивание id из цепочки path2FATHER выполнялось встроенной в Vertica функцией v_txtindex.StringTokenizerDelim:

SELECT v_txtindex.StringTokenizerDelim(path2FATHER, ',') OVER() FROM public.br_RT_0_18 WHERE cert2 = '123456’;

В данном проекте для визуализации была использована библиотека GOJS. Функция использовалась для выгрузки данных из Vertica.

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

Другими словами, когда смена владельца партии товара связана не с транспортировкой или производственным преобразованием, а со стремлением «коммерсантов» накрутить цену на сырье или продукцию. С этой целью создаются от 7 до 30 ООО или ИП, и партия товара прогоняется через эту цепочку, обычно задерживаясь в каждом звене не более 3-х — 4-х часов.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *