DB-MAIN - Créer un MLD et le script SQL de définition des tables
par
, 27/03/2016 à 21h49 (16286 Affichages)
_____________________________________________________________________________________________________
On a vu comment créer des entités-types et leurs associations avec DB-MAIN. Il s’agit ici de produire le MLD et le script SQL de définition des tables qui en sont issues.
(1) Situation initiale
Partons du MCD suivant, dont l’objet est la modélisation de commandes de produits par des clients de l’entreprise Dubicobit :
Pour produire un MLD à partir de ce MCD, on crée un clone de celui-ci. Pour cela, le MCD étant ouvert, dans la barre de menus on choisit « Product » et on clique sur « Copy product » :
Cette action provoque l’ouverture d’une fenêtre « Schema Properties » dans laquelle est repris le nom du MCD, avec un numéro de version + 1 (malgré les apparences, car il ne faudrait pas prendre un tiret pour un signe moins...) :
On modifie le nom du nouveau schéma, par exemple en remplaçant "Clients_MCD" par "Clients_MLD" :
Après qu’on a fait «OK », le clone Clients_MLD du MCD Clients_MCD est créé :
Après avoir cliqué sur l’ovale « Clients_MLD », on a accès au diagramme clone :
Pour obtenir une représentation graphique à la DB-MAIN du MLD, dans la barre de menus on choisit « Transform » et on clique sur « Relational model » :
(2) Représentation graphique
Au résultat, la représentation graphique a changé, la notation des associations est du type « Connect to columns », particulièrement pénible, mais on fera avec, le MLD n’étant finalement ici qu’un intermédiaire servant à la production du script SQL de création des tables :
Ce résultat est hybride. En effet, y figurent toujours des entités-types, avec leurs attributs et leurs identifiants, mais les associations ont été remplacées par des références, symbolisées par des flèches.
Une référence peut être vue comme une contrainte référentielle de la théorie relationnelle, une clé étrangère.
En ce sens, l’entité-type COMMANDE a hérité de l’attribut ClientId, identifiant de CLIENT, et à partir de cet attribut, l’AGL a défini une référence, une contrainte entre les deux entités-types : l’attribut ClientId de l’entité-type COMMANDE fait référence à l’attribut ClientId de l’entité-type CLIENT : une commande ne pourra exister que si les valeurs prises par l’attribut ClientId de l’entité-type COMMANDE sont d’abord des valeurs prises par l’attribut ClientId de l’entité-type CLIENT (on a une application de la restriction {ClientId} de COMMANDE dans la restriction {ClientId} de CLIENT). En plus de la flèche connectant CLIENT et COMMANDE, cette contrainte référentielle (cas particulier de la contrainte d’inclusion) est symbolisée par le mickey « ref: ClientId » dans le cartouche du bas.
L’entité-type LIGNE_CDE est porteuse de deux contraintes référentielles, l’une connectant LIGNE_CDE et PRODUIT, l’autre connectant LIGNE_CDE et COMMANDE. La 2e contrainte est symbolisée non pas par le mickey « ref: ClientId », mais par le mickey « equ: ClientId », traduisant la cardinalité 1,N du MCD : la projection de COMMANDE sur {CommandeId} doit être égale à la projection de LIGNE_CDE sur {CommandeId}. On a affaire à une injection.
Le cartouche du bas de chaque entité-type est pollué par le mickey « acc » : l’AGL anticipe sur le Modèle physique des données. Ainsi, chaque identifiant et chaque référence affublés de ce mickey donneront lieu à une instruction CREATE INDEX lors de la génération du script SQL. On peut bien sûr décocher la case « access key » correspondante :
(3) Toilettage avant production du script SQL
Avant de passer à la production du script SQL, dans la mesure où l’on s’est imposé des règles de codage du nom des contraintes, on aura modifié ces noms en conséquence. Ainsi, DB-MAIN propose de nommer les contraintes de clé primaire en concaténant la chaîne de caractères "ID" et le nom de l’entité-type, ce qui va peut-être à l’encontre de nos propres normes.
Exemple de l’entité-type CLIENT. La contrainte de clé primaire a pour nom ID_CLIENT :
Conformément à nos propres règles de codage du nom des contraintes, renommons-la par exemple en CLIENT_PK, nom qui sera celui de la contrainte dans l’instruction CREATE TABLE en SQL :
Même principe pour les clés alternatives. Par exemple l’AGL a donné le nom SID_CLIENT_1 à la clé alternative {ClientSiret}, renommons-la par exemple ainsi : CLIENT_SIRET_AK. Même principe pour la clé alternative {ClientIban}.
Cela vaut pour les clés étrangères. Ainsi, la contrainte référentielle liant CLIENT et COMMANDE a été nommée FKPASSER_CDE par l’AGL :
On peut préférer renommer cette contrainte en COMMANDE_CLIENT_FK :
(4) Production du script SQL
Caveat : Le script SQL est à produire à partir du MLD. En effet, si une génération est possible à partir du MCD, elle sera toutefois incomplète (absence des contraintes référentielles).
Dans la version de DB-MAIN que nous utilisons ici, la liste des SGBD cibles est réduite, on complétera manuellement ce qui manque dans le script (à savoir les paramètres physiques des tables, lesquels sont du ressort du DBA).
Quoi qu’il en soit, une fois le toilettage des noms terminé, on peut passer à la génération du script SQL de création des tables. Pour obtenir la liste des SGBD connus de l’AGL et sélectionner l’un d’entre eux, on passe par la barre de menus :
File > Generate > mon SGBD :
Evidemment, pour produire un script DB2, Oracle, ou MS SQL Server, c’est plutôt moyen, mais rappelons que le paramétrage physique est du ressort du DBA. Ce qui nous intéresse ici au 1er chef est déjà d’avoir, dans le bon ordre, les instructions CREATE TABLE et ALTER TABLE (pour les contraintes référentielles) : DB-MAIN sait faire. Maintenant, à chacun de voir quel choix de SGBD correspond au mieux (ou au moins mal...) pour le code SQL attendu.
Le résultat obtenu figure ci-dessous (on a retenu MySQL). Là encore, il y aura un travail de toilettage à faire. Par exemple, l’attribut ClientSiret de la table CLIENT a pour type BIGINT (DB-MAIN est chiche aux niveaux MCD et MLD quant aux types disponibles...) : on remplacera par DECIMAL(14). Par ailleurs, DB-MAIN a pris l’initiative de suffixer le nom des clés candidates (c'est-à-dire primaires et alternatives) par la chaîne "ID" : on effectuera un remplacement de masse de "PK_ID" par "PK" et de "AK_ID" par "AK". Même principe pour les clés étrangères, remplacer "FK_FK" par "FK".
A signaler qu’en fonction du SGBD, DB-MAIN met — ou ne met pas — en oeuvre une contrainte pour faire respecter la cardinalité 1,N définie dans le MCD, cas ici de l’association entre COMMANDE et LIGNE_CDE (une commande a au moins une ligne de commande) :
Bien entendu, les SGBD SQL du jour ne permettent pas que l’on procède ainsi. L’AGL met donc la contrainte en commentaire dans le script.alter table COMMANDE add constraint COMMANDE_PK_CHK check(exists(select * from LIGNE_CDE where LIGNE_CDE.CommandeId = CommandeId));
Script (MySQL) produit par DB-MAIN :
-- ********************************************* -- * SQL MySQL generation -- *-------------------------------------------- -- * DB-MAIN version: 9.2.b -- * Generator date: Feb 17 2014 -- * Generation date: Fri Mar 18 16:58:02 2016 -- * LUN file: D:\DBmain\developpez\clients.lun -- * Schema: Clients_MLD -- ********************************************* -- Database Section -- ________________ create database Clients_MLD; use Clients_MLD; -- Tables Section -- _____________ create table CLIENT ( ClientId int not null auto_increment, ClientNom varchar(32) not null, ClientSiret bigint not null, ClientIban varchar(27) not null, constraint CLIENT_PK_ID primary key (ClientId), constraint CLIENT_SIRET_AK_ID unique (ClientSiret), constraint CLIENT_IBAN_AK_ID unique (ClientIban)); create table COMMANDE ( CommandeId int not null, CommandeNo char(8) not null, CommandeDate date not null, ClientId int not null, constraint COMMANDE_PK_ID primary key (CommandeId), constraint COMMANDE_NO_AK_ID unique (CommandeNo)); create table LIGNE_CDE ( CommandeId int not null, ProduitId int not null, Quantite int not null, constraint LIGNE_CDE_PK_ID primary key (CommandeId, ProduitId)); create table PRODUIT ( ProduitId int not null, ProduitReference char(12) not null, ProduitLibelle varchar(32) not null, constraint PRODUIT_PK_ID primary key (ProduitId), constraint PRODUIT_REFERENCE_AK_ID unique (ProduitReference)); -- Constraints Section -- ___________________ -- Not implemented -- alter table COMMANDE add constraint COMMANDE_PK_CHK -- check(exists(select * from LIGNE_CDE -- where LIGNE_CDE.CommandeId = CommandeId)); alter table COMMANDE add constraint COMMANDE_CLIENT_FK_FK foreign key (ClientId) references CLIENT (ClientId); alter table LIGNE_CDE add constraint LIGNE_CDE_PRODUIT_FK_FK foreign key (ProduitId) references PRODUIT (ProduitId); alter table LIGNE_CDE add constraint LIGNE_CDE_COMMANDE_FK foreign key (CommandeId) references COMMANDE (CommandeId); -- Index Section -- _____________ create unique index CLIENT_PK_IND on CLIENT (ClientId); create unique index CLIENT_SIRET_AK_IND on CLIENT (ClientSiret); create unique index CLIENT_IBAN_AK_IND on CLIENT (ClientIban); create unique index COMMANDE_PK_IND on COMMANDE (CommandeId); create unique index COMMANDE_NO_AK_IND on COMMANDE (CommandeNo); create index COMMANDE_CLIENT_FK_IND on COMMANDE (ClientId); create unique index LIGNE_CDE_PK_IND on LIGNE_CDE (CommandeId, ProduitId); create index LIGNE_CDE_PRODUIT_FK_IND on LIGNE_CDE (ProduitId); create unique index PRODUIT_PK_IND on PRODUIT (ProduitId); create unique index PRODUIT_REFERENCE_AK_IND on PRODUIT (ProduitReference);
Rien n’interdit de reprendre un script avec un outil comme MySQL Workbench, d’effectuer une rétro-conception et, par exemple, de compléter avec les actions de compensation associées aux clés étrangères (CASCADE, RESTRICT, NO ACTION).
Pour visualiser le script directement dans DB-MAIN, cliquer sur le nom du fichier qui a été produit, comme ci-dessous :
Le DDL n’a pas l’air d’être modifiable dans DB-MAIN, la case « lock » reste manifestement cochée quoi qu’on fasse.
________________________________________________________________________________________________________________