图数据库与三重存储 - 何时使用哪个?
Posted
技术标签:
【中文标题】图数据库与三重存储 - 何时使用哪个?【英文标题】:Graph Databases vs Triple Stores - when to use which? 【发布时间】:2015-07-21 20:37:24 【问题描述】:我知道 *** 上有类似的问题,但我觉得他们没有回答以下问题。
据我了解,图形数据库存储数据主要遵循以下模式:
Table/Collection 1: store nodes with UID
Table/Collection 2: store relations referencing nodes via UID
这允许存储任意类型的图形。现在据我了解,三重商店只存储三重:
Triple/Collection 1: store triples (2 nodes, 1 relation)
现在我会看到以下关于用例的区别:
图形数据库:当你知道静态连接时 三重存储:当您有松散连接的节点并且经常寻找新的连接时人们似乎没有根据这些标准讨论使用哪一个,这让我感到困惑。我发现的大多数文章都在谈论速度或兼容性等论点。但这不是最相关的一点吗?
反过来说:
想象一下,有一个清晰连接的用户定义图。为什么你只想将它存储为三元组,而丢失有关连接的所有信息?或者必须实现一些自定义解决方案,将 ID 存储在三元组subject
中。
想象一下,您想要使用 SPARQL 查询未知关系的松散收集节点。图形数据库确实支持这一点。但是为此他们必须建立另一个我认为的索引并且会更慢?
编辑: 我看到“丢失有关连接的信息”是错误的说法。如果您按照接受的答案中所示进行操作并为 2 个节点 + 1 个关系插入多个三元组,那么您将保留所有信息,特别是连接了哪些确切节点的信息。
【问题讨论】:
"三重存储只存储三重" 许多(大多数?)三重存储(即,对于 RDF)实际上是 quad 存储,因为它们有一个概念(来自 SPARQL 数据集) 的命名图。由于每个三元组都存在于图中,因此基本项实际上是 (graph,subject,predicate,object)。 "三元组/集合 1:存储三元组(2 个节点,1 个关系)" 不过,顺序很重要。它不是无向边,所以它实际上是(源、关系、目标),或者更常见的是(主语、谓词(或属性)、宾语)。跨度> “你到底为什么只想将它存储为三元组,而丢失 [原文如此] 有关连接的所有信息?”我不确定你在这里的意思。该属性由 URI/IRI 标识,它与 UID 一样通用,只是它更容易记住,可以引用(以便您可以获得有关它的更多信息等),并且主体和客体通常是 URI 或数据字面量。哪些连接信息丢失了? OP 您的标准“静态连接与松散连接的节点”在我看来并不是解决问题的好方法。我认为这两种技术都支持。就像@JoshuaTaylor 所说,我认为 SPARQL/RDF 不会丢失任何关于连接的内容,这只是您选择建模/捕获的问题。 我看到“丢失有关连接的信息”是错误的说法。如果您按照接受的答案所示进行操作并为 2 个节点 + 1 个关系插入几个三元组,那么您将保留所有信息,特别是连接了哪些确切节点的信息。感谢所有 cmets! 【参考方案1】:图数据库和三元存储之间的主要区别在于它们如何对图进行建模。在三重存储(或四重存储)中,数据往往非常原子。我的意思是,图中的“节点”往往是原始数据类型,如字符串、整数、日期等。关系将原始数据连接在一起,因此三元组存储中的“话语单元”是三元组,而不是通常是一个节点或一个关系。
相比之下,其他图形数据库通常被称为“属性存储”,因为节点是与域中的对象相对应的数据容器。节点代表对象,具有属性;它们充当图形建模者指定的丰富数据类型,而不仅仅是原始数据类型。在这些图数据库中,节点和关系是“话语单元”。
假设我有一个叫“Bob”的人,他认识“Susan”。在 RDF 中,它会是这样的:
<http://example.org/person/1> :hasName "Bob".
<http://example.org/person/1> foaf:knows <http://example.org/person/2>.
<http://example.org/person/2> :hasName "Susan".
在像 neo4j 这样的图形数据库中,应该是这样的:
(a:Person name: "Bob")-[:KNOWS]->(b:Person name: "Susan")
请注意,在 RDF 中,它是 3 种关系,但其中只有一种关系实际上表达了两个实体之间的语义。其他两个关系只是跟踪单个更高级别实体(人)的属性。在 neo4j 中,两个节点之间是 1 关系,每个节点都有一个属性。在 RDF 中,您倾向于通过 URI 来识别事物,在 neo4j 中,它是一个自动获取数据库 ID 的数据库对象。这就是我所说的更原子/原始存储(三重存储)和更丰富的属性图之间的区别。
RDF 和三重存储主要是针对您在使用语义网络时遇到的各种架构挑战而构建的。例如,XML 命名空间是内置的,其架构假设是您将混合和匹配许多不同词汇表和命名空间的使用。 (那是一个非常“语义网”的假设)。因此,在 SPARQL 和 RDF 中,您通常会看到至少同时使用 xsd
、rdf
和 rdfs
命名空间,并且可能还会看到 owl
、skos
和许多其他。 SPARQL 和 RDF/RDFS 也有许多钩子和特性,它们明确地使诸如本体推理之类的事情变得更容易。您会倾向于使用 URI 来识别事物,作为“为标识符命名空间”的一种方式,但也因为有些人可能希望取消引用 URI……这里再次假设是多方之间的广泛数据共享安排。
相比之下,属性存储主要针对不同的用例,例如在一个模型/命名空间内灵活建模数据、用于企业应用程序持久性的对象和图形之间的映射、快速发展等。您将倾向于使用自己的方案(或内部数据库 ID)来识别事物。对于网络上的任何随机消费者来说,自动递增整数可能不是最好的 ID 形式(而且它们当然不能像 URL 那样被取消引用),但它们可能不是您对公司内部应用程序的第一个想法。
那么哪个更好?更原子的三元存储格式,还是丰富的属性图?您是否需要在一个查询或数据模型中混合和匹配许多不同的词汇表?您是否需要创建 OWL 本体或进行推理?是否需要将内存中的一堆 java 对象序列化到数据库中?您需要快速遍历长路径吗?这些类型的问题将指导您的选择。
图表就是图表,它们都做图表,所以我认为它们可以表示什么,或者你如何用“图表术语”来思考问题,并没有太大的区别。差异归结为引擎盖下的架构,以及您认为您需要什么样的用例。我不会告诉你一个比另一个更好,但要明智地选择。
【讨论】:
谢谢,我认为这总结得很好!我将对最初的问题进行编辑以总结我的结论。 你解释了很多关于语义网的内容,这很棒。然而,RDF 和 neo4j(也可能是其他非 RDF 图)之间存在根本区别,因为在 RDF 中有有向图。另一方面,neo4j 让您设计有向图和无向图。 neo4j 还内置了权重(也是复杂权重)的概念。不幸的是,这需要在 RDF 中使用笨拙的解决方法。 @TomaszPluskiewicz neo4j 没有以任何方式构建权重;尽管您可以选择对它们进行建模。与 RDF 相同的情况。 Neo4j 也有专门的有向边(没有无向边),尽管您可以选择遍历它们,就好像它们是无向的一样。与 RDF 的情况相同。 @FrobberOfBits 那么Direction enum 呢?使用 RDF,您需要显式地创建两个三元组。这与在您编写时当然可以进行的双向遍历不同。 @FrobberOfBits 关于权重,我说错了。我的意思是neo4j 中的relationship properties。 RDF 没有这种内置的概念。当然,您可以使用空白节点或任何类型的具体化对其进行建模,但它并不完全等效【参考方案2】:(回复本回答的cmets:https://***.com/a/30167732)
当定义 owl:inverseOf 产生式规则时,推理器在添加或更新存储时或从存储中选择时推断出逆属性三元组。这是一个“物化关系”
Schema.org - 一个 RDFS 词汇表 - 将 https://schema.org/isPartOf 定义为 hasPart 的逆属性,例如。如果两者都指定,则无需运行另一个图形模式查询来遍历另一个方向的有向关系。 (:book1 schema:hasPart ?o), (?o schema:isPartOf :book1), (?s schema:hasPart :chapter2)
当然可以使用 RDFS 和 OWL 来描述 neo4j 属性图中和内部的模式;但是没有理由例如推断逆属性或进行模式验证。
有没有 Neo4j 无法存储的 RDF 图? RDF 具有对象的数据类型和语言:您需要具体化指定数据类型和/或语言的属性(并且您将重新实现明确定义的语义)
每个 neo4j 图都可以用 RDF 表示吗?是的。
RDF 是图的一种表示形式,其中有很多存储实现都针对各种用例进行了优化,例如插入和查询性能。
考虑到所有 neo4j 图都可以表示为 RDF,将 neo4j 与特定的三元组(有推理支持)进行比较可能是更有用的比较。
【讨论】:
以上是关于图数据库与三重存储 - 何时使用哪个?的主要内容,如果未能解决你的问题,请参考以下文章
组件绑定与 findComponent() - 何时使用哪个?