Quels types de requêtes ?
Selections
[ @email = 'emmanuel.coquery@univ-lyon1.fr' ]
Jointures classiques
personne[ @id = //rendez-vous/invite/@id ]
Twig joins
rendez-vous[ @debut > '2013-11-12T14:00' ] // invite[ nom = 'Coquery' ]
Selections et jointures (sauf twig)
index
//personne/nom
requête pouvant l'utiliser
//personne[ nom = 'Coquery' ]/age
\(\equiv\)
//personne/nom[ . = 'Coquery' ]/../age
Optimisation du twig join
nœud 1 ancêtre de nœud 2 ?
Le noeud de l'enfant contient l'adresse du noeud du parent
Le noeud parent contient la liste des adresses des noeuds enfants
noeud \(\leftrightarrow\) chemin depuis la racine
1 pas du chemin \(\leftrightarrow\) numéro de l'enfant
\(n_1\) ancêtre de \(n_2\)
\(\equiv\)
chemin(\(n_1\)) prefixe de chemin(\(n_2\))
| Nom | Chemin |
|---|---|
| Martin | 1 |
| Julius | 11 |
| Jones | 111 |
| Brown | 112 |
| Lambert | 12 |
| Bellot | 121 |
| LambertJr | 1211 |
| Soule | 13 |
| Dupuis | 131 |
| Fildou | 132 |
<agenda>
<rendez-vous
debut="2013-11-12T14:00"
fin="2013-11-12T15:30">
<invite id="3">
<nom>Coquery</nom>
</invite>
<salle>Ampere</salle>
</rendez-vous>
<personne id="3">
<nom>Coquery</nom>
</personne>
</agenda>
noeud ↔ intervalle unique
\(n_1\) ancêtre de \(n_2\)
\(\equiv\)
\(intervalle(n_1) \supseteq intervalle(n_2)\)
| Nom | d | f |
|---|---|---|
| Martin | 1 | 20 |
| Julius | 2 | 7 |
| Jones | 3 | 4 |
| Brown | 5 | 6 |
| Lambert | 8 | 13 |
| Bellot | 9 | 12 |
| LambertJr | 10 | 11 |
| Soule | 14 | 19 |
| Dupuis | 15 | 16 |
| Fildou | 17 | 18 |
w: nb fils du parent
h: hauteur de l'arbre
s: taille de l'arbre
Idée: numéroter les fils
avec des nombres impairs uniquement
Utiliser les nombres pairs comme
des noeuds virtuels
Maintient les propriétés ancêtre ↔ descendant
Prévoir de la place au départ:
Grands intervalles
Ajout au [ 1/3, 2/3 ] de la place libre
Plus de place → rééquilibrage des intervalles
Relations entre noeuds
URIs & Littéraux
Peu/pas de contraintes de schéma
Évaluation de SPARQL:
Pas si différent de l'algèbre relationnelle
triplets
Une table triple(suj,pred,obj)
ou 3 tables:
triple(suj,pred,type,obj)
uris(id,uri)
literals(id,lit)
IDs entiers plutôt que chaines
...
SELECT ?r WHERE {
?r agenda:invite ?p.
?p agenda:nom ?n.
FILTER(?n = "Coquery").
}
Requête SPARQL -> Requête SQL
SELECT u.uri
FROM triple invite, triple nom,
literals l, uris u
WHERE invite.obj = nom.suj
AND nom.obj = l.id
AND l.lit = 'Coquery'
AND invite.suj = u.id
Une grande table
Ligne = Subject
Attribut = prédicat
Valeur = sujet
Mapping: ID ↔ URI/Littéral
Attention aux cardinalités
→ plusieurs tables
Utilisation du partitionnement vertical (MIF37)
→ SGBD colonnes
Classe RDFS → Table
Prédicat → attribut
si card max = 1
Prédicat → table
sinon
uri litéral
RendezVous (uri, agenda:debut, agenda:fin, agenda:salle)
Personne(uri, agenda:nom)
agenda:invite(uris,urio)
SELECT rdv.uri FROM RendezVous rdv, "agenda:invite" inv, Personne p WHERE rdv.uri = inv.uris AND inv.urio = p.uri AND p.nom = 'Coquery'
Certains prédicats sont stockés
en relationnel avec ontologie
Les autres:
Lecture seule
Mapping: schéma relationnel → RDFS / Ontologies