图形数据库、NOSQL和Neo4j
图形据图、数 NOSQL 和 Neo4j作者 Peter Neubauer 图者胡图 图布于 2010年9月8日 上午12图0分 社 区架 构,Java
主图NoSQL , 数据图图图, 数据图图
图介
在众数多不同的据模型里~图系据模型自数80年代就图于图治地位~而且有不少图图~如Oracle、MySQL 和MSSQL~图也被图图系据图管理系图;它称数RDBMS,。然而~最近着图系据图使用
案例
全员育人导师制案例信息技术应用案例心得信息技术教学案例综合实践活动案例我余额宝案例
的不增加~一些图图也暴露了出~图主要是随数断来
因图原因,两个数据建模中的一些缺陷和图图~以及在大据量和多服图器之上图行数
水平伸图的限制。图图图图些图图引起了全球图件社的重图,两个区
1.用图、系图和图感器图生的据量呈数指增图数~其增图速度因大部分据量集数
中在象Amazon、Google和其他云服图图图的分布式系图上而图一步加快。
2.数内网据部依图和图图度的增加~图一图图因互图、Web2.0、社交图~以及图大网
量不同系图的据源图放和图准化的图图而加图。数
在图图图些图图图~图系据图图生了更多的图图。图图致大量解图些图图某些特定方面的不数决
同技图的出图~图可以图有它与RDBMS相互配合或代替图 它- 亦被图称混合持久化
; Polyglot Persistence ,。据图替代品不是新图事物~图已图以数并它图象据图数
; OODBMS ,、图次据图;如数LDAP,等形式存在图图图了。但是~图去年图~很几
出图了大量新图目~图被图图它称NOSQL据图;数NOSQL-databases,本文旨在介图图形据图;数Graph Database,在NOSQL图里的地位~第二部分图运
是图Neo4j;一图基于Java的图形据图,的图介。数
NOSQL图境
NOSQL;Not Only SQL~不限于SQL,是一图范图非常泛的持久化解方案广决~它数图不遵循图系据图模型~也不使用SQL作图图图图言。
图图地图~NOSQL据图可以按照图的据模型分成数它数4图,
1.图-图存图图;Key-Value-stores,
2.BigTable图图;BigTable-implementations,
3.文图;档Document-stores,
4.图形据图;数Graph Database,
就Voldemort 或Tokyo Cabinet 图图图/图系图而言~最小的建模图元是图-图图。图BigTable的克隆品图~最小建模图元图是包含不同性的元图~至于象来个数属
CouchDB 和MongoDB 图图的文图~最小图元是文。图形据图图干脆把整据档档数个数
集建模成一大型稠密的图图图。个网构
在此~图我图深入图图NOSQL据图的有意思的方面,伸图性和图图度。数两个
1. 伸图性
CAP: ACID vs. BASE
图了保图据完整性~大多图典据图系图都是以事图图基图的。图全方位保图了据数数数数
管理中据的一致性。图些事图特性也被图数称ACID;A代表原子性、C表示一致性、I是隔性、离D图图持久性,。然而~ACID兼容系图的向外图展已图表图图一图图个。在分布式系图中~高可用性不同方面之图图生的突有完全得到解 冲没决- 亦称CAP 法图,
•强一致性;C,,所有客图端看到的据是同一数个即数版本~使是据集图
生了更新 - 如利用两图段提交图图;XA 事图,~和ACID~
•高可用性;A,,所有客图端图能找数个即到所图求据的至少一版本~使
集群中某些机器已图宕机~
•分容区忍性;P,,整系图保持自个即己的特征~使是被部署到不同服图
器上的图候~图图客图端来图是透明的。
CAP法图假定向外图展的3个两个不同方面中只有可以同图完全图图。图了能图理大型分布式系图~图我图深入了解所采用的不同CAP特征。很多NOSQL据图数首先已图放图了图于一致性;C,的要求~以期得到更好的可用性;A,和分容区忍性;P,。图图生了被图称BASE;基本;B,可用性;A,、图图;状S,、最图一致性;E,,的系图。图有图典意图上的事图~图它没并
且在据模型上引入了图数区束~以支持更好的分模式;如Dynamo 系图等,。图于CAP、ACID和BASE的更深入图图可以在图篇介图里到。找
2. 图图度
蛋白图同源图;网 Protein Homology Network ,~感图Alex Adai,图胞和分子生物学院 - 德州大学
数据和系图的互图性增加图生了一图无法用图图明了或图域无图;domain-independent,
方式图行伸图和自图分的稠密据集~区数甚至图Todd Hoff 也提到了图一图图。图于大型图图据集的可图化容可以图图数内 可图化图图度; Visual Complexity ,。图系模型
在把图系据模型图数扔数个故图堆之前~我图不图图忘图图系据图系图成功的一原因是遵照E.F. Codd的想法~图系据模型数通图图范化的手段原图上能图建模任何数构据图且有没信息冗余和图失。建模完成之后~就可以使用SQL以一图非常强大的方式插数数插况入、修改和图图据。甚至有些据图~图了入速度或图图不同使用情;如OLTP、OLAP、Web图用或图表,的多图图图;星形模式,~图模式图图了图化。图只是理图。然而在图中~践RDBM遇到了前面提到的CAP图图的限制~以及由高性能图图图图而图生的图图,图图大量表、深度嵌套的SQL图图。其他图图包括伸图性、图图随的模式演图~图形图的建模~构构数网半图化据~图图和图等。
图系模型也图很当称适图前图件图图的方法~如面向图象和图图图言~图被图 图象 - 图系阻抗失配。由此~象Java的Hibernate 图图的ORM图被图图了出~而且被图用到图图混合图来
境里。图它数没固然图化了把图象模型映射到图系据模型的任图~但是有图化图图的性能。尤其是半图化据构数很往往被建模成具有图多列的大型表~其中多行的图多列是空的;稀疏表,~图图致了拙劣的性能。甚至作图替代方法~把图些图建模成大构量的图图表~也有图图。因图RDBMS中的图图是一图非常图的集合昂操作。图形是图系图范化的一图替代技图
看看图域模型在据图上的方案~有主数构两个学流派 - RDBMS采用的图系方法和
图 - 即网构图图图~如图图用到的。网
尽构管图图在理图上甚至可以用RDBMS图范化~但由于图系据图的图图特数点~图于象文件图图图的图图图和象社交图图图的图图有图重的图图性构网构响网能影。图图图系上的每次操作都图致会RDBMS上的一次"图图"操作~以表的主图集合图的集合两个来操作图图 ~图图操作不图图慢并随数且无法着图些表中元图量的增加而伸图。
属性图形;Property Graph,的基本图图
在图的图域~有一并没广套被泛接受的图图~存在着很多不同图型的图模型。但是~有人致力于图建一图 属性图形模型; Property Graph Model ,~以期图一大多不数同的图图图。按照图模型~性图里属信息的建模使用3图构造图元,
•图点;图即点,
•图系;图, 即- 具有方向和图型;图图和图向,
•图点和图系上面的性属;特性,即
更特殊的是~图模型是一被图图和图向的性多重图;个个属multigraph,。被图图的图每条个它来条个从图都有一图图~被用作图那图的图型。有向图允图图有一固定的方向~末或源图点到首或目图图点。性图属个属属允图每图点和图有一图可图的性列表~其中的性是图图某个构两个条两名字的图~图化了图形图。多重图允图图点之图存在多图。图意味着个即两条图点可以由不同图图接多次~使图有相同的尾、图和图图。下图图示了一被图图的小型性图。个属
TinkerPop 有图的小型人图图
图图的巨大用途被得到了图可~不同图它跟很域的多图图都有图图。最常用的图图算法包括各图图型的最短路径图算、 图地图; Geodesic Path ,、集中度图量;如PageRank、特征向量集中度、图密度、图系度、HITS等,。然而~在多很况情下~图些算法的图用图限制于研没数究~因图图图中有任何可用于图品图境下的高性能图形据图图图。幸运况几个来的是~近些年情有所改图。有图目已图被图图出~而且目图直指24/7的图品图境,
• Neo4j - 图源的Java性图形模型属
• AllegroGraph~图源~RDF-QuadStore
• Sones - 图源~图注于.NET
• Virtuoso - 图源~图注于RDF
• HyergraphDB - 图源的Java超图模型
•Others like InfoGrid、Filament、FlockDB 等。
下图展示了在图图度和伸图性方面背景下的主要NOSQL分图的位置。图于“图模图展和图图度图展的比图”的更多容~图图图内 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事图写操作。
示例 - 黑客帝国
图
前面已图图图~社交图网数冰它来只是代表了图形据图图用的山一角~但用图图作图例子可以图人很容易理解。图了图述Neo4j的基本功能~下面图小型图自个来黑客帝国图部图影。图图是用Neo4j的Neoclipse 图生的~图件基于插Eclipse RCP,
图图图个个接到一已知的引用图点;id=0,~图是图了方便的一已从个找条知起点到路图入图图。图图个网个践它点不是必图的~但图图明非常有用。
Java的图图看上去大是图图子,概个
在“target/neo”目图图建一新的图形据图个数
EmbeddedGraphDatabase graphdb = new
EmbeddedGraphDatabase("target/neo");
图系图型可以图图图建,
RelationshipType KNOWS = DynamicRelationshipType.withName("KNOWS");或通图图型安全的Java Enum,
enum Relationships implements RelationshipType { KNOWS, INLOVE, HAS_CODED, MATRIX }
图在~图建2图个个点~图每图点加上“name”属两个个性。接着~把图点用一“KNOWS”图系图系起,来
Node neo = graphdb.createNode();
node.setProperty("name", "Neo");
Node morpheus = graphdb.createNode();
morpheus.setProperty("name", "Morpheus");
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("target/neo4j");
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("Neo", root, MATRIX);
Node morpheus = createAndConnectNode("Morpheus", neo, KNOWS);
Node cypher = createAndConnectNode("Cypher", morpheus, KNOWS);
Node trinity = createAndConnectNode("Trinity", morpheus, KNOWS);
Node agentSmith = createAndConnectNode("Agent Smith", cypher, KNOWS);
architect = createAndConnectNode("The Architect", agentSmith, 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("name", name);
node.createRelationshipTo(otherNode, relationshipType);
index.index(node, "name", name);
return node;
}
图是Neo的朋友,
Neo4j的API有一图面向 Java 集合的方法可图易地完成图图。图里~只消看看“Neo”图点的图系便足以出他的找朋友,
for (Relationship rel : neo.getRelationships(KNOWS)) {
Node friend = rel.getOtherNode(neo);
System.out.println(friend.getProperty("name"));
}
returns "Morpheus" as the only friend.
但是~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("name"));
}
我图在图图图图更深一图的图点之前首先从起点图图图于同一深度的所有图点;Order.BREADTH_FIRST,~在深度图1的一次遍图后停止
;StopEvaluator.DEPTH_ONE,~然后返回除了起点;"Neo",之外的所有图点;ReturnableEvaluator.ALL_BUT_START_NODE,。我图在方向两个只遍图图型图KNOWS的图系。图个遍图器再次返回Morpheus是Neo图有的直接朋友。朋友的朋友,
图了图图图是Neo朋友的朋友~KNOWS图网需要再图行深度图2的步图~由Neo图始~返回Trinity和Cypher。图图图程中~图可以通图图整我图的Traverser的StopEvaluator~限制遍图深度图2图图,来
StopEvaluator twoSteps = new StopEvaluator() {
@Override
public boolean isStopNode(TraversalPosition position) {
return position.depth() == 2;
}
};
图要定制ReturnableEvaluator~只返回在深度2到的图找点,ReturnableEvaluator nodesAtDepthTwo = new ReturnableEvaluator() {
@Override
public boolean isReturnableNode(TraversalPosition position) {
return position.depth() == 2;
}
};
图在“朋友的朋友”遍图器就成了,
Traverser friendsOfFriends = neo.traverse(Order.BREADTH_FIRST,
twoSteps, nodesAtDepthTwo, KNOWS, Direction.BOTH);for (Node friend : friendsOfFriends) {
System.out.println(friend.getProperty("name"));}
它的图果是Cypher和Trinity。
图在图恋,
另个个恋从构一有趣的图图是~图图上是否有人正在图~比方图架图;Architect,图始。图次~整图个构需要沿着由架图;假定他的图点ID是已知的~但要到图很才知道,图始的任何图系图始图图~返回图有向外LOVE图系的图点。一定制的个ReturnableEvaluator可以完成图件事,ReturnableEvaluator findLove = new ReturnableEvaluator() {@Override
public boolean isReturnableNode(TraversalPosition position) {
return position.currentNode().hasRelationship(LOVES, Direction.OUTGOING);
}
};
图了遍图所有图系~需要知道整图的所有图系图型,个
List