RelationScript

Exemples

relation model CyberStore
import glossary model from '../glossaries/glossaries.gls'
import qa model from '../qa/relations.qas'

relation Employee(firstname_, salary, address, department)
    | All the employee in the store.
    intention
        (n, s, a, d) in Employee <=>
        | the `Employee` identified by her/his firstname <n>
        | earns <s> € per cycle. She/he lives
        | at the address <a> and works in the `Department` <d>.
    examples
        ('John', 120, 'Randwick', 'Toys')
    constraints
        dom(firstname) = String
        dom(salary) = Integer
        dom(address, department) = String
        key firstname
        firstname -> salary
        firstname -> address, department

relation Leaders(department_:String, boss:s)
    | The department leaders.
    intention
        (p, d) in Leaders <=>
        | The `Leader` of the `Department` <d> is the person <p>.
    constraints
        key department

relation Leaders2   # columns defined "vertically"
    | The department leaders.
    columns
        departement:String
        boss:String

constraints
    Leaders[department] = Employee[department]
    Leaders[boss] C= Employee[firstname]

constraint SalaryDifference
    | The difference of salary in a department must not exceed 100%.

dataset DS1
    | Employees and leaders of Alpha Super store.
    Employee
        ('John', 120, 'Randwick', 'Toys')
        ('Mary', 130, 'Wollongong', 'Furniture')
        ('Peter', 110, 'Randwick', 'Garden')
        ('Tom', 120, 'Botany Bay', 'Toys')
    Leaders
        ('John', 'Toys')
        ('Mary', 'Furniture')
        ('Peter', 'Garden')

negative dataset NDS1
    | Octavia and bookstore do not exist.
    | Violation of referential integrity constraints.
    Employee
        ('John', 120, 'Randwick', 'Toys')
        ('Mary', 130, 'Wollongong', 'Furniture')
    Leaders
        ('Octavia', 'Bookstore')

query JohnBoss(boss)
    | The department leaders.
    (Employee:(firstname='John')[department] * Leaders)[boss]

view Salaries(name_:s, salary:i)
    | The salary of each employee.
    Employee[firstname, salary]

relation LesAppartements
    transformation
        from R_Class(Appartement)
        from R_Compo(EstDans)
        from R_OneToMany(Partage)
    columns
        nom_ : String
        numero_ : Integer
        superficie : Real
        nbDePieces : Integer
        jnum : Integer
    constraints
        key nom_, numero_
        LesAppartements[jnum] C= LesJardins[jnum_]
        LesAppartements[nom_] C= LesBatiments[nom_]

RelationScript

Le langage RelationScript permet d’exprimer des “schemas” au sens du modèle relationnel.

Note

Attention, le terme “modèle de relations” ne doit pas être confondu avec le terme modèle relationnel. Un modèle de relations permet de définir des relations, tout comme un modèle de cas d’utilisation définit des cas d’utilisation, un modèle de classes définit des classes, etc. Le modèle relationnel correspond au contraire à un concept plus général. Il s’agit d’une manière de structurer et d’interroger des données.

Concepts

Le langage RelationScript est basé sur les concepts suivants :

  • les schémas, appelés modèles de relations, (relation models),
  • les relations (relations),
  • les colonnes (columns),
  • les clés et les clés étrangères (keys et foreign keys),
  • les contraintes (constraints),
  • les dépendences fonctionnelles (functional dependencies),
  • les formes normales (normal forms),
  • les jeux de données (data sets),
  • les requêtes (queries)
  • les vues (views)
  • les transformations.

Relations

Les relations peuvent être déclarées sur une seule ligne, en utilisant la notation simple que l’on trouve typiquement dans les livres ; par exemple :

R(x, y, z).

Il est également possible, et de manière tout à fait équivalente, de définir les colonnes de manière verticale (et optionellement d’ajouter le mot clé relation) :

relation R
    columns
        x
        y
        z

Clés

Dans les livres et par convention les attributs clés sont soulignés. En l’absence de soulignement des caractères ascii, en RelationScript le nom des attributs clés est suffixé par un caractère souligné “_”.

R(x_, y_, z).

Dans l’exemple ci-dessus la clé est (x,y). Dans le cas où il y aurait plusieurs clés, les attributs peuvent être suffixés. Par exemple la relation suivante possède 3 clés :

R(x_id1, y_id2_id3, z_id3, t, u).

Telle qu’elle est définie la relation possède 3 clés : < (x), (y), (y,z) >. Dans tous les cas les clés peuvent être spécifées de manière plus explicites dans la section constraints.

relation R(x, y, z)
    constraints
        key x
        key y
        key y,z

Intention

L’intention d’une relation correspond à sa signification, à la manière d’interpréter le contenu d’une relation. L’intention peut soit être implicite, soit de être définie de manière explicite et structurée. Dans l’exemple ci-dessous l’intention est implicite, la relation est définie sous forme de documentation non structurée.

relation R4(a_,c,d)
    | The list of X. This relation means that ...

Il est préférable de définir l’intention de manière structurée comme ci-dessous. Notons que dans est un mot-clé (in en anglais) et que la ligne correspondante à une structure. Le nombre de paramètres du tuple doit correspondre au nombre d’attributs de la relation. Dans le texte de l’intentation les variables doivent apparaître entre crochets (p.e. <a>)

relation R4(a_,c,d)
    | The list of X.
    intention
        (a,c,d) in R4 <=>
        | the person <a> is ... with <c> ... and <d> ...

Contraintes de domaine

Le domaine des attributs peut être défini de différentes manière comme le montre les exemples suivants :

relation R1(a,b,c,d)
    constraints
        dom(a) = String
        dom(b) = dom(c) = Date
        dom(d) = Real ?

relation R2(a:String, b:Date, c:Date, d:Real ?)

relation R3
    columns
        a : String
        b : Date
        c : Date
        d : Real ?

Un type basique suivi de de l’opérateur ? signifie que le domaine est étendu avec la valeur null. En d’autres termes cela signifie que l’attribut correspondant est optionnel.

Note

Le modèle relationnel n’autorise pas les attributs optionnels. Ces cette possibilité est offerte pour faciliter la traduction vers SQL.

Différents types de données sont définis par le langage RelationalScript. Chaque type de données possède sa propre notation abbréviée, ce qui s’avère pratique lors de la définition de relations sur une seule ligne.

Datatype Shortcut
String s
Real r
Boolean b
Integer i
Date d
DateTime dt
Time t

En utilisant la notation abbréviée une relation peut être définie comme suit :

relation LesEmployés(nom:s, prenom:s, age:i, dateNaissance: d)

Contraintes d’intégrité

Les contraintes d’intégrité (et en particulier les contraintes d’intégrité référentielle) peuvent être définies sous forme de documentation en langue naturelle.

constraint Parent
    | Les parents d'une personne doivent être
    | plus agés que cette personne, d'au moins 7 ans.

Si le modèle de relations est dérivé d’un modèle de classes, il n’est pas nécessaire de répeter le corps des contraintes qui sont simplement “héritées” ; seul le nom suffit.

constraint AuMoins7Ans

Le corps de certaines contraintes peut également être défini en utilisant l’algèbre relationnelle.

constraint FK_34h
    | The h of the relation R3 is one of the h of R4.
    R3[h] C= R4[h]

constraints
    R1[d] C= R2[d]
    R1[d1,d1] C= R2[d1,d2]
    R[X] u R[z] = {}
    R[X] n R[z] = Persons[X]

Voir la section concernant l’algèbre relationnelle pour plus de détails sur la notation utilisée.

Dépendences fonctionnelles

Les dépendances fonctionnelles et les concepts associés peuvent être définis comme suit :

relation R(a,b,c,d)
    constraints
        key a,b
        a,b -> c,d
        prime a
        prime b
        /prime c
        a -/> c
        c -ffd> d
        a -/ffd> b
        {a}+ = {a,b,c}

Formes normales

relation R(a,b,c,d)
    constraints
        3NF

Transformations

Un modèle de relations peut être obtenu par transformation à partir d’un modèle de classes. Une telle transformation peut correspondre à l’application d’une suite de règles définies dans une catalogue. Un exemple de catalogue est montré ci-dessous à titre d’illustration (télécharger).

../../_images/regles-m-cornax.png

Considérons de plus le modèle de classes ci-dessous.

../../_images/jardins-uml.png

En utilisant la règle R_Class la classe Batiment est transformée en la relation LesBatiments définie comme suit :

Note

La version française de la règle fait le renommage suivant : X devient LesXs.

relation LesBatiments
    transformation
        from R_Class(Batiment)
    columns
        nom_ : String
        capacite : Integer
    constraints
        key nom_

Remarquer la section transformation et le mot clé from. Vient ensuite le nom de la règle utilisée R_Class qui ici est appliquée à la classe Batiment. Le reste de la définition de la relation est standard.

La transformation de la classe Appartement est montrée ci-dessous à titre d’illustration.

relation LesAppartements
    transformation
        from R_Class(Appartement)
        from R_Compo(EstDans)
        from R_OneToMany(Partage)
    columns
        nom_ : String
        numero_ : Integer
        superficie : Real
        nbDePieces : Integer
        jnum : Integer
    constraints
        key nom_, numero_
        LesAppartements[jnum] C= LesJardins[jnum_]
        LesAppartements[nom_] C= LesBatiments[nom_]

Dans la section transformation ont voit que trois règles ont été appliquées :

  • la règle de transformation de classe R_Class,
  • la règle de transformation de composition R_Compo. Cette règle a été appliquée à la composition EstDans,
  • la règle R_OneToMany appliquée à l’association Partage.

Dans certains cas il est nécessaire de changer le nom de certains attributs, de fusionner deux attributs en une même colonne, etc. Certaines règles peuvent être manquantes ou doivent être appliquée de manière différente. Toutes ces modifications peut être documentées sous forme de documentation dans la section transformation.

relation LesX
    transformation
        from R1(X)
        | Le type de l'attribut z a été changé vers String car ...
        | L'attribut u a été préfixé par le nom du rôle car ...
        | ...

Requêtes

Les requêtes sont simplement des relations dont le corps est exprimé à l’aide de l’algèbre relationnelle.

query Q1(boss)
    | The department leaders
    (Employe:(firstname='John')[department] * Leaders)[boss]

Vues

Au niveau du modèle relationnel les requêtes et les vues sont en tout point équivalentes. Le concept de vue est défini ici pour simplifier la transformation vers le langage SQL.

view V1(boss)
    | The department leaders
    (Employe:(firstname='John')[department] * Leaders)[boss]

Algèbre relationnelle

Le langage RelationScript définit tous les opérateurs classiques de l’algèbre relationnelle (wikipedia). A chaque opérateur est associé une notation en ascii.

Operateur Exemple
Projection Employee[salary]
Selection Employee :( address=’Randwick’ )
Renaming L(employee, address) := Employee[firstname, address]
Cartesian product Employee x Leaders
θ join Employee * ( Employee.dept=Leaders.dept ) Leaders
Natural join Employee * Leaders
Union Employee[firstname] u Leaders[firstname]
Intersection Employee[firstname] n Leaders[firstname]
Difference Employee[firstname] - Leaders[firstname]
Empty set {}
Set inclusion Employee C= Person
Set inclusion Employee C Person
Set equality Employee = Person
Intersection Employee n Person
Union Employee u Person
Tuple (10, 3, ‘Hello)

Dépendances

Le graphe ci-dessous montre les dépendances entre langages avec un focus sur le langage RelationScript.

../../_images/language-graph-res.png