This is a basic RDF schema. It is somewhat influenced by schema used by Redland RDF library, but improved to use advanced PostgeSQL features.
In particular, namespaces are kept in separate table; URLs are stored as (namespace_nid,local_component) pair, which allows for faster matching by using integer indices.
Redland stores statements for each model in a separate table; this could be used with Postgres partitioning and constraint exclusion for better performance on huge databases.
MiniUML graph:
<graphviz> digraph rdf1 {
node [shape="box"] namespace; property; resource; "node"; datatype; model; statement; language;
node [shape="house"]; nid; uri; text; name; cardinal; "value type" [label="«enum»\nvalue type\nPL\nTL\nTC_BAG\nTC_ALT\nTC_SEQ"]
statement->resource [label="subject"] statement->resource [label="context"] statement->property [label="predicate"] statement->"node" [label="object"] statement->"value type" [label="value type"] statement->language [label="lang"] statement->cardinal [label="ord"] property->namespace resource->namespace statement->datatype [label="literal datatype"]
language->name;
"node"->nid; resource->uri; namespace->name; property->name; statement->text [label="literal"];
edge [arrowhead="diamond"] statement->model;
edge [arrowhead="empty"] resource->"node"; datatype->resource; property->resource; model->resource; namespace->resource;
}
</graphviz>
Issues:
- should namespace and model be merged
- missing class for class
create schema rdf; set search_path=rdf; create domain uri varchar; create domain url varchar; create domain nid bigint; create domain turtle text; create domain name name; create domain literal text; create domain lang name; create sequence nid_seq; create sequence sid_seq; -- create type triplet ( "subject" turtle, "predicate" turtle, "object" turtle ); create function nid() returns nid as 'select nextval(''nid_seq'')::nid' language sql; create function sid() returns nid as 'select nextval(''sid_seq'')::nid' language sql; -- turtle syntax creator functions create function turtle_uri(uri) returns turtle as '' language plperl immutable; create function turtle_text(text) returns turtle as '' language plperl immutable; -- resource management create function resource(url,model nid) returns nid as '' language plperl immutable; -- model management create function model(source url) returns nid as '' language plperl immutable;; create function model_update(url) returns integer as '' language plperl immutable;; create function model_replace(url) returns integer as '' language plperl immutable;; -- property management create function property(url,model nid) returns nid as '' language plperl immutable;;; -- statement management create function assert(model nid, subject uri, predicate uri, object uri) returns nid as '' language plperl immutable; create function retract(model nid, subject uri, predicate uri, object uri) returns int as '' language plperl immutable; create function assert(model nid, subject turtle, predicate turtle, object turtle) returns nid as '' language plperl immutable; create function retract(model nid, subject turtle, predicate turtle, object turtle) returns int as '' language plperl immutable; create table model ( nid nid primary key, source url ); create table resource ( nid nid primary key, uri uri, owner nid references model ); select wdbi.bless('model'::regclass,'resource'::regclass,'nid'); create function resource(uri) returns nid as 'select nid from resource where uri=$1' language sql; create table namespace ( nid nid default nid() primary key, name name not null unique, uri uri ); select wdbi.bless('namespace'::regclass,'resource'::regclass,'nid'); create table property ( nid nid default nid() primary key, name name, namespace nid ); select wdbi.bless('property'::regclass,'resource'::regclass,'nid'); alter table property add constraint namespace foreign key (namespace) references namespace; create table language ( language lang primary key ); select wdbi.bless('property'::regclass,'resource'::regclass,'nid'); create table datatype ( nid nid default nid() primary key ); select wdbi.bless('datatype'::regclass,'resource'::regclass,'nid'); drop table statement; create table statement ( sid nid default sid() primary key, subject nid not null references resource, predicate nid not null references property, object nid references resource, literal literal, literal_datatype nid references datatype, lang lang references language, context nid references resource, model nid not null references model, ord integer not null default 1, unique (subject,predicate,ord,lang), constraint validator check((object is null and literal is not null) or (object is null and literal is not null)) ); create index statement_model_idx on statement (model); create index statement_subject_idx on statement (subject); create index statement_predicate_idx on statement (predicate); create index statement_object_idx on statement (object); create index statement_lang_idx on statement (lang);
and another one
<graphviz> digraph rdf { node [shape="box"];
"node";
resource; literal; model; statement;
resource->"node"[arrowhead="empty"]; literal->"node"[arrowhead="empty"];
edge [arrowhead="vee"];
statement->resource[label="subject"]; statement->resource[label="predicate"]; statement->"node"[label="object"]; statement->resource[label="context"];
statement->model;
literal->model;
node [shape="house"]; nid;
uri;
text;
"node"->nid; resource->uri; literal->text[label="value"]; literal->resource[label="datatype"]; literal->resource[label="language"]; } </graphviz>
and nother one:
<graphviz> digraph o {
node [shape="box"] rdf_value; rdf_blank_node; rdf_link;
node [shape="house"]; nid; uri; text; name; cardinal; "value_type" [label="«enum»\nvalue type\nPL\nTL\nTC_BAG\nTC_ALT\nTC_SEQ"]
rdf_link->rdf_value [label="start_node_id"]; rdf_link->rdf_value [label="end_node_id"]; rdf_link->rdf_link [label="parent_link_id"]; edge [style="dashed"]; rdf_link->nid [label="link_id"] rdf_value->"value_type"; rdf_value->nid [label="value_id"];
} </graphviz>