图数据库与三重存储——什么时候使用哪个?
Graph Databases vs Triple Stores - when to use which?
我知道 Whosebug 上也有类似的问题,但我觉得他们没有回答以下问题。
根据我的理解,图形数据库主要遵循以下模式存储数据:
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)
现在我会看到以下关于用例的区别:
- 图数据库:当你知道时,静态连接
- 三重存储:当您的节点连接松散并且经常寻找新连接时
我很困惑,人们似乎没有根据这些标准讨论使用哪一个。我发现的大多数文章都在谈论诸如速度或兼容性之类的争论。但这不是最相关的一点吗?
反过来说:
- 想象一下有一个清晰连接的、用户定义的图表。为什么你只想将它存储为三元组,丢失所有关于连接的信息?或者必须在三元组
subject
. 中实现一些自定义解决方案存储 ID
- 想象一下,您想要使用 SPARQL 查询未知关系的松散收集节点。图数据库确实支持这一点。但是为此他们必须建立另一个我假设的索引并且会更慢?
编辑:
我看到 "loosing info about connections" 是错误的表达方式。如果您按照接受的答案中所示进行操作并为 2 个节点 + 1 个关系插入多个三元组,那么您将保留所有信息,特别是连接了哪些确切节点的信息。
图数据库和三元组存储之间的主要区别在于它们如何对图建模。在三重存储(或四重存储)中,数据往往非常原子。我的意思是图中的 "nodes" 往往是原始数据类型,如字符串、整数、日期等。关系 link 原始数据在一起,因此三重存储中的 "unit of discourse"通常是三元组,而不是节点或关系。
相比之下,其他图形数据库通常被称为"property stores",因为节点是与域中的对象对应的数据容器。节点代表对象,并具有属性;它们充当图形建模者指定的丰富数据类型,而不仅仅是原始数据类型。在这些图形数据库中,节点和关系是 "unit of discourse".
假设我有一个人叫 "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 的数据库对象。这就是我所说的更多 atomic/primitive 商店(三重商店)和更丰富的 属性 图表之间的区别。
RDF 和三元组存储主要是为应对您 运行 对语义 Web 遇到的各种架构挑战而构建的。例如,XML 命名空间是内置的,其架构假设是您将混合和匹配使用许多不同的词汇表和命名空间。 (那是一个非常"semantic web"的假设)。因此,在 SPARQL 和 RDF 中,您通常会 至少 同时使用 xsd
、rdf
和 rdfs
名称空间,并且可能还会 owl
、skos
等。 SPARQL 和 RDF/RDFS 也有许多挂钩和功能,它们明确地使 ontology 推理更容易。您倾向于将 URI 识别为 "namespacing your identifiers" 的一种方式,但也因为有些人可能想取消对 URI 的引用...同样,这里的假设是多方之间的广泛数据共享安排。
相比之下,属性 存储针对不同的用例,例如在一个 model/namespace 中灵活地建模数据 ,对象和图形之间的映射以实现持久性企业应用、快速演化等。您倾向于使用自己的方案(或内部数据库 ID)来标识事物。自动递增的整数可能不是网络上任何随机消费者的最佳 ID 形式(并且它们当然不能像 URL 一样取消引用)但它们可能不是您对公司内部应用程序的第一个想法。
那么哪个更好呢?更原子化的三重存储格式,还是丰富的 属性 图?您是否需要在一个查询或数据模型中混合和匹配许多不同的词汇表?您需要创建 OWL ontology 还是进行推理?是否需要将内存中的一堆 java 对象序列化到数据库中?您需要快速遍历长路径吗?这些类型的问题将指导您的选择。
图就是图,它们都做图,所以我认为它们可以表示什么,或者你如何在 "graph terms" 中思考问题方面没有太大区别。差异归结为引擎盖下的架构,以及您认为需要什么样的用例。我不会告诉你一个比另一个好,但要明智地选择。
(回复对这个答案的评论:)
当定义了 owl:inverseOf 生产规则时,推理器在添加或更新商店时或从商店中选择时会推断出反向 属性 三元组。这是一个"materialized relation"
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 具有对象的数据类型和语言:您需要具体化指定数据类型 and/or 语言的属性(并且您将重新实现定义明确的语义)
每个neo4j图都可以用RDF表示吗?是的
RDF 是图的一种表示形式,其中有很多存储实现针对插入和查询性能等各种用例进行了优化。
将 neo4j 与特定的三元组(具有推理支持)进行比较可能是一个更有用的比较,因为所有 neo4j 图都可以表示为 RDF。
我知道 Whosebug 上也有类似的问题,但我觉得他们没有回答以下问题。
根据我的理解,图形数据库主要遵循以下模式存储数据:
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)
现在我会看到以下关于用例的区别:
- 图数据库:当你知道时,静态连接
- 三重存储:当您的节点连接松散并且经常寻找新连接时
我很困惑,人们似乎没有根据这些标准讨论使用哪一个。我发现的大多数文章都在谈论诸如速度或兼容性之类的争论。但这不是最相关的一点吗?
反过来说:
- 想象一下有一个清晰连接的、用户定义的图表。为什么你只想将它存储为三元组,丢失所有关于连接的信息?或者必须在三元组
subject
. 中实现一些自定义解决方案存储 ID
- 想象一下,您想要使用 SPARQL 查询未知关系的松散收集节点。图数据库确实支持这一点。但是为此他们必须建立另一个我假设的索引并且会更慢?
编辑: 我看到 "loosing info about connections" 是错误的表达方式。如果您按照接受的答案中所示进行操作并为 2 个节点 + 1 个关系插入多个三元组,那么您将保留所有信息,特别是连接了哪些确切节点的信息。
图数据库和三元组存储之间的主要区别在于它们如何对图建模。在三重存储(或四重存储)中,数据往往非常原子。我的意思是图中的 "nodes" 往往是原始数据类型,如字符串、整数、日期等。关系 link 原始数据在一起,因此三重存储中的 "unit of discourse"通常是三元组,而不是节点或关系。
相比之下,其他图形数据库通常被称为"property stores",因为节点是与域中的对象对应的数据容器。节点代表对象,并具有属性;它们充当图形建模者指定的丰富数据类型,而不仅仅是原始数据类型。在这些图形数据库中,节点和关系是 "unit of discourse".
假设我有一个人叫 "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 的数据库对象。这就是我所说的更多 atomic/primitive 商店(三重商店)和更丰富的 属性 图表之间的区别。
RDF 和三元组存储主要是为应对您 运行 对语义 Web 遇到的各种架构挑战而构建的。例如,XML 命名空间是内置的,其架构假设是您将混合和匹配使用许多不同的词汇表和命名空间。 (那是一个非常"semantic web"的假设)。因此,在 SPARQL 和 RDF 中,您通常会 至少 同时使用 xsd
、rdf
和 rdfs
名称空间,并且可能还会 owl
、skos
等。 SPARQL 和 RDF/RDFS 也有许多挂钩和功能,它们明确地使 ontology 推理更容易。您倾向于将 URI 识别为 "namespacing your identifiers" 的一种方式,但也因为有些人可能想取消对 URI 的引用...同样,这里的假设是多方之间的广泛数据共享安排。
属性 存储针对不同的用例,例如在一个 model/namespace 中灵活地建模数据 ,对象和图形之间的映射以实现持久性企业应用、快速演化等。您倾向于使用自己的方案(或内部数据库 ID)来标识事物。自动递增的整数可能不是网络上任何随机消费者的最佳 ID 形式(并且它们当然不能像 URL 一样取消引用)但它们可能不是您对公司内部应用程序的第一个想法。
那么哪个更好呢?更原子化的三重存储格式,还是丰富的 属性 图?您是否需要在一个查询或数据模型中混合和匹配许多不同的词汇表?您需要创建 OWL ontology 还是进行推理?是否需要将内存中的一堆 java 对象序列化到数据库中?您需要快速遍历长路径吗?这些类型的问题将指导您的选择。
图就是图,它们都做图,所以我认为它们可以表示什么,或者你如何在 "graph terms" 中思考问题方面没有太大区别。差异归结为引擎盖下的架构,以及您认为需要什么样的用例。我不会告诉你一个比另一个好,但要明智地选择。
(回复对这个答案的评论:
当定义了 owl:inverseOf 生产规则时,推理器在添加或更新商店时或从商店中选择时会推断出反向 属性 三元组。这是一个"materialized relation"
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 具有对象的数据类型和语言:您需要具体化指定数据类型 and/or 语言的属性(并且您将重新实现定义明确的语义)
每个neo4j图都可以用RDF表示吗?是的
RDF 是图的一种表示形式,其中有很多存储实现针对插入和查询性能等各种用例进行了优化。
将 neo4j 与特定的三元组(具有推理支持)进行比较可能是一个更有用的比较,因为所有 neo4j 图都可以表示为 RDF。