Skip to content

Jena SDB

ThibWeb edited this page Jan 19, 2013 · 7 revisions

Jena SDB : stockage de RDF dans une BD relationnelle

Jena SDB est une solution de persistance pour les modèles RDF de Jena stockant les triplets dans une base de données relationnelle classique.

Dans notre infrastructure, on utilise la base de données cloud Xeround, basée sur MySQL avec un moteur propre, hébergée sur les serveurs islandais de GreenQloud.

Sur cette base, limitée à 10Mo en version gratuite, nous hébergeons le jeu de données Passim : un annuaire de sociétés de transport en commun interconnecté avec le COG de l'INSEE. Ce jeu de données est composé de 20'000 triplets pesant 2Mo en sérialisation RDF/XML, et atteint 8Mo sur la base ordonnée par SDB.

Installation

Mise en place de l'instance Xeround

Xeround propose gratuitement une instance d'un serveur de bases de données basé sur MySQL. Il suffit de choisir quel datacenter utiliser et de créer un compte sur l'instance en question pour ensuite pouvoir la gérer comme n'importe quelle base de données MySQL avec des outils comme phpMyAdmin. On aura ensuite créé sur cette instance une base de données qu'SDB utilisera.

Installation des outils par ligne de commande de SDB

SDB peut être utilisé via son API Java ou grâce à différents scripts Bash.

Il faut tout d'abord télécharger la distribution de SDB ainsi qu'un driver JDBC pour la base de données qui sera exploitée. Ici, Xeround est basé sur MySQL, on va donc télécharger le driver JDBC officiel de MySQL : ConnectorJ.

Le dossier de SDB est ensuite déplacé à un endroit approprié sur l'ordinateur, dans lequel on placera également le connecteur JDBC. Par exemple, /Users/Will/.sdb/sdb-1.3.5/.

Plusieurs variables d'environnement doivent ensuite être définies :

# SDBROOT donne le chemin du dossier d'installation de SDB.
export SDBROOT=/Users/Will/.sdb/sdb-1.3.5
# SDBROOT doit être ajouté au PATH.
export PATH=$SDBROOT/bin:$PATH
# Chemin vers le connecteur JDBC à utiliser.
export SDB_JDBC=$SDBROOT/mysql-connector-java-5.1.22-bin.jar
# Login et mot de passe d'un utilisateur ayant les droits sur la base de données qu'on utilisera.
export SDB_USER="USER_LOGIN"
export SDB_PASSWORD="USER_PASSWORD"

Configuration et remplissage de la base SDB

Les outils précédemment installés peuvent ensuite être utilisés pour déployer nos données sur la base. Il va tout d'abord falloir créer un fichier de description de la base au format Turtle :

@prefix sdb:     <http://jena.hpl.hp.com/2007/sdb#> .
@prefix rdfs:	 <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ja:      <http://jena.hpl.hp.com/2005/11/Assembler#> .

# MySQL on Xeround.
# By Thibaud Colas & Mathilde Salthun-Lassalle

<#store> rdf:type sdb:Store ;
	# Which layout (hash/index) to use.
	# Index might be better for MySQL http://tech.groups.yahoo.com/group/jena-dev/message/43462.
    sdb:layout     "layout2/index" ;
    sdb:connection <#conn> ;
    sdb:engine     "Xeround" ;
.

<#conn> rdf:type sdb:SDBConnection ;
    sdb:sdbType       "MySQL" ;
    sdb:sdbHost       "instance33931.db.xeround.com:15462" ;
    sdb:sdbName       "jena-sdb" ;
    sdb:driver        "com.mysql.jdbc.Driver" ;
    .

Ce fichier spécifie à la fois la structure de la base et la connexion à utiliser : une base avec un layout index (choisi par manque d'espace), le moteur Xeround, et les coordonnées de l'instance à utiliser lors de la connexion. Seuls manquent le login et le mot de passe qui ont eux été définis en variable d'environnement pour ne pas être visibles dans le CVS.

Une fois la configuration écrite, la commande sdbconfig --sdb sdb-xeround-complex.ttl --format permet de mettre en place la structure de la base : tables nœud, préfixes, triplets, quadruplets.

Reste à importer les données au sein de la base avec la commande sdbload --sdb sdb-xeround-complex.ttl passim-linked.rdf. Le processus peut être assez long : 18 secondes à 4 triplets par seconde pour un jeu de 90Ko, jusqu'à 45min pour la totalité de PASSIM.

Pour finir, le script sdbconfig --sdb sdb.ttl --index créé les indexes accélérant les requêtes. On peut enfin lancer une requête avec sdbquery --sdb sdb-xeround-complex.ttl 'SELECT * WHERE { ?s a ?p } LIMIT 10' pour vérifier que tout a bien été exécuté avec succès.

Configuration et remplissage via l'API Java

Configurer SDB en Java

Utilisation

Avec la librairie Java de SDB, on peut configurer et exploiter des bases SDB. Voici un exemple d'utilisation avec les classes Store et Dataset, reposant sur la description externe :

    static public void main(String...argv) {
        String queryString = "SELECT * { ?s ?p ?o } LIMIT 10" ;
        Query query = QueryFactory.create(queryString) ;
        Store store = SDBFactory.connectStore("sdb-xeround-complex.ttl") ;
        
        // Must be a DatasetStore to trigger the SDB query engine. Creating a graph from the Store, and adding it to a general purpose dataset will not necesarily exploit full SQL generation. The right answers will be obtained but slowly.
        Dataset ds = DatasetStore.create(store) ;
        QueryExecution qe = QueryExecutionFactory.create(query, ds) ;
        try {
            ResultSet rs = qe.execSelect() ;
            ResultSetFormatter.out(rs) ;
        } finally { qe.close() ; }
        
        // Close the SDB conenction which also closes the underlying JDBC connection.
        store.getConnection().close() ;
        store.close() ;
    }

Ou encore avec une configuration directe de JDBC :

    static public void main(String...argv) {
        String queryString = "SELECT * { ?s ?p ?o } LIMIT 10" ;
        Query query = QueryFactory.create(queryString) ;
        StoreDesc storeDesc = new StoreDesc(LayoutType.LayoutTripleNodesIndex, DatabaseType.MySQL) ;
        
        JDBC.loadDriverMySQL();
        String jdbcURL = "jdbc:mysql://instance33931.db.xeround.com:15462/jena-sdb"; 
        SDBConnection conn = new SDBConnection(jdbcURL, "your-login", "your-password") ; 

        // Make store from connection and store description. 
        Store store = SDBFactory.connectStore(conn, storeDesc) ;
        
        Dataset ds = DatasetStore.create(store) ;
        QueryExecution qe = QueryExecutionFactory.create(query, ds) ;
        try {
            ResultSet rs = qe.execSelect() ;
            ResultSetFormatter.out(rs) ;
        } finally { qe.close() ; }
        store.close() ;
    }

Et enfin en utilisant un modèle Jena :

    static public void main(String...argv) {
        Store store = StoreFactory.create("sdb-xeround-complex.ttl") ;
        Model model = SDBFactory.connectDefaultModel(store) ;
        
        StmtIterator sIter = model.listStatements() ;
        for (int i = 0; sIter.hasNext() && i < 10; i++) {
            Statement stmt = sIter.nextStatement() ;
            System.out.println(stmt) ;
        }
        sIter.close() ;
        store.close() ;
    }

Mise en application avec l'ontologie

Todo !