Что такое идеальный "квант информации" или "минимальная единица смысла" и зачем задаваться этим вопросом? С этим связано много боли, часто даже неосознаваемой. Мы предлагаем решение, но сначала нужно разобраться для чего это нужно. Рекомендуем ознакомиться с первой статьёй в серии.
Ретроспектива
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 презентации.
Комментарии (8)
nin-jin
06.09.2021 08:34Вы описали принцип работы, наверно, любой графовой субд. Чем ваша реализация отличается? Ну, кроме крайней неэффективности запросов из-за отсутствия "легковесных" рёбер (прямые ссылки между узлами) и необходимости приджойнивать таблицы со значениями (про которые в статье вы почему-то забыли упомянуть).
lair
У меня, простите, идиотский вопрос.
Как с помощью этих "квантов информации" выразить простой факт: баланс на счету мистера Икс на 09.09.1909 составлял 800 франков?
IvanSGlazunov Автор
Спасибо @lair за внимание к нам и статьям. Очень приятно видеть такие вдумчивые вопросы и интерес.
Мы еще не релизнули packer/unpacker который бы позволял пушить ассоциативные модели с правами и поведением в пакет для пакетных мендежеров.
Сделал за 10 минут пример. Он работоспособен в демке.
Но если представлять как это могло бы быть не придираясь к словам: это были бы типы add, at, time в дополнение к тем что есть в демке. Я бы их добавил в mp нужный для запросов (это в следующей статье как раз). Пунктирные линии - визуализация materialized path вычисленного в триггере в момент когда mp_include добавил к каждому из новых типов.
Пример запроса для вычисления баланса. Если эти вычисления нужны очень часто, легко добавить линк sum и с помощью (еще не описанных) Associative handlers на js прямо в триггере в рамках транзакции он будет вычисляться, при добавлении или удалении add.
Поиск всех данных что есть
Вставка этой демо структуры в демке. Пока так. В разработке обращение к типам не по id а по package/typename (если сильно упрощать).
Прошу учитывать:
сейчас нет некоторых механик, и временный побочный эффект - необходимость указания id
пример перестанет работать уже в течении месяца-двух, так как 31, 32... id будут заполнены и вероятно появиться reserved id механика и механика обращения к линкам по package/linkName.
Получение всего о юзере
GUI будет намного приятнее, мы работаем над собственным вьювером, интуитивным управлением, и еще очень много чем. То что доступно сейчас - временно решение для наглядности демонстрации.
Мы будем подерживать кастомные таблички вроде этих string/number, поставляемые вместе с ассоциативными моделями. Единственное ограничение - они не должны использоваться для ссылочны данных, только для хранения данных.
lair
А что такое
number
в этой вашей записи? В статье ничего такого нет.IvanSGlazunov Автор
В статье и не должно быть. Статьи постепенно говорят о разных подходах, и концепциях. Все разом будет слишком много. Я учту что вы бы хотели большую насыщенность)
lair
Так что же это такое?
IvanSGlazunov Автор
В конце моего первого ответа я сразу дал ответ на этот вопрос.
Продублирую специально для вас.
lair
Я не понимаю, что такое "кастомные таблички". Слово "кастомные" наводит меня на мысль, что это что-то, что не является частью основной модели — а это, в свою очередь, наводит на мысль, что основная модель не способна к выражению нужных мне фактов.
Ну и да, сравнение вашего рисунка сверху с записью:
явно не в пользу первого, уж простите.