I. Introduction▲
D2R Server est un outil permettant de proposer toutes vos données contenues dans une base de données (MySQL, PostgreSQL, Oracle…) en RDF. Simplement dit, il permet donc de faire correspondre vos données avec un vocabulaire quelconque afin de les manipuler en RDF. Une fois ceci fait, il propose également une interface Web afin de parcourir visuellement vos données RDF ainsi qu'un SPARQL endpoint en vue de les interroger. Pour plus de détails sur ses fonctionnalités, je vous renvoie à la traduction de la documentation. Bien entendu toute la démarche que je vais vous montrer est possible sur tous les OS où Java est disponible.
II. Mise en Å“uvre▲
Nous allons travailler sur une base de données décrivant des joueurs de tennis et les tournois dans lesquels ils jouent. Voici donc le SQL minimum correspondant à notre base de données :
-- phpMyAdmin SQL Dump
-- version 3.5.1
-- http://www.phpmyadmin.net
--
-- Client: localhost
-- Généré le: Dim 02 Décembre 2012 à 16:27
-- Version du serveur: 5.5.24-log
-- Version de PHP: 5.4.3
SET
SQL_MODE=
"NO_AUTO_VALUE_ON_ZERO"
;
SET
time_zone =
"+00:00"
;
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */
;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */
;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */
;
/*!40101 SET NAMES utf8 */
;
--
-- Base de données: `tennis`
--
-- --------------------------------------------------------
--
-- Structure de la table `player`
--
DROP
TABLE
IF
EXISTS
`player`
;
CREATE
TABLE
IF
NOT
EXISTS
`player`
(
`id`
int
(
11
)
NOT
NULL
AUTO_INCREMENT
,
`familyName`
varchar
(
32
)
COLLATE
utf8_unicode_ci NOT
NULL
,
`givenName`
varchar
(
32
)
COLLATE
utf8_unicode_ci NOT
NULL
,
`birthDate`
date
NOT
NULL
,
`size`
int
(
11
)
NOT
NULL
,
`weight`
int
(
11
)
NOT
NULL
,
`livingCity`
varchar
(
32
)
COLLATE
utf8_unicode_ci NOT
NULL
,
`start`
int
(
11
)
NOT
NULL
,
`game`
varchar
(
32
)
COLLATE
utf8_unicode_ci NOT
NULL
,
`ranking`
int
(
11
)
NOT
NULL
,
`points`
int
(
11
)
NOT
NULL
,
PRIMARY
KEY
(
`id`
)
)
ENGINE
=
InnoDB DEFAULT
CHARSET
=
utf8 COLLATE
=
utf8_unicode_ci AUTO_INCREMENT
=
3
;
--
-- Contenu de la table `player`
--
INSERT
INTO
`player`
(
`id`
, `familyName`
, `givenName`
, `birthDate`
, `size`
, `weight`
, `livingCity`
, `start`
, `game`
, `ranking`
, `points`
)
VALUES
(
1
, 'Djokovic'
, 'Novak'
, '1987-05-22'
, 188
, 80
, 'Belgrade'
, 2003
, 'droitier, revers à deux mains'
, 2
, 0
)
,
(
2
, 'Querrey'
, 'Sam'
, '1987-11-07'
, 198
, 91
, 'Thousand Oaks, Californie'
, 2006
, 'droitier, revers à deux mains'
, 29
, 0
)
;
-- --------------------------------------------------------
--
-- Structure de la table `tournament`
--
DROP
TABLE
IF
EXISTS
`tournament`
;
CREATE
TABLE
IF
NOT
EXISTS
`tournament`
(
`id`
int
(
11
)
NOT
NULL
AUTO_INCREMENT
,
`name`
varchar
(
32
)
COLLATE
utf8_unicode_ci NOT
NULL
,
`year`
int
(
11
)
NOT
NULL
,
`id_winner`
int
(
11
)
NOT
NULL
,
PRIMARY
KEY
(
`id`
)
,
KEY
`fk_tournament`
(
`id_winner`
)
)
ENGINE
=
InnoDB DEFAULT
CHARSET
=
utf8 COLLATE
=
utf8_unicode_ci AUTO_INCREMENT
=
2
;
--
-- Contenu de la table `tournament`
--
INSERT
INTO
`tournament`
(
`id`
, `name`
, `year`
, `id_winner`
)
VALUES
(
1
, 'open du Canada'
, 2012
, 1
)
;
-- --------------------------------------------------------
--
-- Structure de la table `tournament_phase`
--
DROP
TABLE
IF
EXISTS
`tournament_phase`
;
CREATE
TABLE
IF
NOT
EXISTS
`tournament_phase`
(
`id`
int
(
11
)
NOT
NULL
AUTO_INCREMENT
,
`phase`
varchar
(
10
)
COLLATE
utf8_unicode_ci NOT
NULL
,
`id_tournament`
int
(
11
)
NOT
NULL
,
`id_player1`
int
(
11
)
NOT
NULL
,
`id_player2`
int
(
11
)
NOT
NULL
,
`id_winner`
int
(
11
)
NOT
NULL
,
PRIMARY
KEY
(
`id`
)
,
KEY
`fk_tournament_phase`
(
`id_tournament`
)
,
KEY
`fk_tournament_phase2`
(
`id_player1`
)
,
KEY
`fk_tournament_phase3`
(
`id_player2`
)
,
KEY
`fk_tournament_phase4`
(
`id_winner`
)
)
ENGINE
=
InnoDB DEFAULT
CHARSET
=
utf8 COLLATE
=
utf8_unicode_ci AUTO_INCREMENT
=
2
;
--
-- Contenu de la table `tournament_phase`
--
INSERT
INTO
`tournament_phase`
(
`id`
, `phase`
, `id_tournament`
, `id_player1`
, `id_player2`
, `id_winner`
)
VALUES
(
1
, '1/8'
, 1
, 1
, 2
, 1
)
;
--
-- Contraintes pour les tables exportées
--
--
-- Contraintes pour la table `tournament`
--
ALTER
TABLE
`tournament`
ADD
CONSTRAINT
`fk_tournament`
FOREIGN
KEY
(
`id_winner`
)
REFERENCES
`player`
(
`id`
)
;
--
-- Contraintes pour la table `tournament_phase`
--
ALTER
TABLE
`tournament_phase`
ADD
CONSTRAINT
`fk_tournament_phase`
FOREIGN
KEY
(
`id_tournament`
)
REFERENCES
`tournament`
(
`id`
)
,
ADD
CONSTRAINT
`fk_tournament_phase2`
FOREIGN
KEY
(
`id_player1`
)
REFERENCES
`player`
(
`id`
)
,
ADD
CONSTRAINT
`fk_tournament_phase3`
FOREIGN
KEY
(
`id_player2`
)
REFERENCES
`player`
(
`id`
)
,
ADD
CONSTRAINT
`fk_tournament_phase4`
FOREIGN
KEY
(
`id_winner`
)
REFERENCES
`player`
(
`id`
)
;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */
;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */
;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */
;
Vous pouvez bien entendu modifier la structure et ajouter du contenu à votre guise. Maintenant, il nous reste à télécharger D2R Server, le seul prérequis est d'avoir installé Java sur votre ordinateur. Une fois l'outil téléchargé et dézippé vous devez avoir une structure comme celle-ci :
Vous ne devez toucher à rien dans ce dossier sous risque de rendre l'outil inutilisable. Maintenant que l'outil est prêt à fonctionner ouvrons une invite de commande, personnellement je préfère Power Shell. Assurez-vous que votre SGBD est bien démarré, pour moi ce sera MySQL, puis placez-vous dans le répertoire de D2R Server :
Tapez maintenant cette commande :
./generate-mapping -o mapping.ttl -u julien -p julien jdbc:mysql://localhost/tennis
- -o nom du fichier d'associations généré ;
- -u nom d'utilisateur de MySQLÂ ;
- -p mot de passe correspondant à l'utilisateur ;
- le dernier paramètre correspond à l'adresse de la base de données.
Maintenant que nous avons notre fichier d'associations, nous pouvons démarrer D2R Server, comme ceci :
./d2r-server ./mapping.ttl
Ouvrez votre navigateur à l'adresse http://localhost:2020, vous devriez avoir ce résultat :
Vous pouvez dès à présent naviguer parmi vos données, par exemple :
Comme vous pouvez le remarquer, certaines propriétés ne sont pas des valeurs à proprement parler, mais plutôt des URI. Pourquoi ? Tout simplement parce que D2R lors de la création de son fichier a analysé votre base de données et a vu que les champs correspondant à ces propriétés avaient des clés étrangères et donc l'outil crée automatiquement un lien vers l'id correspondant. Ainsi vous pouvez avoir une véritable structuration RDF bien formée.
III. Le fichier d'associations D2RQ▲
Vous êtes totalement libre de modifier ou non votre fichier d'associations. Il est d'ailleurs même fortement conseillé de le faire afin de faire correspondre vos champs et vos tables à un véritable vocabulaire ou à une véritable ontologie. Voici un petit exemple de changement pour la fiche d'un joueur :
# Table player
# ne pas oublier de rajouter "@prefix foaf: <http://xmlns.com/foaf/0.1/> ." au début du fichier
map:player a d2rq:ClassMap;
d2rq:dataStorage map:database;
d2rq:uriPattern "player/@@player.id@@";
d2rq:class foaf:Person;
d2rq:classDefinitionLabel "player";
.
map:player__label a d2rq:PropertyBridge;
d2rq:belongsToClassMap map:player;
d2rq:property rdfs:label;
d2rq:pattern "@@player.givenName@@ @@player.familyName@@";
.
map:player_familyName a d2rq:PropertyBridge;
d2rq:belongsToClassMap map:player;
d2rq:property foaf:familyName;
d2rq:propertyDefinitionLabel "player familyName";
d2rq:column "player.familyName";
.
map:player_givenName a d2rq:PropertyBridge;
d2rq:belongsToClassMap map:player;
d2rq:property foaf:givenName;
d2rq:propertyDefinitionLabel "player givenName";
d2rq:column "player.givenName";
.
Vous obtenez maintenant un RDF plus compréhensible pour tout le monde :
Je vous laisse terminer le reste en créant votre propre vocabulaire ou ontologie. Petite précision, vous avez pu remarquer que la propriété correspondant à l'id du joueur n'est plus affichée, ceci pour dire que vous avez le droit d'ajouter ou de supprimer autant d'associations que vous le voulez. Et par conséquent, les requêtes SPARQL sont aussi plus compréhensibles, par exemple le résultat de celle-ci :
SELECT DISTINCT ?name WHERE {
?player rdfs:label ?name ;
rdf:type foaf:Person .
}
Donnera :
IV. Conclusion▲
Voilà vous pouvez dès à présent entamer la suite de votre apprentissage en lisant la documentation puisque vous avez maintenant toutes les bases requises pour bien l'appréhender. N'hésitez pas à proposer sur le post correspondant à ce tutoriel vos fichiers d'associations D2RQ concernant cette base de données de tennis afin de partager vos résultats et demander des conseils.
V. Remerciements▲
Merci à Torgar et à Claude Leloup pour leur relecture orthographique.