Ассоциативные связи

от автора

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

Ретроспектива

Relational tables, document oriented databases, jsonb stores… В них мы часто представляем минимальной единицей смысла модель в таблице/коллекции. Модель состоит из разной структуры колонок/полей, и отражает некий реальный объект или абстрактную концепцию автора.

Такой подход создает проблемы:

  • Множество пространств адресации. (Если вы не видите ее, вскоре будет статья исключительно на эту тему, и вы увидите почему это проблема реальна).

  • Множество точек контроля структуры данных, изменение которых стоит дорого.

  • Совместимость только на том уровне который заложен автором.

  • Неспособность полноценно описать что-то новое без создания еще одной таблицы/коллекции.

  • Невозможность разделить предметы от отношений между ними.

Все эти проблемы решаются в ассоциативной модели данных Deep.Case.

Если вам интересна оптимизация или поиск по диапазонам в графе — здесь будет ссылка.

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

Deep.Case оперирует концепцией Link (связь) как минимальной единицей смысла / квантом информации.

Links таблица

Links (сеть связей) очень похожа на граф, однако в графе есть однозначное деление на nodes (узлы) и edges (рёбра) ссылающиеся только на них. Links не разделяет эти пространства адресов. Это позволяет связям ссылаться на связи и нести любой смысл который в них может заложить автор моделей данных.

Link структура

Структура связи состоит из обязательных уникального id связи и type_id связи используемой как тип данной связи. Необязательные поля from_id и to_id могут быть заполнены только вместе.

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

Заполненные поля from_id и to_id ссылаются на другие связи. Такими связями можно описывать любые отношения.

{   links(where: { id: { _eq: 8 } }) {     id     type_id     from_id     to_id   } }
{   "data": {     "links": [       {         "id": 8,         "type_id": 1,         "from_id": 7,         "to_id": 6       }     ]   } }

Link как узел (node)

В связях можно не заполнять from_id и to_id. Такие связи играют роль node, узла, точки, предмета отношений.

{   links(where: { id: { _eq: 28 } }) {     id     type_id     from_id     to_id   } }
{   "data": {     "links": [       {         "id": 28,         "type_id": 6,         "from_id": 0,         "to_id": 0       }     ]   } }

Link как связь

Если from_id и to_id заполнены, связь играет роль отношения между узлами или связями. Она может ответить на вопрос как они связаны используя type_id. Некоторое окружение узла связями может ответить на множество вопросов о его смысле, отношениях, предназначении, значении и состоянии.

{   links(where: { id: { _in: [6,7,8] } }) {     id     type_id     from_id     to_id   } }
{   "data": {     "links": [       {         "id": 6,         "type_id": 1,         "from_id": 0,         "to_id": 0       },       {         "id": 7,         "type_id": 1,         "from_id": 0,         "to_id": 0       },       {         "id": 8,         "type_id": 1,         "from_id": 7,         "to_id": 6       }     ]   } }

Единый GraphQL API

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

Очевидно, что там доступна структура самой связи, а также из связи можно перейти к другим связям как по ее ссылкам (from_id и to_id), так и по обратным ссылкам от других связей (исходящих и входящих). Например, можно перейти на все связи которые ссылаются на данную связь по from_id (исходят из неё) с помощью relationship out, или по to_id (входят в неё) с помощью relationship in.

{   links(where: { id: { _eq: 8 } }) {     id     type {       id     }     from {       id       type_id       from_id       to_id       out {         id         type_id         from_id         to_id       }     }     to {       id       type_id       from_id       to_id       in {         id         type_id         from_id         to_id       }     }   } } 
{   "data": {     "links": [       {         "id": 8,         "type": {           "id": 1         },         "from": {           "id": 7,           "type_id": 1,           "from_id": 0,           "to_id": 0,           "out": [             {               "id": 8,               "type_id": 1,               "from_id": 7,               "to_id": 6             }           ]         },         "to": {           "id": 6,           "type_id": 1,           "from_id": 0,           "to_id": 0,           "in": [             {               "id": 8,               "type_id": 1,               "from_id": 7,               "to_id": 6             },             {               "id": 13,               "type_id": 1,               "from_id": 6,               "to_id": 6             },             {               "id": 24,               "type_id": 22,               "from_id": 23,               "to_id": 6             }           ]         }       }     ]   } } 

SQL-like queries

Мы можем не только получать данные по описанным выше структурам. Мы можем применять sql-like where предикат для выполнения разнообразных сложных фильтраций на каждом уровне.

{   links(where: {id: { _eq: 6 } }) {     id     type { id }     from { id }     to { id }     out(where: { from_id: { _eq: 6} }) {       id       type_id       from_id       to_id     }     in(where: { type_id: { _eq: 1} }, limit: 1) {       id       type_id       from_id       to_id     }   } }
{   "data": {     "links": [       {         "id": 6,         "type": {           "id": 1         },         "from": null,         "to": null,         "out": [           {             "id": 13,             "type_id": 1,             "from_id": 6,             "to_id": 6           }         ],         "in": [           {             "id": 8,             "type_id": 1,             "from_id": 7,             "to_id": 6           }         ]       }     ]   } }

Subscriptions

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

subscription {   links(where: { from_id: { _eq: 7 }, to_id: { _eq: 6 } }) {     id     type_id   } }

Поддержите ассоциативные технологии

Мы создаем среду разработки (коробочную CE/EE версию и SaaS версию), позволяющую использовать ассоциативный подход для решения ваших бизнес задач, нуждающихся в хранении данных, с возможностью адаптации под любые изменения бизнеса. Мы создадим распределённую сеть серверных кластеров в едином ассоциативном пространстве, в том числе чтобы не думать о региональном законодательстве, создавая проект. Мы создаём культуру публикации повторно используемых моделей данных с их поведением.

Присоединяйтесь к нашему сообществу в Discord. Подпишитесь на ранний доступ в нашем Waitlist или поддержите нас на Patreon. http://deep.foundation/

На нашем сайте можно найти ссылки на черновики будущих статей находящихся в разработке, ссылки на исходники кода, планы по project и product менеджменту и invest презентации.

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

Задача по рефакторингу вам нужна для подготовки систем к следующим задачам по изменениям в бизнес логике?

50% Да7
50% Нет7

Проголосовали 14 пользователей. Воздержались 2 пользователя.

ссылка на оригинал статьи https://habr.com/ru/articles/576398/