DDIA-数据模型与查询语言

431 阅读2分钟

图状数据模型

图由两种对象组成:顶点(实体)和边(实体间关系)。图提供了单个数据存储区保存完全不同类型对象的一致性方式。比如顶点可以表示人、地点、事件等不同的实体。

属性图

用关系模式表示属性图:

CREATE TABLE vertices (
  	vertex_id 	integer primary key,	# 顶点唯一标识符
  	properties json # 顶点属性的集合(键-值对)
);
CREATE TABLE edges (
  	edge_id			integer primary key, # 唯一标识符
  	tail_vertex integer references vertices (vertex_id), # 边开始的节点(尾部节点)
  	head_vertex integer references vertices (vertex_id), # 边结束的节点(头部节点)
  	label				text,	# 描述两个顶点间关系类型的标签
  	properties	json	# 属性的集合(键-值对)
);
CREATE INDEX edges_tails ON edges (tail_vertex); # 顶点的出边集合
CREATE INDEX edges_head ON edges (head_vertex); # 顶点的入边集合

Cypher 查询语言

Cypher [ˈsaɪfər] 是一种用于属性图的声明式查询语言。

下面使用属性图来表示:来自爱达荷州(Idaho)的Lucy同来自法国波恩(Burgundy)的Alain结婚了,目前两人定居在英国伦敦。

使用 Cypher 语言可以把上图左半边 Lucy 的出生地址写入到图数据库:

CREATE
	(NAmerica:Location 	{name: 'North America', type: 'continent'}),
	(USA:Location 			{name: 'United States', type: 'country'}),
	(Idaho:Location			{name: 'Idaho', type: 'state'}),
	(Idaho) -[:WITHIN]-> (USA) -[:WITHIN]-> (NAmerica),	# (Idaho) -[:WITHIN]-> (USA) 创建一个WITHIN的边
	(Lucy)  -[:BORN_IN]-> (Idaho) # 创建一个 BORN_IN的边

使用Cypher查询从美国移民到欧洲的人员名单:

MATCH
	(person) -[:BORN_IN]-> 	() -[:WITHIN*0..]-> (us:Location {name: 'United States'}),
	(person) -[:LIVES_IN]-> () -[:WITHIN*0..]-> (eu:Location {name: 'Europe'})
RETURN person.name

Cypher 使用 【:WITHIN*0..】表达 类似正则表达式的(*)语义。在属性图的语义下代表沿着WITHIN边遍历零次或多次。

该查询的具体解读如下:找到满足下面两个条件的所有顶点 person,返回顶点的 name 属性。

  1. person 有一个 BORN_IN 边。从该顶点沿着一系列出边 WITHIN 直到达到类型是 Location 姓名是 United States 的顶点。
  2. 同一个 person 顶点也有一个 LIVES_IN 边。沿一系列 WITHIN 出边,最终到达类型是 Location,name 属性是 Europe 的顶点。