Sémantiser une base de données relationnelle (1er épisode)

Dans un billet précédent, j’avais commencé à envisager l’évolution de la base de données relationnelle des auteurs de langue bretonne du projet PRELIB afin de mieux gérer la saisie des données temporelles. Mais au delà de ce problème, ce pose la question du stockage dans une base de donnée relationnelle et le passage au web sémantique.

Je m’intéresse depuis 2012 au web sémantique mais j’avais du mal à passer à la pratique faute d’avoir trouvé un outil de publication en RDF bien documenté et des vocabulaires ou des ontologies permettant d’exprimer nos données biographiques en RDF.

Concernant les outils, j’avais découvert en 2013 le logiciel Open source Callimachus en lisant le livre Linked Data co-écrit par David Wood (livre dont je vous recommande la lecture que je trouve plus digeste que celle du livre en français Le web sémantique), mais la documentation de Callimachus n’était pas assez aboutie à l’époque et je n’ai pas su comment l’utiliser pour mes besoins. J’avais aussi repéré CubicWeb un outil en Python sur lequel repose data.bnf.fr. Mais son installation s’est avérée trop compliquée sous Windows et je n’ai pas pu le tester. Sans compter là encore sur une documentation peu aboutie.

D’un autre côté, la plateforme DataLift, que j’ai rapidement testée la semaine dernière, permettrait dans un premier temps de transformer les données relationnelles en RDF. Je conserverai le stockage des données dans la base de données relationnelle mySQL, mais elles seraient « libérées » de la base sous la forme d’un export en RDF (et interrogeables à travers un SPARQL Endpoint ou REST + RESTdesc ? A voir).

Pour découvrir DataLift, je vous conseille de visionner la vidéo de démonstration de Gabriel Kepeklian où il se sert de DataLift pour sémantiser en quelques clics un fichier CSV des emplacements des kiosques à journaux mis à disposition sur ParisData. C’est plutôt convaincant.

Du côté des vocabulaires, j’avais identifié FRBR pour la saisie des œuvres littéraires mais j’avais du mal à en trouver une pour exprimer les données biographiques jusqu’à ce que j’entende parler fin 2014 de CIDOC1 CRM2 grâce au projet Biblissima.

Une lecture récente de documents sur le CIDOC CRM m’a également permit de comprendre que FRBRoo (FRBR object oriented) était une extension du modèle du CIDOC et que je devais plutôt m’intéresser à FRBRoo qu’à FRBR pour exprimer en RDF les données de ma base concernant la production littéraire.

L’objectif, au printemps 2015 est donc d’essayer de voir comment exprimer les données avec le CIDOC CRM et FRBRoo puis de convertir les données de la base de données relationnelles avec DataLift afin de comparer les requêtes SPARQL avec des requêtes SQL, de faire des essais d’analyse de réseau à partir de ces données RDF et de vérifier si le web sémantique permet réellement d’inférer de nouvelles connaissances (peut-être l’aspect le plus intéressant du web sémantique) en mettant en pratique l’article Bringing reasoning to the Web de Ruben Verborgh.

Vous pouvez télécharger le PDF du Schéma conceptuel de la base de données PRELIB au 23 octobre 2014. Ce n’est certainement pas un modèle à suivre pour la conception d’une base de données relationnelle mais il me servira de référence pour RDFiser la base de données par étapes successives.

Pour commencer, où peut-on trouver des informations sur le CIDOC CRM ?

Le site officiel du CIDOC CRM (version du 17 avril 2015) est la source de référence mais est un peu fouillis. L’information est dispersée dans de multiples sous-rubriques où l’on a un peu de mal à se retrouver. Mais j’ai découvert un peu par hasard qu’une nouvelle version du site est en chantier à cette adresse http://139.91.183.82:8888/drupal/ où l’excellent CIDOC-CRM Tutorial et la version HTML du manuel de référence de la version 6.0 du CRM (sortie en février 2015) sont mieux mis en avant.

SI vous êtes intéressés par la version PDF du manuel de référence (200 pages) de la version 6.0, il est disponible depuis la page Official Release of the CIDOC CRM où vous trouverez également un lien vers l’expression en RDF Schema du modèle (à consulter aussi sur LOV, Linked Open Vocabulary3).

Le manuel faisant 200 pages, vous aurez une meilleure introduction au CRM en lisant le document d’introduction (les anglophones appellent ce type de document des « primer ») ou si vous avez du temps devant vous, en visionnant les vidéos du CIDOC-CRM Tutorial.

Pour vous y retrouver dans les multiples entités et propriétés du modèle, vous pouvez aussi consulter des représentations graphiques de la version 5.0.4 du modèle : La version complète et la version réduite.

Toutes ces ressources sont en anglais. Le seul document de référence en français sur le CIDOC CRM est la traduction de la norme ISO 21127 (la normalisation ISO du CIDOC CRM) dont la lecture vous coutera 198 francs suisses sur le site de l’ISO ou 157 euros sur la boutique en ligne de l’Afnor.

Il faut noter au passage que le CIDOC CRM est un modèle et qu’il n’impose pas de langage pour exprimer les données. Je pourrai donc tout aussi bien adapter ma base de données relationnelle pour qu’elle repose sur le modèle, rien ne m’oblige à utiliser le RDF sinon mon intérêt pour ce format et le web sémantique. Il est néanmoins dommage que l’on ne trouve pas d’exemples de données exprimées en RDF sur le site officiel du CIDOC CRM alors que le Dublin Core Metadata Initiative l’a fait pour le Dublin Core dans deux guides utilisateurs publiés sur son wiki4.

Table "Personne" de la base de données relationnelle PRELIB
Table « Personne » de la base de données relationnelle PRELIB

Essayons d’appliquer le modèle CIDOC CRM à la base de données en commençant par la table « Personne » qui stocke des informations sur des individus. L’entité qui correspond le mieux à cette table est E21 Person. Dans le futur site du projet, chaque individu va devenir une ressource RDF de type E21 Person accessible à partir d’une URI construite à partir de la clé primaire de la table « Personne ». Par exemple, les informations sur Théodore Hersart de la Villemarqué, qui a pour clé primaire id_personne = 80 dans la table « Personne » pourra être accessible à l’URI http://prelib.huma-num.fr/person/80. Notez que vous pourrez récupérer depuis cette URI, soit du contenu en HTML sur Théodore si vous la consultez avec votre navigateur web, soit du RDF si vous vous connectez avec une application telle ARQ pour faire des requêtes SPARQL5.

Une première lecture de la référence à E21 Person dans le manuel de référence peut donner l’impression que l’entité n’a qu’une seule propriété P152 has parent. Ne peut-on que donner des informations sur les parents d’un individu avec CIDOC-CRM ?

Que neni.

En effet, en consultant la représentation graphique des entités et des modules disponibles pour signifier l’existence d’un objet ou d’une personne (reproduite ci-dessous), on se rend compte qu’il existe une propriété P98 brought into life qui permet de lier la personne à une ressource de type E67 Birth. Notez au passage que le sens de la flèche entre E67 Birth et E21 Person indique que P98 brought into life est une propriété de E67 Birth et non pas de E21 Person.

Source : http://www.cidoc-crm.org/cidoc_graphical_representation_v_5_1/existence.html
Source :http://www.cidoc-crm.org/cidoc_graphical_representation_v_5_1/existence.html

Le diagramme indique aussi les cardinalités. Ces couples (0,n) ou (1,n) ou (0,1) qui indiquent le nombre d’entités minimales et maximales impliquées dans la relation. Notamment le (0,n) indiqué du côté de E67 Birth pour la propriété  P98 brought into life indique qu’un accouchement (il s’agit plus d’un accouchement que d’une naissance si je ne m’abuse) peut donner naissance à zéro (!?) ou plusieurs enfants (dans le cas de jumeaux, triplés, etc.). Le (1,1) du côté de E21 Person précise comme on pourrait s’y attendre qu’une personne ne peut naitre qu’une seule fois lors du même accouchement et qu’un individu est forcément né une fois (donc Dieu ne peut être une E21 Person si on considère qu’il a toujours existé). On voit que E67 Birth nous permet aussi de déclarer le père et la mère des enfants et il y a fort à parier que l’on puisse aussi déclarer le lieu de la naissance.

A creuser : Les cardinalités fonctionnent-elles pour toutes les instances de l’entité ou pour une seule ? Autrement dit, dès qu’un individu est impliqué dans un accouchement comme nouveau-né, est ce que cela suffit pour qu’il ne puisse pas être impliqué dans un autre accouchement ?

Au passage, rien ne nous empêche d’enfreindre les règles de cardinalité. Il nous faudra nous même mettre en place des mécanismes pour vérifier si les règles sont respectées.

Concernant les parents, le manuel indique pour E67 Birth que dans ce modèle, le père biologique n’est pas vu comme un participant nécessaire de l’événement. Ce qui conforte l’idée que l’entité E67 Birth permet de décrire un accouchement (un événement impliquant la mère et les nouveaux-nés, ayant lieu à une date, une durée et à un endroit donnés) et non pas des liens de parentés. Puisque comme chacun sait, les pères n’assistent pas systématiquement à la naissance de leurs enfants.

In this model, the biological father is not seen as a necessary participant in the E67 Birth event.

Le manuel précise également que P96 by mother et P97 from father concernent uniquement les parents biologiques. Le modèle n’écarte pas pour autant les parents non-biologiques puisqu’ils peuvent être déclarés avec la fameuse propriété P152 has parent évoquée précédemment :

This property associates an instance of E21 Person with another instance of E21 Person who plays the role of the first instance’s parent, regardless of whether the relationship is biological parenthood, assumed or pretended biological parenthood or an equivalent legal status of rights and obligations obtained by a social or legal act.

Extrait de l'acte de naissance de Théodore Hersart de la Villemarqué
Extrait de l’acte de naissance de Théodore Hersart de la Villemarqué. Source : Archives départementales du Finistère (http://mnesys-portail.archives-finistere.fr).

D’après l’acte de naissance de Théodore Hersart de la Villemarqué6, l’auteur du Barzaz-Breiz est né le 7 juillet 1815 à Quimperlé et il est le fils de Pierre Michel François Marie Toussaint Hersart de la Villemarqué et de Marie Ursule Claude Henriette Kerjean Feydeau.

Pour exprimer cette information en RDF, il nous faut une URI (si possible une URL permanente ou PURL) où un processeur SPARQL comme ARQ pourra trouver une version RDF Shema ou OWL du CIDOC CRM7. En tapant « CIDOC » sur LOV (Linked Open Vocabularies), on trouve que l’espace de nom du CIDOC est http://www.cidoc-crm.org/cidoc-crm/.

L’URI http://prelib.huma-num.fr/person/80 pourrait donc renvoyer le RDF suivant (exprimé ici avec Turtle) :

@prefix prelib: <http://prelib.huma-num.fr/> .
@prefix cidoc: <http://www.cidoc-crm.org/cidoc-crm/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix dc: <http://purl.org/dc/terms/> .

prelib:person/80 a cidoc:Person, foaf:Person ;
dc:title "Théodore-Claude-Henri Hersart de la Villemarqué (1815-1895)"@fr ;
foaf:name "Théodore-Claude-Henri Hersart de la Villemarqué"@fr ;
foaf:givenName "Théodore Claude Henri" ;
foaf:familyName "Hersart de la Villemarqué" ;
foaf:nickname "Barz Nizon", "Kervarker";
foaf:gender "male"@en, "homme"@fr.

Le CIDOC CRM permet de nommer les ressources mais je vais me contenter pour l’instant d’exprimer le nom et les pseudonymes de Théodore avec le Dublin Core et FOAF (Friend of a Friend) comme le fait la BnF sur data.bnf.fr.

Les informations concernant la naissance de Théodore devront être exprimées depuis une autre URI par une autre ressource de type E67 Birth. En effet, je ne peux exprimer à l’adresse http://prelib.huma-num.fr/person/80 que des triplets qui ont pour sujet8 la ressource elle-même (Enfin, je suppose que c’est comme cela qu’il faut procéder).

Je pourrai mettre à disposition la ressource à l’URI http://prelib.huma-num.fr/birth/1 (où le chiffre 1 indique le numéro de la ressource de type E67 Birth) mais pour éviter d’utiliser des chemins dédiés à chaque classe du CIDOC CRM, je vais utiliser le nom de la classe générique E5 Event dans le chemin de l’URI.

Supposons donc qu’à l’URI http://prelib.huma-num.fr/event/1 on va pouvoir récupérer le RDF suivant (en supposant que l’URI correspondant à Marie Kerjean Feydeau, la mère de Théodore soit http://prelib.huma-num.fr/person/1115) :

@prefix prelib: <http://prelib.huma-num.fr/> .
@prefix cidoc: <http://www.cidoc-crm.org/cidoc-crm/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix dc: <http://purl.org/dc/terms/> .

prelib:event/1 a cidoc:Event ;
prelib:event/1 a cidoc:Birth ;
cidoc:brought_into_life prelib:person/80 ;
cidoc:by_mother prelib:person/1115.

Comme rien ne prouve que le père de Théodore n’ai assisté à l’accouchement, on ne le rajoute pas à l’événement avec la propriété P97 from father. Par contre, comment signaler la date et le lieu de l’heureux événement ? C’est là que ça se complique.

En parcourant les représentations graphiques sur le site officiel du modèle, j’ai trouvé la modélisation des informations sur la nationalité d’une personne où l’on constate que l’on peut déclarer qu’un accouchement E67 Birth s’est produit durant une E4 Period et à une E53 Place.

Modélisation des informations sur une personne avec le modèle CIDOC CRM. Source : http://www.cidoc-crm.org/cidoc_graphical_representation_v_5_1/person_nationality.html.
Modélisation des informations sur une personne avec le modèle CIDOC CRM. Source : http://www.cidoc-crm.org/cidoc_graphical_representation_v_5_1/person_nationality.html.

Cependant, P10 falls within sert à lier entre elles des E4_Period et servirait plutôt à déclarer que la naissance de Théodore a eu lieu durant la Restauration. Comme E67 Birth est une sous-classe de E2 Temporal Entity (une sous-sous-sous-classe) il doit bien y avoir moyen de déclarer la date du 7 juillet 1815 avec une propriété quelconque de Temporal Entity ou de ses sous-classes ?

En cherchant sur le web, j’ai trouvé la présentation du modèle CIDOC CRM par Patrick Le Boeuf le 9 décembre 2010 (reproduite ci-dessus) où l’on constate à la diapositive n°37 que la valeur littérale de la date de l’accouchement pourrait être saisie grâce à une ressource de type E50 Date elle même reliée à notre accouchement par P4 has time-span.

Pour l’instant, j’utilise une ressource anonyme ou blank node en anglais pour exprimer la ressource de type E50 Date et je saisi la valeur littérale avec une propriété rdfs:label et en lui donnant un type xsd:date conforme au format ISO 8601.

@prefix prelib: <http://prelib.huma-num.fr/> .
@prefix cidoc: <http://www.cidoc-crm.org/cidoc-crm/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix dc: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

prelib:event/1 a cidoc:Event ;
prelib:event/1 a cidoc:Birth ;
cidoc:brought_into_life prelib:person/80 ;
cidoc:by_mother prelib:person/1115.
cidoc:is_identified_by _:date1

_:date1 a cidoc:Date ;
rdfs:label "1815-07-07"^^xsd:date

Pourquoi utiliser rdfs:label ? Et bien parce que c’est le seul moyen que j’ai trouvé l’instant pour saisir cette fameuse valeur. Si vous exprimez ces données avec RDF/XML, vous pouvez toujours mettre la valeur à l’intérieur d’une balise, comme dans l’exemple de la saisie de la période entre -500 à 500 tiré du wiki du projet Claros.

<crm:E52_Time-Span>
<crm:P82_at_some_time_within>
<claros:Period>
<claros:period_begin rdf:datatype="&xsd;gYear">-550</claros:period_begin>
<claros:period_end   rdf:datatype="&xsd;gYear">-500</claros:period_end>
</claros:Period>
</crm:P82_at_some_time_within>
</crm:E52_Time-Span>

Sauf qu’avec Turtle ou Notation3 (N3), la valeur (l’objet du triplet RDF) passe forcément par l’utilisation d’un prédicat. C’est pourquoi GND Ontology l’ontologie de la Deutsche Nationalbibliothek met à disposition la propriété (en non pas la classe) Date of birth qui permet la déclaration suivante :

@prefix prelib: <http://prelib.huma-num.fr/> .
@prefix cidoc: <http://www.cidoc-crm.org/cidoc-crm/> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix dc: <http://purl.org/dc/terms/> .
@prefix gnd: <http://d-nb.info/standards/elementset/gnd#> .

prelib:person/80 a cidoc:Person, foaf:Person , gnd:DifferentiatedPerson ;
dc:title "Théodore-Claude-Henri Hersart de la Villemarqué (1815-1895)"@fr ;
foaf:name "Théodore-Claude-Henri Hersart de la Villemarqué"@fr ;
gnd:dateOfBirth "1815/07/07"^^xsd:date .

Bon, ce billet est assez long comme ça. La suite au prochain épisode…

  1. Comité International pour la DOCumentation du Conseil international des musées []
  2. Conceptual Reference Model []
  3. Linked Open Vocabularies est un projet hébergé par l’Open Knowledge Fundation qui propose le référencement d’ontologies pour le web des données. []
  4. Wiki qui n’est certes pas mis en avant. []
  5. Pour en savoir plus, vous pouvez consulter la page Wikipedia sur la négociation de contenu : http://fr.wikipedia.org/wiki/N%C3%A9gociation_de_contenu. []
  6. L’acte de naissance de Théodore Hersart de la Villemarqué peut-être consulté en ligne dans la version numérisée des actes de naissances de Quimperlé entre 1814 et 1822 sur le portail des Archives départementales du Finistère. []
  7. Si vous n’êtes pas familiers avec ce vocabulaire, lisez le RDF 1.1 Primer du W3C. C’est une bonne introduction au web sémantique []
  8. Pour le concept de triplets RDF composés d’un sujet, d’un prédicat et d’un objet, lire le RDF 1.1 Primer. []

La saisie et les requêtes de dates pour la prosopographie (1ère partie)

Avertissement : Cet article est en cours de rédaction mais il est publié pour permettre une discussion sur ce sujet.

Depuis 2012, date de mon arrivée à l’UMS, je travaille avec deux enseignantes-chercheuses de Celtique, Mannaig Thomas et Nelly Blanchard à une base de données prosopographique des auteurs de langue bretonne. Cette base de données a été créée dans le cadre du projet PRELIB dont une des ambitions est de comprendre les raisons qui ont poussé des personnes à écrire et à publier en breton. En effet, écrire en breton, langue de tradition orale, ne va pas de soi et résulte d’un choix qui peut être influencé par la fréquentation de personnes rencontrées dans des lieux de sociabilité tels que des cercles littéraires, des associations ou des mouvements politiques.

La base contient des informations du type : François Jaffrennou est né le 15 mars 1879 à Carnoët, il a étudié au Collège Notre-Dame-de-Bon-Secours à Guingamp vers 1891 puis a débuté des études de droit à Rennes en 1899. Il a contribué aux revues An Oaled, War Sao, Buez Breiz. Il a été secrétaire de la section Langue et Littérature Bretonne de l’Union Régionaliste Bretonne à partir du 14 aout 1898. Il est l’auteur de Oberou yaouankiz, Ganedigez eun emzao, Le dictionnaire français-breton de poche.

Dans cette base de données relationnelle, conçue avec mySQL, la plupart des dates (par ex. une date de naissance) ne sont pas saisies dans un seul champ sous la forme d’une date complète (un jour, un mois, une année) mais dans trois champs séparant la saisie du jour, du mois et de l’année. Du point de vue du stockage, les dates ne sont pas stockées au format SQL DATE mais dans trois champs SQL de type INTEGER (un chiffre entier).

Les bases de données relationnelles ne permettent pas la saisie d’intervalles de temps. Elles ne permettent la saisie de données temporelles que sous la forme de dates (avec obligatoirement un jour, un mois, une année). Or les données historiques sont souvent imprécises et il n’est pas rare que l’on ne connaisse pas la date complète d’un événement (une date de naissance, la date à laquelle un individu a été élu président d’une association, etc.). La séparation de la saisie a donc été envisagée sous la forme de trois champs séparés pour le jour, le mois et l’année en attendant de trouver une solution plus orthodoxe.

Dans les bases de données SQL, les données de type date sont stockées au format aaaa-mm-jj (je parle bien ici du stockage dans la base et non pas de la saisie, le stockage dans ce format n’empêchant pas la saisie dans un formulaire web de dates au format français jj/mm/aaaa). La date du 3 juillet 1896 sera donc stockée sous la forme 1896-07-03.

On pourrait alors envisager de stocker une date incomplète en remplaçant le jour ou le mois par des zéros. Par exemple, si l’on sait que la personne est née en 1896 sans aucune précision sur le mois ou le jour de naissance, on pourrait stocker la date 1896-00-00 dans la base. Et si l’on sait au moins qu’elle est née en juillet 1896 de stocker la date 1896-07-00.

Mais cette solution amène d’autres problèmes : Premièrement, Django, le framework qui sert à élaborer les formulaires de saisie de notre base ne permet pas la saisie de dates non « valides » et l’adaptation de Django pour ajouter cette fonctionnalité ne semble pas chose aisée (Tout du moins si l’on en juge par la question How to deal with “partial” dates (2010-00-00) from MySQL in Django? posée sur le site de questions-réponses Stack Overflow en juin 2010).

Deuxièmement, il faudrait aussi adapter Django pour l’affichage des dates incomplètes. Car une personne souhaitant consulter la base comprendra peut-être qu’une personne est née en juillet 1896 mais comprendra moins l’affichage de 1896-07-00 ou 00/07/1896.

D’autre part les requêtes dans la base ne donnent pas des résultats attendus. En partant de la table prelib_participe_collectif qui stocke les participations d’individus à des collectifs, j’ai saisi des dates d’entrées dont certaines sont incomplètes (la saisie a été faite directement dans la base avec phpMyAdmin, sans passer par Django) : 0000-05-03 (le 3 mai d’une année indéterminée ?), 1898-08-14, 1959-00-00 (l’année 1959 ?), 1959-05-00 (le mois de mai 1959 ?), 1959-06-08, 2015-08-09.

Or la requête qui devrait permettre de récupérer les dates d’entrées dans des collectifs postérieures au 16 mai 1959 ne renvoie que 1959-06-08 et 2015-08-09 :

SELECT `date_entree`
FROM `prelib_participe_collectif`
WHERE `date_entree` > ‘1959-05-16’
ORDER BY `id_participe_collectif`

Alors que la requête qui devrait permettre de récupérer les dates d’entrées dans les collectifs antérieures au 16 mai 1959 renvoie les dates 0000-05-03, 1898-08-14, 1959-00-00, 1959-05-00 :

SELECT `id_participe_collectif`, `date_entree`
FROM `prelib_participe_collectif`
WHERE `date_entree` < ‘1959-05-16’
ORDER BY `id_participe_collectif`

Cela vient du fait que 1959-00-00 reste une date et n’est pas considérée par mySQL comme l’année 1959 soit une durée entre le 1er janvier 1959 à 0h et le 31 décembre 1959 à minuit. mySQL doit probablement comparer les années (1959 = 1959) puis les mois (00 < 05) puis les jours (00 < 16) de ces deux « dates » et en déduire que 1959-00-00 < 1959-05-16.

Ce qui amène à la constatation suivante : Les « dates » incomplètes sont en fait des durées (l’année 1959, le mois de mai 1959, d’avril à juin 1959). Il faudrait donc plutôt stocker une date de début et une date de fin quand on ne connait pas la date exacte d’un événement.

A ce propos, les développeurs de l’outil de création de bibliothèques numériques CollectiveAccess sont même allés plus loin puisqu’ils stockent toutes les métadonnées temporelles décrivant un document sous forme de durées. Ainsi la date du 7 juin 2007 est stockée sous la forme des deux dates (à la seconde près) du 7 juin 2007 à 00:00:00 et du 7 juin 2007 à 24:59:59. L’avantage de cette solution est que les deux dates sont stockées dans le format SQL TIMESTAMP prévu à cet effet. On bénéficie alors de tous les avantages des requêtes sur les dates en SQL.

Ce changement de paradigme du stockage d’une date vers le stockage d’une durée change aussi les requêtes. On ne fait plus de requête pour trouver les dates d’entrées dans un collectif antérieures au 16 mai 1959 pour reprendre l’exemple précédent, mais pour trouver des intervalles de temps terminés avant l’intervalle de temps du 16 mai 1959 à 00:00:00 au 16 mai à 24:59:59 ou des intervalles de temps dans lequel le 16 mai 1959 est compris.

Que donneraient donc les requêtes SQL sur des dates uniquement stockées sous forme d’intervalles temporels ? Ne seront-elles pas trop complexes ?

Autre piste : Le stockage en RDF offre-t-il des avantages pour le stockage des dates et à quoi ressemblerai des requêtes sur des durées avec SPARQL ?