Transformation des associations 1:1

Objectifs

  • Savoir intégrer des associations 1:1 dans des relations ;

  • Savoir préserver l'unicité de l'association.

Mise en situation

Supposez que vous modélisiez un monde où chaque citoyen, à la naissance, obtient une carte d'identité. En modèle conceptuel, la carte d'identité et le citoyen sont des classes bien différentes, et comme une carte d'identité ne peut appartenir qu'à un seul citoyen et inversement, vous utiliserez une association 1:1.

Au moment de passer au modèle relationnel, il pourrait être tentant de traiter cette association 1:1 comme une association 1:N, et de référencer la carte d'identité comme clé étrangère de la relation citoyen, par exemple.

Mais comment exprimer le fait qu'une carte d'identité n'appartient qu'à un citoyen ? C'est ce que vous allez découvrir dans ce module.

Méthode

La solution la plus simple et la plus générale pour transformer une association 1:1 consiste à traiter cette association 1:1 comme une association 1:N, puis à ajouter une contrainte UNIQUE sur la clé étrangère pour limiter la cardinalité maximale à 1.

@startumlskinparam defaultFontName Inconsolataskinparam classFontStyle boldskinparam linetype orthohide circleclass Classe1 {a : type {unique}b : type}class Classe2 {c : type {unique}d : type}Classe1 "1"-right-"1" Classe2: association@enduml
1
Table1 (#a, b, c=>Table2) avec c UNIQUE NOT NULL
2
Table2 (#c, d)
3
4
Table1(#a, b)
5
Table2(#c, d, a=>Table1) avec a UNIQUE NOT NULL

Remarque

Si la cardinalité minimale est 1..1 on ajoute la contrainte « UNIQUE NOT NULL ».

Exemple

DescriptionInformations[1]

@startuml

skinparam defaultFontName Inconsolata

skinparam classFontStyle bold

skinparam linetype polyline

skinparam nodesep 100

hide circle

class Hotel {

nom : string {unique}

adresse : string

codePostal : string

ville : string

étoiles : integer

}

class Restaurant {

nom : string {unique}

étoiles : integer

}

class Bar {

nom : string {unique}

spécialité : string

}

Hotel "1..1" - "*" Restaurant : est-situé <

Restaurant "1..1" - "0..1" Bar : est-situé <

@enduml

1
Hotel(#nom:string, adresse:string, codePostal:string, ville:string, étoiles:integer)
2
Restaurant (#nom:string, étoiles:integer, hotel=>Hotel) avec hotel non null
3
Bar (#nom:string, spécialité:string, restaurant=>Restaurant) avec restaurant unique non null

Attention

Il existe toujours deux solutions selon que l'on choisit l'une ou l'autre relation pour accueillir la clé étrangère. Selon la cardinalité minimale, un des deux choix peut être plus pertinent.

Complément

Il est parfois possible de choisir de fusionner les deux classes au sein d'une seule relation plutôt que d'opter pour une clé étrangère.