我正在尝试将当前的关系数据库转换为RDF / OWL三重存储。我遇到的一件事是当我有一个具有多个值的复合键/复合键的桥/联接表时。例如,我有以下内容:
Equipment (EquipmentId)
EquipmentPoints (EquipmentId, PointId, CommodityId)
Point (PointId)
对于说Equipment :hasPoint ...
,我不确定如何对数据建模?特定点可能是不同的商品,具体取决于所使用的设备类型。
感谢任何帮助。
答案 0 :(得分:1)
您需要将语义Web视为数据的Web或图形,而不是通过外键相互链接的一组表。
数据集中的实体可以彼此链接,就像一个网站可以链接到另一个网站一样。从这个意义上讲,没有主键或专门的复合键之类的东西。只有资源相互链接。
在这种情况下,我可能会像以下示例中那样对其进行建模:
@base <http://example.com/resource/> .
<Equipment1> <hasId> "1" .
<Equipment1> <name> "Equipment 1" .
<Point1> <hasId> "1" .
<Point1> <description> "This is Point 1" .
<Equipment1> <hasEquipmentPoint> <EquipmentPoint1> .
<Point1> <hasEquipmentPoint> <EquipmentPoint1> .
<EquipmentPoint1> <hasCommodity> <Commodity1> .
或者,您可以尝试对其建模,使其更接近于所显示的表格,并改为将equipmentPoint链接到该点和设备:
<EquipmentPoint1> <hasEquipment> <Equipment1> .
<EquipmentPoint1> <hasPoint> <Point1> .
<EquipmentPoint1> <hasCommodity> <Commodity1> .
显然是修改名称,等等。 如您所见,没有键的概念,只是知识图中的一堆边,它描述了两个资源之间的链接。如上所述,带有复合键的表可能只是一个单独的资源。没有主键,但应该仍然可以进行搜索。
答案 1 :(得分:1)
首先,也许您可以重塑事物,摆脱:EquipmentPoint
。它们可能仅仅是关系建模的产物。 RDF属性可以具有多个值。有关更多详细信息,请参见here。
为清楚起见,我将稍微简化您的数据模型:
Equipment (EquipmentId)
EquipmentPoints (EquipmentId, PointId)
Point (PointId)
RDF是无模式的,RDF中没有约束。
您可以像another answer所示对事物进行建模:
@prefix : <https://stackoverflow.com/q/51974155/7879193#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
:equipment1 rdf:type :Equipment .
:equipment2 rdf:type :Equipment .
:point1 rdf:type :Point .
:point2 rdf:type :Point .
:equipmentPoint1 rdf:type :EquipmentPoint .
:equipmentPoint2 rdf:type :EquipmentPoint .
:equipmentPoint1 :hasEquipment :equipment1 ;
:hasPoint :point1 .
:equipmentPoint2 :hasEquipment :equipment1 ;
:hasPoint :point1 . # "constraint violation"
为了定义约束,可以使用SHACL之类的语言。不幸的是,SHACL中没有core constraint components用于复合键,应该使用SPARQL-based constraints:
:EquipmentPointShape a sh:NodeShape ;
sh:targetClass :EquipmentPoint ;
sh:sparql [
sh:message "Violation!" ;
sh:severity sh:Violation ;
sh:select """
SELECT ?this {
?point1 ^:hasPoint ?this, ?that .
?equipment ^:hasEquipment ?this, ?that .
FILTER (?this != ?that)
}
"""
] .
OWL设计用于推理,而不是用于约束检查。有关更多详细信息,请参见this answer。但是,您可以使用OWL 2 keys。
首先,添加一些本体“样板”:
[] rdf:type owl:Ontology .
:Equipment rdf:type owl:Class .
:Point rdf:type owl:Class .
:EquipmentPoint rdf:type owl:Class .
:hasPoint rdf:type owl:ObjectProperty .
:hasEquipment rdf:type owl:ObjectProperty .
:equipment1 rdf:type owl:NamedIndividual .
:equipment2 rdf:type owl:NamedIndividual .
:point1 rdf:type owl:NamedIndividual .
:point2 rdf:type owl:NamedIndividual .
:equipmentPoint1 rdf:type owl:NamedIndividual .
:equipmentPoint2 rdf:type owl:NamedIndividual .
现在您有了正确的Turtle序列化本体。然后添加:
:EquipmentPoint owl:hasKey (:hasEquipment
:hasPoint
) .
[ rdf:type owl:AllDifferent ;
owl:distinctMembers (:equipmentPoint1
:equipmentPoint2
)
] .
推理机将推断您的本体不一致。
请注意,OWL中没有唯一名称假设,也没有开放世界假设。
删除后
[ rdf:type owl:AllDifferent ;
owl:distinctMembers (:equipmentPoint1
:equipmentPoint2
)
] .
推理机会推断出
:equipmentPoint1 owl:sameAs :equipmentPoint2 .