Transformation des associations N:M

Objectif

  • Savoir intégrer des associations de type N:M dans des relations.

Mise en situation

De nombreux modèles conceptuels contiennent des associations N:M. Pensez par exemple à un système d'emprunt de bibliothèque, où chaque livre peut être emprunté par plusieurs personnes, et où chaque personne peut emprunter plusieurs livres.

Au moment de passer au modèle relationnel, une problématique forte se pose : impossible de représenter cette association en ajoutant une clé étrangère représentant le livre dans la relation personne. En effet, si cette manière de faire permet de dire quel livre a été emprunté par quelle personne, impossible de représenter le fait qu'une personne ait emprunté plusieurs livres !

Comment faire ? C'est ce que vous allez découvrir dans ce module.

Méthode

Pour chaque association de type M:N :

  • on crée une nouvelle table,

  • composée de deux clés étrangères, une vers chaque table associée aux classes liées,

  • et dont la clé primaire est la concaténation de ces deux clés étrangères.

@startumlskinparam defaultFontName Inconsolataskinparam classFontStyle boldskinparam linetype orthohide circleclass Classe1 {a : type {unique}b : type}class Classe2 {c : type {unique}d : type}Classe1 "0..N"-right-"0..N" Classe2: association@enduml
1
Table1 (#a:type, b:type)
2
Table2 (#c:type, d:type)
3
Assoc (#a=>Table1,#c=>Table2)

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

}

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

class Chef {

nom : string

prénom : string

}

Restaurant "*" - "*" Chef : cuisine-dans <

@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
Chef (#id:integer, nom:string, prénom:string)
4
Cuisine (#chef=>Chef, #restaurant=>Restaurant)

ComplémentExpressions des contraintes de cardinalité minimale

Si la cardinalité est au moins 1 (1..N) d'un côté et/ou de l'autre, alors des contraintes d'existence simultanée de tuples devront être ajoutées. Cela peut être exprimé avec des projections.

@startumlskinparam defaultFontName Inconsolataskinparam classFontStyle boldskinparam linetype orthohide circleclass Classe1 {a : type {unique}b : type}class Classe2 {c : type {unique}d : type}Classe1 "1..N"-right-"1..N" Classe2: association@enduml
1
Table1 (#a:type, b:type)
2
Table2 (#c:type, d:type)
3
Assoc (#a=>Table1, #c=>Table2)
4
Contraintes : PROJECTION(Table1,a) = PROJECTION(Assoc,a) AND PROJECTION(Table2,c) = PROJECTION(Assoc,c)

Si la cardinalité est 0..N:1..N, alors seule une des deux contraintes est exprimée.