关于“规模扩展和复杂度扩展的比较”的更多内容,请阅读Emil Eifrem的博文。
Neo4j - 基于Java的图形数据库
Neo4j是一个用Java实现、完全兼容ACID的图形数据库。数据以一种针对图形网络进行过优化的格式保存在磁盘上。Neo4j的内核是一种极快的图形引擎,具有数据库产品期望的所有特性,如恢复、两阶段提交、符合XA等。自2003年起,Neo4j就已经被作为24/7的产品使用。该项目刚刚发布了1.0版 - 关于伸缩性和社区测试的一个主要里程碑。通过联机备份实现的高可用性和主从复制目前处于测试阶段,预计在下一版本中发布。Neo4j既可作为无需任何管理开销的内嵌数据库使用;也可以作为单独的服务器使用,在这种使用场景下,它提供了广泛使用的REST接口,能够方便地集成到基于PHP、.NET和JavaScript的环境里。但本文的重点主要在于讨论Neo4j的直接使用。
开发者可以通过Java-API直接与图形模型交互,这个API暴露了非常灵活的数据结构。至于象JRuby/Ruby、Scala、Python、Clojure等其他语言,社区也贡献了优秀的绑定库。Neo4j的典型数据特征:
数据结构不是必须的,甚至可以完全没有,这可以简化模式变更和延迟数据迁移。
? 可以方便建模常见的复杂领域数据集,如CMS里的访问控制可被建模成细粒度的访问控制表,类对象数据库的用例、TripleStores以及其他例子。 ? 典型使用的领域如语义网和RDF、LinkedData、GIS、基因分析、社交网络数据建模、深度推荐算法以及其他领域。
?
甚至“传统”RDBMS应用往往也会包含一些具有挑战性、非常适合用图来处理的数据集,如文件夹结构、产品配置、产品组装和分类、媒体元数据、金融领域的语义交易和欺诈检测等。
围绕内核,Neo4j提供了一组可选的组件。其中有支持通过元模型构造图形结构、SAIL - 一种SparQL兼容的RDF TripleStore实现或一组公共图形算法的实现。 要是你想将Neo4j作为单独的服务器运行,还可以找到REST包装器。这非常适合使用LAMP软件搭建的架构。通过memcached、e-tag和基于Apache的缓存和Web层,REST甚至简化了大规模读负荷的伸缩。
高性能?
要给出确切的性能基准数据很难,因为它们跟底层的硬件、使用的数据集和其他因素关联很大。自适应规模的Neo4j无需任何额外的工作便可以处理包含数十亿节点、关系和属性的图。它的读性能可以很轻松地实现每毫秒(大约每秒1-2百万遍历步骤)遍历2000关系,这完全是事务性的,每个线程都有热缓存。使用最短路径计算,Neo4j在处理包含数千个节点的小型图时,甚至比MySQL快1000倍,随着图规模的增加,差距也越来越大。
这其中的原因在于,在Neo4j里,图遍历执行的速度是常数,跟图的规模大小无关。不象在RDBMS里常见的联结操作那样,这里不涉及降低性能的集合操作。Neo4j以一种延迟风格遍历图 - 节点和关系只有在结果迭代器需要访问它们的时候才会被遍历并返回,对于大规模深度遍历而言,这极大地提高了性能。 写速度跟文件系统的查找时间和硬件有很大关系。Ext3文件系统和SSD磁盘是不错的组合,这会导致每秒大约100,000写事务操作。
1.示例 - 黑客帝国
图
前面已经说过,社交网络只是代表了图形数据库应用的冰山一角,但用它们来作为例子可以让人很容易理解。为了阐述Neo4j的基本功能,下面这个小型图来自黑客帝国这部电影。该图是用Neo4j的Neoclipse产生的,该插件基于Eclipse RCP:
这个图链接到一个已知的引用节点(id=0),这是为了方便的从一个已知起点找到条路进入这个网络。这个节点不是必须的,但实践证明它非常有用。 Java的实现看上去大概是这个样子:
在“target/neo”目录创建一个新的图形数据库 EmbeddedGraphDatabase graphdb = new EmbeddedGraphDatabase(\关系类型可以动态创建:
RelationshipType KNOWS = DynamicRelationshipType.withName(\或通过类型安全的Java Enum:
enum Relationships implements RelationshipType { KNOWS, INLOVE, HAS_CODED, MATRIX }
现在,创建2个节点,给每个节点加上“name”属性。接着,把两个节点用一个“KNOWS”关系联系起来:
Node neo = graphdb.createNode(); node.setProperty(\
Node morpheus = graphdb.createNode(); morpheus.setProperty(\neo.createRelationshipTo(morpheus, KNOWS);
任何修改图或需要数据隔离级别的操作要包在事务中,这样可以利用内置的回滚和恢复功能:
Transaction tx = graphdb.beginTx(); try { Node neo = graphdb.createNode(); ... tx.success(); } catch (Exception e) { tx.failure(); } finally { tx.finish(); }
创建“黑客帝国”图的完整代码:
graphdb = new EmbeddedGraphDatabase(\index = new LuceneIndexService(graphdb); Transaction tx = graphdb.beginTx(); try { Node root = graphdb.getReferenceNode(); // we connect Neo with the root node, to gain an entry point to the graph // not neccessary but practical. neo = createAndConnectNode(\ Node morpheus = createAndConnectNode(\ Node cypher = createAndConnectNode(\ Node trinity = createAndConnectNode(\morpheus, KNOWS); Node agentSmith = createAndConnectNode(\KNOWS); architect = createAndConnectNode(\HAS_CODED); // Trinity loves Neo. But he doesn't know. trinity.createRelationshipTo(neo, LOVES); tx.success(); } catch (Exception e) { tx.failure(); } finally { tx.finish(); }
以及创建节点和关系的成员函数
private Node createAndConnectNode(String name, Node otherNode, RelationshipType relationshipType) { Node node = graphdb.createNode(); node.setProperty(\
node.createRelationshipTo(otherNode, relationshipType);
index.index(node, \ return node; }
2.谁是Neo的朋友?
Neo4j的API有一组面向Java集合的方法可轻易地完成查询。这里,只消看看“Neo”节点的关系便足以找出他的朋友:
for (Relationship rel : neo.getRelationships(KNOWS)) { Node friend = rel.getOtherNode(neo);
System.out.println(friend.getProperty(\}
returns \
但是,Neo4j的真正威力源自Traverser-API的使用,它可以完成非常复杂的遍历描述和过滤器。它由Traverser和ReturnableEvaluator组成,前者计算StopEvaluator来获知何时停止,后者则用于在结果中包含哪些节点。此外,你还可以指定要遍历关系的类型和方向。Traverser实现了Java的Iterator接口,负责延迟加载和遍历整个图,在节点被首次要求访问(如for{...}循环)时进行。它还内置了一些常用的Evaluator和缺省值:
Traverser friends = neo.traverse(Order.BREADTH_FIRST, StopEvaluator.DEPTH_ONE,
ReturnableEvaluator.ALL_BUT_START_NODE, KNOWS, Direction.BOTH); for (Node friend : friends) {
System.out.println(friend.getProperty(\}
我们在继续访问更深一级的节点之前首先从起点访问处于同一深度的所有节点(Order.BREADTH_FIRST),在深度为1的一次遍历后停止
(StopEvaluator.DEPTH_ONE),然后返回除了起点(\)之外的所有节点(ReturnableEvaluator.ALL_BUT_START_NODE)。我们在两个方向只遍历类型为KNOWS的关系。这个遍历器再次返回Morpheus是Neo仅有的直接朋友。
3.朋友的朋友?
为了调查谁是Neo朋友的朋友,KNOWS网络需要再进行深度为2的步骤,由Neo开始,返回Trinity和Cypher。实际编程中,这可以通过调整我们的Traverser的StopEvaluator,限制遍历深度为2来实现: StopEvaluator twoSteps = new StopEvaluator() { @Override
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库社交网络下的数据库应用Neo4j(2)在线全文阅读。
相关推荐: