KiWi Triplestore
KiWi is a triplestore developed as part of the Apache Marmotta project, an Open Platform for Linked Data.
KiWi stores RDF as relational tables in a PostgreSQL database (can also use H2 or MySQL databases as backend). However, it supports the SPARQL query language, semantic reasoning, quads/named graphs, standard RDF serializations (e.g. Turtle), and transactions.
Relational structure
As stated above, in KiWi the RDF graph is represented via relational tables. For representing nodes in the graph (i.e. resources), it uses the following table:
nodes(id bigint PRIMARY KEY,
-- uri, bnode, string, int, double, timestamp, boolean
ntype nodetype, -- lexical value (e.g. "1" for 1)
svalue text, double precision,
dvalue
ivalue bigint,timestamp,
tvalue int,
tzoffset boolean,
bvalue REFERENCES nodes(id), -- IRI denoting its type (xsd:int)
ltype bigint varchar(5), -- language tag for strings
lang timestamp
createdat )
All nodes are assigned a unique ID. If the node is a URI/IRI or a
blank node, ntype
equals uri
or
bnode
, respectively. If the node is a literal,
ntype
is either string
, int
,
double
, timestamp
or boolean
,
depending on the literals type. E.g. if it is an integer,
ntype
is int
. Note that if a literal is non of
these types, it will have ntype
equal to
string
. The more concrete literal type (as added to a
literal value in RDF, such as xsd:int
in
"1"^^xsd:int
) is represented by the column
ltype
, which references a node with the corresponding types
URI.
The column svalue
contains the lexical/string
representation of the node. The following columns, dvalue
,
ivalue
, tvalue
, and bvalue
contain the value cast to the columns type, if it preserved the value
and NULL
otherwise. E.g. an integer 1
would
have svalue
equal to '1'
, ivalue
equal to 1
, a dvalue
equal to
1.0
, and NULL
for all the other coumns. A
double value 1.2
would have svalue
equal to
'1.2'
, dvalue
equal to 1.2
, and
the NULL
for the other columns (also ivalue
equal to NULL
, as 1
is not equal to the
original value).
A timestamp value can store the timezone as an offset in the column
tzoffset
.
If the literal is a string with a language tag, this tag is put into
the lang
column.
Finally, the column createdat
simply contains the
timestamp for when the node was inserted into the database.
Triples/quads are represented in KiWi with the following table:
triples(id bigint PRIMARY KEY,
REFERENCES nodes(id),
subject bigint REFERENCES nodes(id),
predicate bigint object bigint REFERENCES nodes(id),
context bigint REFERENCES nodes(id),
REFERENCES nodes(id),
creator bigint boolean,
inferred boolean,
deleted timestamp,
createdat timestamp
deletedat )
Each triple/quad is assigned a unique ID. The columns
subject
, predicate
, and object
contains the ID of the nodes that is the subject, predicate and object,
respectively. If the triple is part of a named graph (called a context
in KiWi), the column context
contains the ID of the node
with the named graph’s IRI.
The column creator
contains a possible ID for a node
denoting the creator of the triple/quad.
As stated above, KiWi supports reasoning, and the column
inferred
contains a boolean to state whether the
triple/quad is inferred or not. The following column,
deleted
states whether the triple/quad should be considered
deleted or not. If it is deleted, the column deletedat
tracks the timestamp of the deletion. Similarly as nodes, the
triple-table also contains a createdat
column containing
the timestamp the triple/quad was inseted.
If the triplestore is initialized via Toko, there will also be a view
named triples_str
that contains all triples in the
triplestore with the svalue
(lexical value) of the
elements. This is convenient if one simply wants to see (as in read) all
triples in the triplestore. The view contains the following columns:
triples_str (id bigint,
subject text,
predicate text,object text,
context text
)
Example
If we load the following RDF graph:
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix ex: <http://example.org/> .
ex:earth rdf:type ex:Planet ;
rdfs:label "The Earth"@en ;
ex:radius "6371.1"^^xsd:decimal ;
ex:orbits [ rdfs:label "The sun" ] .
into a KiWi triplestore, we would get the following
nodes
-table:
id | ntype | svalue | dvalue | ivalue | tvalue | tzoffset | bvalue | ltype | lang | createdat
----+--------+-------------------------------------------------+--------+--------+--------+----------+--------+-------+------+-------------------------
1 | uri | http://www.w3.org/1999/02/22-rdf-syntax-ns# | | | | | | | | 2021-02-08 19:04:40.494
2 | uri | http://www.w3.org/2000/01/rdf-schema# | | | | | | | | 2021-02-08 19:04:40.503
3 | uri | http://www.w3.org/2001/XMLSchema# | | | | | | | | 2021-02-08 19:04:40.507
5 | uri | http://example.org/ | | | | | | | | 2021-02-08 19:04:40.511
6 | uri | http://example.org/earth | | | | | | | | 2021-02-08 19:04:40.515
7 | uri | http://www.w3.org/1999/02/22-rdf-syntax-ns#type | | | | | | | | 2021-02-08 19:04:40.518
8 | uri | http://example.org/Planet | | | | | | | | 2021-02-08 19:04:40.521
9 | uri | http://localhost/context/default | | | | | | | | 2021-02-08 19:04:40.524
10 | uri | http://www.w3.org/2000/01/rdf-schema#label | | | | | | | | 2021-02-08 19:04:40.536
11 | string | The Earth | | | | | | | en | 2021-02-08 19:04:40.565
12 | uri | http://example.org/radius | | | | | | | | 2021-02-08 19:04:40.572
13 | uri | http://www.w3.org/2001/XMLSchema#decimal | | | | | | | | 2021-02-08 19:04:40.575
14 | double | 6371.1 | 6371.1 | | | | | 13 | | 2021-02-08 19:04:40.582
15 | uri | http://example.org/orbits | | | | | | | | 2021-02-08 19:04:40.587
16 | bnode | 1778308138d26b | | | | | | | | 2021-02-08 19:04:40.589
17 | string | The sun | | | | | | | | 2021-02-08 19:04:40.592
with the following triples
-table:
id | subject | predicate | object | context | creator | inferred | deleted | createdat | deletedat
----+---------+-----------+--------+---------+---------+----------+---------+-------------------------+-----------
18 | 6 | 7 | 8 | 9 | | f | f | 2021-02-08 20:04:40.529 |
19 | 6 | 10 | 11 | 9 | | f | f | 2021-02-08 20:04:40.57 |
20 | 6 | 12 | 14 | 9 | | f | f | 2021-02-08 20:04:40.585 |
21 | 16 | 10 | 17 | 9 | | f | f | 2021-02-08 20:04:40.594 |
22 | 6 | 15 | 16 | 9 | | f | f | 2021-02-08 20:04:40.595 |
Reasoning
KiWi supports reasoning using a datalog-like rule language over triples, with truth maintenance and justifications. For more information, see the KiWi Reasoner page.
Known Bugs
The following is a list of bugs encountered while using the KiWi triplestore in IN5800:
- (SPARQL) If one puts more than one triple in an
OPTIONAL
-clause, only the first triple with be optional - (SPARQL) If one attempts to add variables (containins integers) in
the
SELECT
-clause (e.g.SELECT (?x + ?y AS ?z) WHERE { ... }
) the result might be replaced with an IRI in the triplestore - (SPARQL) If one attempts to use
FILTER NOT EXISTS
-clause, the query crashes with an error