• Aucun résultat trouvé

5.2 Le virage du NoSQL

6.1.3 Contraintes d’attributs

Étant donnée une clause entité ENTITY(CONSTRAINT) (syntaxe 1), la sous-clause de contrainte CONSTRAINT peut prendre diverses formes complexes. Cette partie aborde les contraintes d’at-tributs qui en sont la forme la plus simple et qui, comme leurs noms l’indiquent, permettent de spécifier des contraintes portant sur les valeurs des attributs de l’entité désignée par la sous-clause ENTITY.

6.1.3.1 Syntaxe simplifiée

La syntaxe de base permettant de construire une contrainte d’attribut est la suivante :  Syntaxe 2 (Contrainte d’attribut atomique) :

Une expression de la forme :

BLOCK1 COMPARATOR BLOCK2 est une contrainte d’attribut d’une entité ENTITY lorsque :

1. elle est utilisée au sein de la clause de contrainte d’une clause entité d’entité ENTITY ENTITY( ... BLOCK1 COMPARATOR BLOCK2 ... )

2. les blocs BLOCK1 et BLOCK2 sont au choix :

— une valeur de type numérique, chaîne de caractère ou date ; — un libellé identifiant un attribut particulier d’une entité. 3. le comparateur COMPARATOR est un comparateur de la Table 6.1.

> Remarque 7 :

En réalité, cette syntaxe est un cas particulier de la syntaxe 3 p. 136. Par souci de clarté, la syntaxe ici présentée est cependant prise comme support d’explication dans un premier temps.

Dans la pratique, une clause entité ENTITY(CONSTRAINT) dont la sous-clause CONSTRAINT se résume à une contrainte d’attribut atomique est donc de la forme :

ENTITY(BLOCK1 COMPARATOR BLOCK2)

Un libellé d’attributs est intrinsèquement typé. Par exemple, l’attribut date_naissance de l’entité patient est intrinsèquement du type date. Même si d’un point de vue purement syntaxique cela ne représente pas une nécessité, une contrainte d’attribut n’est cohérente qu’à condition que les deux sous-clauses BLOCK1 et BLOCK2 soient du même type. Le comparateur COMPARATOR peut alors correspondre à n’importe quel comparateur introduit dans la Table 6.1 et disponible pour le type de données commun à ces deux blocs. De même, lorsque qu’un bloc d’une expression du type ENTITY(BLOCK1 COMPARATOR BLOCK2) désigne un attribut d’entité, cette expression ne prend de sens que si l’attribut en question est un attribut de l’entité dési-gnée par ENTITY.

Deux cas de figures peuvent dans la pratique se présenter. Si dans une clause entité ENTITY(BLOCK1 COMPARATOR BLOCK2):

— BLOCK1 (resp. BLOCK2) désigne un attribut de l’entité ENTITY et que BLOCK2 (resp. BLOCK1) est une valeur typée alors cette clause entité dans son ensemble permet de cibler l’ensemble des entités de type ENTITY dont l’attribut en question (i.e. BLOCK1 (resp. BLOCK2)) vérifie une contrainte relativement à une valeur fixe (i.e. BLOCK2 (resp. BLOCK1)).

¸ Exemple 8 (contraintes attribut-comparateur-valeur) :

La contrainte sexe = "F" permet de spécifier une valeur à l’attribut sexe de l’entité patient. La clause entité patient(sexe = "F") désigne alors l’ensemble des patients de sexe féminin. Dans cette contrainte, relativement à la syntaxe 2 :

sexe est un libellé d’attribut unique constituant le bloc BLOCK1;

= constitue le COMPARATOR (comparateur d’égalité entre deux chaînes de caractère) ; "F" est une valeur de type « chaîne de caractère » constituant le bloc BLOCK2. Le même type de contrainte peut être construite avec les types de données Date et

Numérique. Par exemple la clause entité sejour(date_entree = 2006-09-05) dé-signe l’ensemble des séjours dont la date d’entrée est le 5 Janvier 2006 (comparaison de deux dates). De même, la clause entité analyse_biologique(valeur > 3.5) dé-signe l’ensemble des analyses biologiques dont la valeur de l’analyse est supérieure à 3.5 (comparaison de deux numériques).

— BLOCK1 et BLOCK2 désignent tous deux un attribut de l’entité ENTITY alors la clause entité dans son ensemble permet de sélectionner les entités de type ENTITY dont la valeur du premier attribut (i.e. BLOCK1) vérifie une contrainte relativement à celle de l’autre (i.e. BLOCK1).

¸ Exemple 9 (contraintes attribut-comparateur-attribut) :

La clause entité analyse_biologique(valeur < borneInf) désigne les analyses dont le résultat est inférieur à la borne inférieure et donc l’ensemble des analyses qui sont « anormalement basses ». Les deux blocs valeur et borneInf de la contrainte de cette clause entité désignent tous deux des attributs de l’entité analyse_biologique. La contrainte de cette clause entité prend donc la forme d’une comparaison entre deux attributs d’entité de type numérique.

6.1.3.2 Multi-valuation

Lorsqu’il est nécessaire de multi-valuer la valeur d’un attribut d’entité, il est possible de le faire en concaténant l’ensemble des valeurs en question et en les séparant par une virgule « , ». La multi-valuation d’une valeur s’apparente à un « OU » logique. En d’autre termes, lorsque dans une contrainte d’attribut une valeur multi-valuée est assignée à un attribut, la clause entité contenant cette contrainte désigne alors l’ensemble des entités dont l’attribut vérifie la contrainte avec au moins une des valeurs présente dans la multi-valuation.

¸ Exemple 10 (multi-valuation) :

patient(prenom="Jacques","Jean","Daniel") désigne l’ensemble des patients dont le prénom est « Jacques » ou bien « Jean » ou encore « Daniel ». Il est également possible de multi-valuer une valeur de type date (sejour(date_entree=2010-01-01,2010-01-02)) ou une valeur de type numérique (analyse_biologique(valeur=1.1,2.2,3.3))

6.1.3.3 Expressions arithmétiques

Les blocs peuvent également prendre la forme d’expressions arithmétiques pour créer des contraintes plus évoluées. Ces expressions arithmétiques sont alors construites en composant des attributs et des valeurs de même type par l’intermédiaire des opérateurs arithmétiques disponibles pour ce type de données commun (cf. Table 6.1). Deux exemples sont donnés ci-dessous :

¸ Exemple 11 :

La clause entité sejour(date_sortie - date_entree >= 10.0) désigne l’ensemble des séjours dont la durée est supérieure ou égale à 10 jours. La contrainte considérée dans cet exemple est donc date_sortie - date_entree >= 10.0 dans laquelle :

— le bloc date_sortie - date_entree de cette dernière se présente sous forme d’une expression arithmétique effectuant la soustraction de deux dates et permet d’évaluer la différence en jour entre la date d’entrée et la date de sortie d’un séjour ;

— le deuxième bloc (le bloc 10.0) est une simple valeur numérique ;

— « >= » est quant à lui le comparateur « supérieur ou égal à » permettant de comparer deux numériques.

¸ Exemple 12 :

La contrainte considérée dans cette exemple est la suivante : date_sortie - date_entree >= 10.0

Le bloc date_sortie - date_entree de cette dernière se présente sous forme d’une expres-sion arithmétique effectuant la soustraction de deux dates et permet d’évaluer la différence en jour (cf. remarque 6 p. 133) entre la date d’entrée et la date de sortie d’un séjour. Le deuxième bloc (le bloc 10.0) est une simple valeur numérique. « >= » est quant à lui le comparateur « supérieur ou égal à » permettant de comparer deux numériques. En somme, La clause entité sejour(date_sortie - date_entree >= 10.0) désigne l’ensemble des séjours dont la durée est supérieure ou égale à 10 jours.

¸ Exemple 13 :

Dans la clause entité analyse_biologique(valeur > 2*borneSup), la contrainte est consti-tuée d’un bloc de gauche se résumant à l’attribut valeur de l’entité analyse_biologique, d’un comparateur de numérique (>) et d’une expression arithmétique comme bloc de droite. Cette dernière correspondant au double de la borne supérieure de l’analyse biologique. La clause entité dans son ensemble désigne l’ensemble des analyses biologiques dont le résultat est deux fois supérieur à la normale.

6.1.3.4 Syntaxe générique

Le langage de requête accepte en réalité des contraintes suivant une syntaxe plus générique que la syntaxe 2. Une contrainte peut contenir plusieurs blocs de même type séparés par des comparateurs en suivant la syntaxe :

 Syntaxe 3 :

Dans sa forme la plus générique, une contrainte d’attribut est de la forme : BLOCK1 COMPARATOR12 BLOCK2 COMPARATOR23 BLOCK3 ... BLOCKn

En réalité, comme il le sera précisé dans la suite les possibilités qu’offre cette syntaxe ne sont pas indispensables en terme d’expressivité du langage car l’utilisation d’opérateurs Booléens permet de construire des requêtes équivalentes. Cependant elle permet dans certains cas une plus grande lisibilité et une écriture des requêtes plus naturelle comme il l’est illustré dans l’exemple suivant :

¸ Exemple 14 (syntaxe générique) :

Pour récupérer l’ensemble des analyses biologiques ayant un résultat normal, il est possible d’utiliser la clause entité :

analyse_biologique(borneInf<=valeur<=borneSup)

Cette dernière est cependant équivalente à la conjonction des deux clauses entités analyse_biologique(borneInf<=valeur)

et

analyse_biologique(valeur<=borneSup)

6.1.3.5 Opérateurs Booléens

L’utilisation des opérateurs Booléens classiques « AND » et « OR » ainsi que des parenthèses (« ( » et « ) ») au sein de la sous-clause de contraintes d’une clause entité est possible. Ils

permettent de lier logiquement plusieurs contraintes que ce soit des contraintes d’attribut ou des contraintes sémantiques comme il le sera expliqué dans la sous-section 6.1.4.

> Remarque 8 (priorité des opérations) :

Les priorités classiques des opérations avec l’aide des opérateurs Booléens et des paren-thèses sont évidement respectées. Ainsi les opérations entre parenparen-thèses prévalent sur les opérateurs AND et OR et l’opérateur AND prévaut sur l’opérateur OR.

Voici quelques exemples illustrant cette possibilité dans le cadre de l’utilisation de contraintes d’attribut :

¸ Exemple 15 (usage du AND et du OR) : La requête :

patient(

sexe="F" AND date_naissance<=1970-01-01 OR sexe="M" AND date_naissance<= 1975-01-01) permet de désigner l’ensemble des patients qui sont :

— soit de sexe féminin et nés avant le 1er janvier 1970 — soit de sexe masculin et nés avant le 1er janvier 1975 .

¸ Exemple 16 (contraintes parenthésées) : La requête :

analyse_biologique( date>=2010-01-01

AND (valeur<borneInf OR valeur>borneSup))

désigne l’ensemble des analyses biologiques ayant eu lieu après le 1er janvier 2010 et dont le résultat est « anormal » (i.e. « anormalement bas » ou « anormalement haut »).

> Remarque 9 (Expressions arithmétiques et opérateurs Booléens) :

La syntaxe générique syntaxe 3 peut simplement s’exprimer à l’aide de l’opérateur Booléen AND. Par exemple, si l’on reprend l’exemple 14 on a l’équivalence logique :

analyse_biologique(borneInf<=valeur<=borneSup) ⇔

analyse_biologique(borneInf<=valeur AND valeur<=borneSup)

> Remarque 10 (Multi-valuation de valeurs et opérateurs Booléens) :

La multi-valuation de la valeur d’un attribut est équivalente à l’utilisation de l’opérateur Booléen OR. En effet, si l’on reprend l’exemple 10, on a l’équivalence logique :

patient(prenom="Jacques","Jean","Daniel") ⇔

De même que :

patient(prenom="Jacques","Jean","Daniel" AND nom="Bernoulli") ⇔

patient((prenom="Jacques" OR prenom="Jean" OR prenom="Daniel") AND nom="Bernoulli")

En plus des opérateurs Booléens OR et AND, le langage de requête permet l’exploitation de l’opérateur Booléen NOT. Ce dernier ne peut cependant être utilisé qu’uniquement devant une clause entité et constitue donc davantage un élément de syntaxe d’une clause entité qu’un opérateur Booléen à part entière :

 Syntaxe 4 (négation d’une clause entité) :

Étant donnée une clause entité ENTITY(CONSTRAINT), la négation de cette clause entité est l’expression de la forme :

NOT ENTITY(CONSTRAINT)

La négation NOT ENTITY(CONSTRAINT) d’une clause entité désigne et/ou cible l’ensemble des entités de type ENTITY qui ne sont pas désignés/ciblés par la clause entité ENTITY(CONSTRAINT).

Ainsi, de manière ensembliste, si l’on note :

— EENTITY l’ensemble contenant toutes les entités de type ENTITY ;

— EENTITY(CONSTRAINT) l’ensemble des entités de type ENTITY désignées par la clause entité ENTITY(CONSTRAINT);

— ENOT ENTITY(CONSTRAINT) l’ensemble des entités de type ENTITY désignées par la négation de la clause entité ENTITY(CONSTRAINT).

alors :

ENOT ENTITY(CONSTRAINT) = ∁EENTITYEENTITY(CONSTRAINT)

= EENTITY(CONSTRAINT)

= EENTITY\ EENTITY(CONSTRAINT)