注:本文以Hbase作为backend,并以下图为例
0、数据模型
Titan在Hbase中的存储结构
Table “名称:titan” | |||||||
| Column Family 1:e | CF2:? | |||||
Column: ’knows’的ID+IN+点1的ID+边8的ID | Column: ’created’的ID+OUT+点3的ID+边11的ID | Column: ’created’的ID+OUT+点5的ID+边10的ID | Column : ’name’的ID | Column : ’age’的ID |
|
| |
RowKey |
| ||||||
v1的ID | Weight=1.0 | Weight=0.4(字符串?) | Weight=1.0 | Name=”josh” | Age=32 |
|
|
上面的RowKey和ColumnKey都是合成的,实际存成HBase的字符数组中,所以直接查看只能看到二进制串,必须知道相应格式才能解析出来。例如边的ColumnKey中有个表示方向的标记IN或OUT,代码中是这样的:
1、创建一个图
<pre name="code" class="java">// Gremlin
conf = new BaseConfiguration();
conf.setProperty("storage.backend","hbase");
conf.setProperty("storage.hostname","77.77.77.77,77.77.77.78");
conf.setProperty("storage.tablename","graph1");
g = TitanFactory.open(conf);
setProperty("storage.tablename","graph1");
2、插入节点
g.addVertex([name:"marko", age:29]);
那么Titan是如何执行这条语句的呢?即如何把点v1放入到本文开头描述的hbase的数据模型中呢?
g.addEdge(g.v(1),g.v(4),"created",[weight:23]);
首先从图中读取ID为1和ID为4的两个结点,接下来就是对Rowkey为1和4的两个行进行写入操作。在HBase的大表中专门有一行保存了边和点的属性名和id的对应关系。如果图g中已经有了Label为“created”的边,就在该行中找到该Label的ID。否则新建一个新的ID和Label的对应关系表示“created”的ID,并保存在该行中。
在1所在的行中建立一个新的Column,Column名字是一个混合的二进制字段,其中包含了“created”的ID,边的方向(out),vertex-centric indices排序用的sort key(本例为空),相邻的邻接点的ID差值(4-1的前一个邻接点的ID)和这条边自身的独有ID。这个Column的Value则是混合了Label的signature(本例为空)和所有Property(weight=23)的另一个二进制字段。
在4所在的行中建立了另一个相对应的Column,保存了4的入边。3、存储一个图
4、根据属性查询节点
g.V.has(“age”, GREATER_THAN, 10).has(“name”, “marko”)
当用户调用hasNext时,titan根据对应的索引找到其rowKey位置,在用户调用next时输出