RDF Basics
A ten-minute introduction to the data model Waratah stores and queries. Nothing here is Waratah-specific — it is RDF 1.1, the model shared by every RDF system, so it transfers to any tool in this space.
Statements, not tables
RDF keeps data as simple three-part statements called triples:
⟨subject⟩ ⟨predicate⟩ ⟨object⟩
Read a triple as one sentence about one thing:
⟨http://ex/alice⟩ ⟨http://ex/livesIn⟩ ⟨http://ex/brisbane⟩ "Alice lives in Brisbane."
Every fact gets its own triple, and triples that share a subject or an object are connected — that is the graph in graph database. Nothing is fixed in advance about which predicates exist or which subjects carry them; adding a new kind of fact never changes the shape of what is already stored, and data from two different sources merges whenever they use the same identifiers.
IRIs
Subjects and predicates are IRIs — globally unique identifiers that look
like URLs (http://ex/alice). An IRI identifies a thing; it does not have
to be fetchable. Because IRIs are long, every syntax lets you abbreviate
them with a prefix:
PREFIX ex: <http://ex/> ex:alice # same as <http://ex/alice>
Predicates come from vocabularies — shared IRI sets that give a community
common words. rdf:type ("is a"), rdfs:label ("is named"), and the
xsd: datatypes below are the everyday core.
Literals
The object of a triple can also be a literal — a value rather than an identifier:
"http://ex/name" → "Alice" "2025"^^xsd:gYear "Sunny"@en
A literal is a string, optionally with a datatype (2025 as a year, not
a bare word) or a language tag (Sunny as English text). Datatypes come
from the XML Schema namespace: xsd:string, xsd:integer, xsd:double,
xsd:boolean, and — important for Waratah — xsd:dateTime, xsd:date,
xsd:gYear, and xsd:gYearMonth.
Blank nodes
A triple’s subject or object can also be a blank node: an identifier
that is local to the store, written _:b0 in serializations. Blank nodes
say "some thing exists here, but it has no name of its own" — typically
for structure that only makes sense inside its parent fact. You will
rarely write them by hand.
Graphs: triples get a fourth part
RDF lets statements be grouped into named graphs, which adds a fourth slot — where the statement lives — making each fact a quad:
⟨subject⟩ ⟨predicate⟩ ⟨object⟩ ⟨graph⟩
Triples you load without saying otherwise land in the default graph. Named graphs are how one store holds many datasets (or many snapshots, or per-source data) side by side and queries can address them. This is why RDF stores like Waratah are called quadstores.
Turtle, the everyday syntax
Turtle is the compact text serialization you will load most often. The demo dataset from Getting Started, written as Turtle:
@prefix ex: <http://ex/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
ex:alice rdf:type ex:Person ;
ex:name "Alice" ;
ex:livesIn ex:brisbane .
ex:bob rdf:type ex:Person ;
ex:name "Bob" ;
ex:livesIn ex:hobart .
ex:brisbane rdf:type ex:City ;
ex:hasWeather "Sunny" .
ex:hobart rdf:type ex:City ;
ex:hasWeather "Cold" .
The semicolons continue statements about the same subject; a is the
usual shorthand for rdf:type. The same data comes in other shapes —
N-Triples (one triple per line, no prefixes), N-Quads and TriG (the quad
forms), RDF/XML, and gzipped variants of these; Waratah’s loader reads
all of them.
What a query looks like
SPARQL is RDF’s query language, and its core idea is one line long: write the shape of the statements you want, with variables in the slots you do not know yet:
SELECT ?name WHERE {
?person ex:livesIn ex:brisbane .
?person ex:name ?name .
}
The store finds every way to fill the variables with real triples —
here, every ?name belonging to someone who livesIn ex:brisbane.
SPARQL Basics builds on this with filters,
optionals, unions, and aggregates.