Data Model - moevm/nosql2h20-relatives-neo4j GitHub Wiki

Схема БД

SQL:

Graph representation (NOSQL)

Список сущностей

SQL:

1. Person - сущность представляющая собой конкретного человека, имеет следующие атрибуты:

id: Int - уникальный идентификатор, генерируется neo4j

firstName: str - Имя человека

lastName: str - Фамилия человека -

middleName: str - Отчество человека

sex: str - Пол

educ: str - Образование

bornDate: Date - Дата рождения

socialStatus: str - Пару слов о себе

img - Фотография человека (Путь на диске или URL)

2. RelativeRealtions - родословное отношение между людьми, имеет следующие атрибуты:

Id: Int - уникальный идентификатор, генерируется neo4j

PersonIdOne: Int - идентификатор первого человека в отношении

PersonIdTwo: Int - идентификатор второго человека в отношении

NOSQL(Neo4j):

Каждый человек в генеалогическом дереве представляет собой отдельный узел с указанными на графф - диаграмме атрибутами. Идентификатор узла - уникальный идентификатор человека. Он используется для создания родословных отношений между узлами, членами семьи. Каждое семейное дерево имеет свою метку на узлах label - например Давыдовы. Это позволяет проще строить поисковые запросы и создавать отношения. Само же отношение так же имеет метку label, означающая тип отношения. В данный момент существует только один тип отношений - DirectRelative

Оценка объема информации:

Neo4j:

1. Node:

id - 4B

firstName: str - 50B

lastName: str - 50B

middleName: str - 50B

bornDate: Date - 4B

sex: str - 50B

educ: str - 50B

socialStatus: str - 100B

label - 50B

img - 200B

Sum: 508B

2. Relation

id - 4B

label - 50B

Sum: 54B

Пусть в дереве N узлов, M отношений => v = 508N + 54M

Для дерева высотой 4, мы будем иметь 13 узлов и 14 связей. Примем эти числа как средние значения для каждого дерева => M = 13/14*N

Тогда v = 508N + 5413/14N = 558.14N

Примем N = 13, M = 14(Случай дерева до прадедушек и прабабушек 1 из членов нашей команды) -> v = 7360B

Пусть в базе данных 1000 генеалогических деревьев => V = 7360000B = 7,02Mb фактического объема

Исключая переменные id из узла и отношения, мы получим формулу для чистого объема => v = 504N + 5013/14N = 550,42N

Избыточность модели Neo4j: 558.14N/550,42N

Фактический

Запросы

Добавление узла

CREATE (n:FamilyTree {firstName: "Alex", lastName: "Davydov", middleName: "Anatolyevich", 
bornDate: datetime("1999-09-12"), socialStatus: "student"}) 
SET n.id = id(n)

Удаление узла

MATCH (n:FamilyTree { id: $id1 }) 
DELETE n

Добавление связи

MATCH (a:FamilyTree), (b:FamilyTree) 
WHERE a.id = $id1 AND b.id = $id2 
CREATE (a)-[: DirectRelative]->(b)

Удаление связи

MATCH (n:FamilyTree {id: $id1})-[r: DirectRelative]-(m:FamilyTree {id: $id2}) 
DELETE r

SQL

_1. Person

id: Int - 4B

firstName: str - 50B

lastName: str - 50B

middleName: str - 50B

bornDate: Date - 4B

socialStatus: str - 100B

img - 200B

Sum: 458B

_2. RelativeRealtions

Id: Int - 4B

PersonIdOne: Int - 4B

PersonIdTwo: Int - 4B

Sum: 12B

Пусть мы имеем N людей и M отношений родословной связи между ними => v = 458N + 12M

Для дерева высотой 4, мы будем иметь 13 узлов и 14 связей. Примем эти числа как средние значения для каждого дерева => M = 13/14*N

Тогда v = 458N + 1213/14 = 469,14*N

(как и в случае с Neo4j) -> v = 6098B

Пусть в базе данных 1000 генеалогических деревьев => V = 6098000B = 5,82Mb фактического объема

Исключая переменные Id, PersonIdOne, PersonIdTwo пересчитаем формулу => v = 454*N

Избыточность модели SQL: 469,14N/454N

Запросы

Добавить нового человека

INSERT INTO Person 
VALUE (person_id, "Alex", "Davydov", "Anatolyevich", "1999-09-12", "student")

Добавить новую родственную связь между людьми

INSERT INTO RelativeRelations
VALUE (relation_id, person_id_1, person_id_2)

Сравнение SQL и Neo4j

Запросы на Cipher являются более компактными по сравнению на SQL. Для реализации отношения в SQL требуется созданиe дополнительных сущностей

Графовая модель данных занимает больше места в памяти, чем реляционная, но работает быстрее.

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

Доп Задание

Mongo(Представление данных)

{
"_id": <ObjectId>,
"firstName": "Alexander",
"lastName": "Davydov",
"middleName": "Anatolyevich",
"bornDate": <Timestamp>,
"socialStatus": "student",
"img": "/Home/imgs/img.jpg",
"fatherId": <ObjectId>,
"motherId": <ObjectId> 
}

Список сущностей

Каждое поле за исключением fatherId, motherId представляет собой ту же сущность как и в обзоре SQL-сущностей(см. первые пункты статьи)

fatherId - это идентификатор отца, по умолчанию имеет значение null

motherId - это идентификатор матери, по умолчанию имеет значение null

Оценка объема информации:

id: Int - 4B

firstName: String - 50B

lastName: String - 50B

middleName: String - 50B

bornDate: Date - 4B

socialStatus: String - 100B

img: String - 200B

fatherId: Int - 4B

motherId: Int - 4B

Sum: 466B

Мы получаем довольно таки простой случай, где объем информации будет пропорционален числу сущностей в дереве => v = 466*N

Пусть мы имеем 1000 деревьев в среднем включающих 14 родственников => V = 144661000 = 6,22Mb фактического объема данных

Исключая переменные _id, motherId, fatherId, получаем формулу для пересчета чистого объема данных => v = 454*N

Избыточность модели Mongo: 466N/454N

Запросы

Добавление узла

db.familyTree.insertOne(
{
_id:1,
firstName: "Alexander",
lastName: "Davydov",
middleName: "Anatolyevich",
bornDate: new Date("1999-09-12"),
socialStatus: "student",
img: "/Home/imgs/img.jpg",
fatherId: null,
motherId: null 
})

Добавление связи между узлами

db.users.updateOne(
{
_id: $id
}, 
{
$set: {`fatherId` : $fatherId, `motherId`: $motherId}
})
⚠️ **GitHub.com Fallback** ⚠️