2014-10-15 3 views
1

Я начинаю работать в графических базах данных, поэтому, пожалуйста, расскажите обо мне, прежде чем я немного поработал с реляционным mySQL, но я не рассматриваю себя как гуру в этой области. Я нашел следующие вопросы 12 относительно дизайна базы данных, но я хотел бы знать ваше мнение о моей проблеме. Я хочу создать свой собственный набор данных, на котором я могу проверить свои запросы Cypher. Одной из областей, которая приходит мне на ум, является набор данных, который будет похож на социальную сеть, ориентированную на слушателей музыки, что-то вроде LastFM.Пример neo4j - график против реляционных понятий

Так что моя первая мысль была создать два типа узлов Bands и лиц:

(nir:Band { name: "Nirvana", town: "Seatle", country: "USA", genere: "Grunge" }) 
(dgr:Person { name: "Dave Grohl", born: 1969, instrument: "drums" }) 

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

(dgr)-[:IS_MEMBER_OF {from: 1987, to: 1994} ]->(nir) 
(user1)-[:IS_FRIEND_OF]->(user6) 
(user1)-[:LIKES]->(nir) 

Тогда я понял, что это понятие имеет минимум три ограничения, которые я могу видеть прямо сейчас:

  1. диапазон может быть классифицирован только по одному жанру
  2. Группа может исходить только из одного города/страны
  3. Участник группы может играть только на одном инструменте во всех диапазонах, в которых он когда-либо был членом

Чтобы решить первые две проблемы, я сначала подумал о некоторых типах данных, которые будут похожи на массив (как известно из Python и т. Д.). В этом массиве может храниться более одного элемента (несколько жанров или нескольких городов и стран), но я не нашел ничего о массивах в neo4j. Тогда я понял, что все эти ограничения могут быть элегантно решена естественным путем Neo4j, единственное, что требуется немного модификация узлов и отношений:

(nir:Band { name: "Nirvana" }) 
(foo:Band { name: "Foo Fighters" }) 

(dgr:Person { name: "Dave Grohl", born: 1969 }) 

(grn:Genere { name: "Grunge" }) 
(rck:Genere { name: "Rock" }) 

(dgr)-[:IS_MEMBER_OF {from: 1987, to: 1994, instrument:"drums"} ]->(nir) 
(dgr)-[:IS_MEMBER_OF {from: 1994, to: 1998, instrument:"drums"} ]->(foo) 
(dgr)-[:IS_MEMBER_OF {from: 1998, to: 2014, instrument:"guitar"} ]->(foo) 

(stl:Town { name: "Seatle" }) 
(por:Town { name: "Portland" }) 

(usa:Country { name: "USA" }) 

(stl)->[:IS_IN]->(usa) 
(por)->[:IS_IN]->(usa) 

(nir)->[:IS_FROM]->(stl) 
(nir)->[:IS_FROM]->(por) 

(nir)->[:PLAYS]->(grn) 
(nir)->[:PLAYS]->(rck) 

(user1)-[:IS_FRIEND_OF]->(user6) 
(user1)-[:LIKES]->(nir) 

Наконец мои вопросы:

  1. Позволяет сказать, что я я доволен ограничениями, упомянутыми выше, и это отлично подходит для моих нужд (группа может происходить только из одного города и т. д.). Есть еще лучше иметь разные типы узлов (город, страна, жанр), как это было упоминается? Существуют ли какие-либо (рабочие) преимущества с использованием свойства в уже существующем узле по сравнению с полностью разным типом узла, будет , имеющим отношение к узлу типа, который представляет собой, например, Инструмент или что-то совершенно отличное от будущей точки зрения?
  2. В реляционной базе данных есть правило: если у вас есть отношения m: n , вам понадобится таблица соединений. Может ли это быть применено и к базам данных , но вместо таблицы соединения требуется создание нового узла (Город, Страна, Жанр)?

Редактировать в ответ на @Michael Hunger

«Вы должны спросить себя, какие запросы/прецеденты вы хотите решить с ним» Если instrument является членом IS_MEMBER_OF отношений или если instrument является членом из Person Я все еще могу (возможно, запрос Cypher будет выглядеть более неуклюжим, я не знаю), чтобы получить желаемые данные, например показать мне, что все барабанщики играют в группах, которые происходят из США.Конечно, я ограничена вышеупомянутыми ограничениями (Человек может играть только на одном инструменте и т. Д.). Мой вопрос в том, что если имеет смысл создать другую модель базы данных (вторая предлагаемая схема), если я знаю об этих ограничениях (первая предлагаемая схема), и я доволен ими. Есть ли какие-либо преимущества, которые имеют вторую предложенную схему по сравнению с первой? Тот, который я вижу прямо сейчас, состоит в том, что вторая схема хорошо масштабируется в отличие от первой, есть ли что-то еще, например, производительность?

«Для некоторых конкретных случаев использования может быть интересно моделировать членство в группе как узлы, тогда вы можете подключить их к узлу инструмента, дереву времени (year-> month-> membership) или поместить их в порядок (со следующими отношениями) ». Не могли бы вы привести несколько простых примеров CYPHER? Трудно себе представить.

«Графические базы данных предварительно материализуют отношения и хранят их с узлами, которые они соединяют» Означает ли это, что следующие два в основном одинаковы с точки зрения производительности? Потому что оба отношения соединяют узлы.

CREATE (dgr:Person {name:"Dave Grohl", instrument: "drums"})-[:IS_MEMBER_OF]->(nir:Band {name:'Nirvana'}) 
CREATE (dgr:Person {name:"Dave Grohl"})-[:IS_MEMBER_OF {instrument: "drums"} ]->(nir:Band {name:'Nirvana'}) 
+1

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

ответ

1

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

Для некоторых конкретных случаев использования может быть интересно моделировать членство в группе как узлы, тогда вы можете подключить их к узлу инструмента, дереву времени (year-> month-> membership) или поместить их в порядок (со следующими отношениями).

Относительно вашего вопроса о соединении таблиц.

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

Таким образом, вам также не нужны технические первичные и внешние ключи. Единственное, что имеет смысл, это индексировать свойства, которые вы использовали бы для поиска ваших объектов, например. : Person (name),: Band (имя), то же самое для жанров, стран и городов (если вы хотите их искать по имени).

Приятный инструмент, который может помочь вам приступить к работе, - это генератор примера граф.

У нас также есть несколько наборов данных и статей о музыкальном домене, если вам интересно: http://www.neo4j.org/misc/music (набор данных musicbrainz устарел и должен быть обновлен).

+0

Большое спасибо за ответ, я сожалею о более позднем ответе. Я почти забыл этот вопрос. –

Смежные вопросы