Monday 29 March 2010

Neo4J - java graph DB

Недавно я рассказывал про граф ориентированные базы данных. А сегодня хочу поделиться с Вами историей использования одной из них. Встречайте Neo4J.
Итак немного о самой системе: Neo4J предлагает Вам полноценную базу данных с транзакциями, индексами (Lucene), несколькими режимами работы и низким порогом вхождения, благодаря очень простой структуре. Все коды открыты и доступны, а приложение поставляется под двойной лицензией AGPL для некоммерческого использования и тарифная сетка для коммерческого. Для начала использования данной базы Вам достаточно знать джаву и понимать чего Вы хотите от сетевой структуры данных (графа).

Мне, при моём знакомстве, была интересна производительность при больших объемах данных и удобство работы с самой БД. Начнём с удобства и создадим базу данных с большим кол-вом вершин и ребёр. Для этого используем специальный класс доступа к БД, который оптимизирован под вставку:

batchGraphDb = new BatchInserterImpl( dbpath, stringProps );
batchIndexService = new LuceneIndexBatchInserterImpl( batchGraphDb );

, где dbPath - путь к файлам будущей базы данных, а stringProps - настройки.
Cоздадим несколько вершин следующим образом:

Map<String, Object> properties = new HashMap<String, Object>();

properties.put("a_key", 5);
properties.put("b_key", "some string");

long createdNode = batchGraphDb.createNode(properties);
batchIndexService.index(createdNode, "a_key", properties.get("a_key"));

Далее в идеале стоит вызвать метод batchIndexService.optimize(); который приведёт индексы в порядок и продолжим создавать рёбра:

Map<String, Object> edgeProperties = new HashMap<String, Object>();
edgeProperties.put("length", 345);
edgeProperties.put("version", "7.5");

long startNodeId = batchIndexService.getSingleNode("a_key", 5);
long endNodeId = batchIndexService.getSingleNode("a_key", 7);

batchGraphDb.createRelationship(
startNodeId,
endNodeId,
DynamicRelationshipType.withName("trust"),
edgeProperties);

Не хитрые манипуляции создают ребро из одной вершины в другую с типом "trust" и собственными свойствами. Ну и на последок закрытие соединения с БД:

if ( null != batchIndexService ) batchIndexService.shutdown();
if ( null != batchGraphDb ) batchGraphDb.shutdown();

Данные готовы, а нам не терпиться проверить её производительность. Показатели качества будут озвучены в следующем посте, а пока можно ознакомиться с другой статьей на эту тему: MySQL vs. Neo4j on a Large-Scale Graph Traversal

archive

Wednesday 17 March 2010

Graph DB

Большинство из нас знают, что в последнее время наряду с привычными реляционными базами данных набирают обороты так называемые Document-oriented, key-value и иерархические базы. А я в последнее время заинтересовался другой разновидностью хранилищ - граф ориентированными базами данных.
Что такое граф, я думаю все знают, а вот зачем для них понадобились свои собственные базы данных? Дело всё в том, что для структуры данных типа граф, набор действий зачастую несколько отличается от привычных нам вставок, обновлений и выборок по заданным условиям. Чего только стоят поиск в ширину и глубину. В принципе на небольших объемах данных традиционные способы представления себя оправдывают, но если предположить, что ваш граф начинает расти и в нём становится несколько миллионов вершин и десятки миллионов связей - реляционные базы данных загибаются под попытками провернуть нужное кол-во join-ов дабы удовлетворить многим условиям выборки при прохождении графа в случае поиска.
Что представляет собой граф ориентированная БД - это хранилище, которое использует некоторые априорные знания о графах, для формирования своей внутренней структуры. В таких базах поиск по критерию зачастую происходит не самым эффективных способом, а вот вычитка связей вершины, и вершин связей сильно оптимизирована. Таким образом обход графа (traversing) становиться операцией, которая в несколько раз быстрее аналогичной родственной реализации в реляционных БД.

Для ознакомления можно взглянуть на:

archive