Triple-Stores and SPARQL
Triple-Stores,可以理解为三元组存储,即用三元组存储图。
SPO 三元组
其含义如下:
Subject | 对应图中的一个点 |
Object | 1. 一个原子数据,如 string 或者 number。 2. 另一个 Subject。 |
Predicate | 1. 如果 Object 是原子数据,则 <Predicate, Object> 对应点附带的 KV 对。 2. 如果 Object 是另一个 Object,则 Predicate 对应图中的边。 |
仍是上边例子,用 Turtle triples (一种 Triple-Stores 语法)表达为:
@prefix : <urn:example:>. _:lucy a :Person. _:lucy :name "Lucy". _:lucy :bornIn _:idaho. _:idaho a :Location. _:idaho :name "Idaho". _:idaho :type "state". _:idaho :within _:usa. _:usa a :Location _:usa :name "United States" _:usa :type "country". _:usa :within _:namerica. _:namerica a :Location. _:namerica :name "North America". _:namerica :type "continent".
一种更紧凑的写法:
@prefix : <urn:example:>. _:lucy a: Person; :name "Lucy"; :bornIn _:idaho _:idaho a: Location; :name "Idaho"; :type "state"; :within _:usa. _:usa a: Location; :name "United States"; :type "country"; :within _:namerica. _:namerica a :Location; :name "North America"; :type "continent".
语义网(The Semantic Web)
万维网之父Tim Berners Lee于1998年提出,知识图谱前身。其目的在于对网络中的资源进行结构化,从而让计算机能够理解网络中的数据。即不是以文本、二进制流等等,而是通过某种标准结构化互相关联的数据。
语义:提供一种统一的方式对所有资源进行描述和结构化(机器可读)。
网:将所有资源勾连起来。
下面是语义网技术栈(Semantic Web Stack):
语义网技术栈
其中 RDF (ResourceDescription Framework,资源描述框架)提供了一种结构化网络中数据的标准。使发布到网络中的任何资源(文字、图片、视频、网页),都能以统一的形式被计算机理解。即,不需要让资源使用方深度学习抽取资源的语义,而是靠资源提供方通过 RDF 主动提供其资源语义。
感觉有点理想主义,但互联网、开源社区都是靠这种理想主义、分享精神发展起来的!
虽然语义网没有发展起来,但是其中间数据交换格式 RDF 所定义的 SPO三元组(Subject-Predicate-Object) 却是一种很好用的数据模型,也就是上面提到的 Triple-Stores。
RDF 数据模型
上面提到的 Turtle 语言(SPO三元组)是一种简单易读的描述 RDF 数据的方式, RDF 也可以基于 XML 表示,但是要冗余难读的多(嵌套太深):
<rdf:RDF xmlns="urn:example:" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <Location rdf:nodeID="idaho"> <name>Idaho</name> <type>state</type> <within> <Location rdf:nodeID="usa"> <name>United States</name> <type>country</type> <within> <Location rdf:nodeID="namerica"> <name>North America</name> <type>continent</type> </Location> </within> </Location> </within> </Location> <Person rdf:nodeID="lucy"> <name>Lucy</name> <bornIn rdf:nodeID="idaho"/> </Person> </rdf:RDF>
为了标准化和去除二义性,一些看起来比较奇怪的点是:无论 subject,predicate 还是 object 都是由 URI 定义,如
lives_in 会表示为 <http://my-company.com/namespace#lives_in>
其前缀只是一个 namespace,让定义唯一化,并且在网络上可访问。当然,一个简化的方法是可以在文件头声明一个公共前缀。
SPARQL 查询语言
有了语义网,自然需要在语义网中进行遍历查询,于是有了 RDF 的查询语言:SPARQL Protocol and RDF Query Language, pronounced “sparkle.”
PREFIX : <urn:example:> SELECT ?personName WHERE { ?person :name ?personName. ?person :bornIn / :within* / :name "United States". ?person :livesIn / :within* / :name "Europe". }
他是 Cypher 的前驱,因此结构看起来很像:
(person) -[:BORN_IN]-> () -[:WITHIN*0..]-> (location) # Cypher ?person :bornIn / :within* ?location. # SPARQL
但 SPARQL 没有区分边和属性的关系,都用了 Predicates。
(usa {name:'United States'}) # Cypher ?usa :name "United States". # SPARQL
虽然语义网没有成功落地,但其技术栈影响了后来的知识图谱和图查询语言。
图模型和网络模型
图模型是网络模型旧瓶装新酒吗?
否,他们在很多重要的方面都不一样。
模型 | 图模型(Graph Model) | 网络模型(Network Model) |
连接方式 | 任意两个点之间都有可以有边 | 指定了嵌套约束 |
记录查找 | 1. 使用全局 ID 2. 使用属性索引。 3. 使用图遍历。 |
只能使用路径查询 |
有序性 | 点和边都是无序的 | 记录的孩子们是有序集合,在插入时需要考虑维持有序的开销 |
查询语言 | 即可命令式,也可以声明式 | 命令式的 |
查询语言前驱:Datalog
有点像 triple-store,但是变了下次序:(subject, predicate, object) → predicate(subject, object). 之前数据用 Datalog 表示为:
name(namerica, 'North America'). type(namerica, continent). name(usa, 'United States'). type(usa, country). within(usa, namerica). name(idaho, 'Idaho'). type(idaho, state). within(idaho, usa). name(lucy, 'Lucy'). born_in(lucy, idaho).
查询从美国迁移到欧洲的人可以表示为:
within_recursive(Location, Name) :- name(Location, Name). /* Rule 1 */ within_recursive(Location, Name) :- within(Location, Via), /* Rule 2 */ within_recursive(Via, Name). migrated(Name, BornIn, LivingIn) :- name(Person, Name), /* Rule 3 */ born_in(Person, BornLoc), within_recursive(BornLoc, BornIn), lives_in(Person, LivingLoc), within_recursive(LivingLoc, LivingIn). ?- migrated(Who, 'United States', 'Europe'). /* Who = 'Lucy'. */
- 代码中以大写字母开头的元素是变量,字符串、数字或以小写字母开头的元素是常量。下划线(_)被称为匿名变量
- 可以使用基本 Predicate 自定义 Predicate,类似于使用基本函数自定义函数。
- 逗号连接的多个谓词表达式为且的关系。
条件匹配集合扩充
基于集合的逻辑运算:
- 根据基本数据子集选出符合条件集合。
- 应用规则,扩充原集合。
- 如果可以递归,则递归穷尽所有可能性。
Prolog(Programming in Logic的缩写)是一种逻辑编程语言。它创建在逻辑学的理论基础之上。
参考
- 声明式(declarative) vs 命令式(imperative):https://lotabout.me/2020/Declarative-vs-Imperative-language/
- SimmerChan 知乎专栏,知识图谱,语义网,RDF:https://www.zhihu.com/column/knowledgegraph
- MySQL 为什么叫“关系”模型:https://zhuanlan.zhihu.com/p/64731206