Merci François
N'hésite pas à commenter et amender si besoin le MCD proposé, ton expertise est toujours la bienvenue
Merci François
N'hésite pas à commenter et amender si besoin le MCD proposé, ton expertise est toujours la bienvenue
Bonjour Escartefigue
FSMrel
ok merci pour l'infoUn identifiant relatif est utilisé quand on a une entité-type dite "faible", c'est à dire une entité-type qui n'a d'existence qu'en présence de l'entité-type dite "forte" qui lui est associée.
Ci dessous les divers points revus
Concernant les entités Prestation, Intervention
Je pense que la prestation devrait être rattachée à une entité mission et la mission rattachée à un adresse (Celle du lieu où doit intervenir le technicien)
Je vais parler d’adresse et non plus de site intervention se sera plus simple.
Je reprends des règles déjà évoquées avec des corrections pour certaines
R008 : le contrat contient une ou plusieurs prestations
R009 : Le contrat contient une ou plusieurs interventions
Une prestation programme des interventions pour réaliser les missions suivant diverses périodicités (annuelle, mensuelle …)
Par exemple un contrôle électrique doit avoir lieu chaque année en septembre
R010 : Une prestation est rattachée à un seul contrat
R011 : Une prestation est programmée suivant une périodicité année mois
R012 : Une prestation contient une ou plusieurs interventions> à remplacer par
R012 : Une Prestation contient une ou plusieurs missions (Contrôle électrique…)
Entité Mission à créer et à rattacher à Prestation et adresse
R022 : Une ou plusieurs missions sont contenues dans une prestation
R023 : Une ou plusieurs missions peuvent être réalisés à une ou plusieurs adresses
Dans ton schéma je pense que la mission devrait être rattachée à Compétences
R024 une mission requiert un type de qualification
R025 une ou plusieurs qualifications peuvent être requise pour une plusieurs missions (règle à confirmer)
L’intervention a pour rôle d’affecter un technicien: ton schéma est correct
mais aussi de planifier le rdv avec le client en fonction de la périodicité prévue par la prestation
Une intervention concerne une seul adresse
Concernant l’entité Adresse
Adresse principale c’est uniquement pour identifier le siège social d’une société et l’adresse secondaire c’est pour un établissement secondaire de la société qui est rattaché au siège social
Par exemple le Siège social de Monoprix est à Paris mais tu as plein d’établissements secondaires dans toute la France.
La finalité étant de pouvoir dire que Monoprix à Paris et les Monoprix en province font partis d’une même société (ils ont en commun le siren et sont différenciés par des siret ou des adresses différentes)
Concernant l’entité Clients
Je ne comprends pas la cardinalité 1-1 dans l’association réflexive
En te remerciant
La notion de mission n'était pas présente jusqu'ici, à préciser.
En l'état, ma proposition n°17 est conforme au besoin car elle permet de connaître le lieu d'intervention : soit celui de l'adresse du client du contrat (du donneur d'ordre), soit, si besoin, à une autre adresse, précisée au niveau de l'intervention.
Le MCD de la réponse 17 est conforme à R008, par contre, d'après les explications précédentes, le contrat n'est pas directement en lien avec l'intervention : le contrat consiste en une ou plusieurs prestations, chaque prestation faisant l'objet d'une ou plusieurs missions. C'est ce que représente le MCD de ma réponse
En d'autres termes, les règles que j'ai appliquées sont :
R008a : le contrat inclut une à plusieurs prestations
R008b : une prestation est incluse dans un et un seul contrat
R009a : pour une prestation, on planifie une à plusieurs interventions
(ou zéro à plusieurs comme indiqué dans mon MCD n°17 si les prestations peuvent ne pas être connues lors de la souscription du contrat)R009b : une intervention est planifiée pour une et une seule prestation
Constatez que vos règles sont incomplètes car elles ne mentionnent qu'un sens de chaque association, or il faut bien mentionner chaque sens (de A vers B et de B vers A)
Le MCD proposé est conforme à cette règle : le client siège social de monoprix sera associé à une adresse de type 3 dans mon exemple, alors que les filiales seront associées à des adresses de type 1
Ce modèle indique que plusieurs clients donneurs d'ordre peuvent partager le même client payeur (coté 1,n de l'association) et qu'un client donneur d'ordre n'a qu'un et un seul client payeur (coté 1,1).
Nous verrons les autres points après Noël, je m'accorde une petite pause de quelques jours, alors bon réveillon et à très bientôt
Bonjour Escartefigue
Bon réveillon à toi aussi
Merci pour tout le travail réalisé et les explications fournies
a bientôt !
Bonsoir,
C'est jouable si un client peut être à la fois donneur d'ordre et payeur, à savoir si on pratique l'auto-référence.
D'un point de vue technique. En SQL :
Pour créer les clients :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 CREATE TABLE Client ( CliId INT IDENTITY , CliNom varchar(48) NOT NULL , CliPayeur INT not NULL , PRIMARY KEY (CliId) , FOREIGN KEY (CliPayeur) REFERENCES Client(CliId) ) ;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 insert into Client values ('Fernand', 1) , ('Raoul', 1) , ('Paul', 1)=>
Code : Sélectionner tout - Visualiser dans une fenêtre à part select * from Client ;
Fernand est ici sujet à l'auto-référence.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 CliId CliNom CliPayeur 1 Fernand 1 2 Raoul 1 3 Paul 1
Si les rôles payeur et donneur d'ordre sont exclusifs, 1,1 est à remplacer par 0,1. D'où le code :
Et pour créer les clients :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 CREATE TABLE Client ( CliId INT IDENTITY , CliNom varchar(48) NOT NULL , CliDeReference INT , PRIMARY KEY (CliId) , FOREIGN KEY (CliDeReference) REFERENCES Client(CliId) ) ;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 insert into Client values ('Fernand', NULL) , ('Raoul', 1) , ('Paul', 1)=>
Code : Sélectionner tout - Visualiser dans une fenêtre à part select * from Client ;
Bien entendu, le bonhomme NULL doit être interdit de séjour, mais il s'agit là d'un débat à part entière.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 CliId CliNom CliDeReference 1 Fernand NULL 2 Raoul 1 3 Paul 1
MDA_1602, tenez bon, courage !
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
Bonsoir FSM
Merci je m'accroche tant bien que mal car tout cela est très nouveau pour moi mais fort heureusement les échanges me permettent de mieux appréhender ce sujet.
Je débute également en SQL
Oui c'est le cas , un client peut être payeur, donneur d'ordre et site d'intervention , on est dans le cas de figure ci dessousC'est jouable si un client peut être à la fois donneur d'ordre et payeur, à savoir si on pratique l'auto-référence
Ex1: Dans un contrat tu aurais la société Pantin située à Paris (crée sous ID20) qui demande (Donneur d'ordre ID20) un contrôle pour son agence situé aussi à Paris (ID20)
Cette société (ID20) sera donc le payeur, le donneur d'ordre et le site d'intervention
Ex2 Dans un contrat tu peux indiquer deux adresses différentes pour une même société :
La société Tartanpion située à Paris (ID11) sera ton payeur mais c'est Tartanpion à Toulouse qui demande une intervention pour son agence située a Toulouse donc ici ton DO et site Intervention serait Tartanpion à Toulouse (ID10)
Question sur le code ci dessous : la création d'une FK(ADR ident_principal) faisant référence à un identifiant de la même table c'est pour matérialisé l'association réflexive adresse principale et secondaire ?
Serait il possible de me faire un cas concret ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 CREATE TABLE ADR_adresse( ADR_ident INT IDENTITY, ADR_ligne1 VARCHAR(35) NOT NULL, ADR_ligne2 VARCHAR(35), ADR_ligne3 VARCHAR(35), ADR_ligne4 VARCHAR(35), ADR_ligne5 VARCHAR(35), ADR_ident_principal INT NOT NULL, CPO_ident INT NOT NULL, VIL_ident INT NOT NULL, PRIMARY KEY(ADR_ident), FOREIGN KEY(ADR_ident_principal) REFERENCES ADR_adresse(ADR_ident), FOREIGN KEY(CPO_ident) REFERENCES CPO_code_post(CPO_ident), FOREIGN KEY(VIL_ident) REFERENCES VIL_ville(VIL_ident) );
Concernant les contacts il faudrait indiquer un identifiant relatif car un contact est toujours rattaché à un client sans client il n'a pas d'existence.
En effet pour créer un contact il faut d'abord créer le client auquel je vais rattacher au contact.
C'est bien comme ça que je l'avais compris et modélisé, donc tout va bien
Par contre, c'est sans rapport avec l'héritage : dans mon MCD, le client est donneur d'ordre non pas parce qu'il est de tel ou tel sous-type, mais seulement parce qu'il a souscrit au moins une commande.
De même, il est client payeur uniquement parce qu'il est référencé en tant que tel (FK CLI_ident_payeur) dans la table des clients.
Oui, c'est bien l'association reflexive qui crée cette FK, mais comme indiqué plus haut, je pense que cette notion d'adresse principale et secondaire n'a plus de sens :
Soit l'adresse du chantier est l'adresse du client donneur d'ordre auquel cas, il suffit d'utiliser l'adresse de ce client
Soit l'adresse du chantier est particulière, auquel cas on crée une occurrence d'adresse en lien avec la prestation.
C'est la raison pour laquelle, contrairement à mon premier MCD, l'adresse n'est plus identifiée relativement au client : elle est associée soit au client, soit à la prestation.
Sauf si une même personne peut être contact de plusieurs clients (cas d'espèce : le mandataire), auquel cas l'identification absolue est requise. Qu'en est-il dans votre cas ?
Passons donc à un exemple simple et concret. On a des clients, des factures et des lignes de facture. SGBD : SQL Server.Envoyé par MDA
Pour ne pas être empoisonnés pendant les tests, commençons par virer les tables correspondantes :
Créons la table Client :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 drop table if exists LigneFacture ; drop table if exists Facture ; drop table if exists Client ; go
Y a du métabolisme dans cette affaire... En effet, pour interdire la suppression d’un client payeur auquel sont rattachés des donneurs d’ordre, pour la clé étrangère, on code "on delete no action". Si aucun donneur d’ordre n’est rattaché, pas de problème, on peut supprimer un payeur.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 CREATE TABLE Client ( ClientId INT IDENTITY , ClientNom varchar(48) NOT NULL , ClientPayeur INT not NULL , PRIMARY KEY (ClientId) , FOREIGN KEY (ClientPayeur) REFERENCES Client(ClientId) on delete no action ) ; go
Quelques payeurs
Quelques donneurs d'ordres
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 insert into Client values ('Fernand', 1) , ('Antoine',2) Go
Au résultat :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 insert into Client values ('Raoul', (select ClientId from client where ClientNom = 'Fernand')) , ('Paul', (select ClientId from client where ClientNom = 'Fernand')) Go
=>
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 select * from Client ; Go
Notez l'auto-référence concernant Fernand et Antoine.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 ClientId ClientNom ClientPayeur 1 Fernand 1 2 Antoine 2 3 Paul 1 4 Raoul 1
Passons aux factures :
Quelques factures :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 create table Facture ( FactureId int identity , FactureNumero int not null , FactureLibelle varchar(64) not null , FactureClient int not null , primary key (FactureId) , foreign key (FactureClient) references client on delete no action ) ;
Au résultat :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 insert into Facture values ( 1234 , 'ma participation' , (select ClientId from Client where ClientNom = 'Fernand') ) , ( 314116 , 'entretien de la maison' , (select ClientId from Client where ClientNom = 'Fernand') ) , ( 98765 , 'whisky supérieur' , (select ClientId from Client where ClientNom = 'Raoul') ) ; Go
=>
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 select FactureNumero , FactureLibelle , ClientNom from Client join Facture on Client.ClientId = Facture.FactureClient go
Passons aux lignes de facture :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 FactureNumero FactureLibelle ClientNom 1234 ma participation Fernand 314116 entretien de la maison Fernand 98765 whisky supérieur Raoul
Pour en revenir au métabolisme des données, comme une ligne de facture n’est jamais qu’une propriété d’une facture, la suppression d’icelle entraîne celle de ses lignes, d’où le "on delete cascade".
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 create table LigneFacture ( FactureId int not null , LigneFactureId int not null -- , LigneFactureNumero int not null , LigneFactureLibelle varchar(64) not null , primary key (FactureId, LigneFactureId) , foreign key (Factureid) references Facture on delete cascade ) ; go
Quelques lignes de facture :
Voyons voir :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 insert into LigneFacture values ( (select factureid from facture where FactureNumero = 98765) , 1 , 'achat de verres' ) , ( (select factureid from facture where FactureNumero = 314116) , 1 , 'ravalement du mur' ) , ( (select factureid from facture where FactureNumero = 314116) , 2 , 'peinture du plafond' ) ;
=>
Code : Sélectionner tout - Visualiser dans une fenêtre à part select * from LigneFacture ;Supprimons la facture 98765 de Raoul :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 FactureId LigneFactureId LigneFactureLibelle 2 1 ravalement du mur 2 2 peinture du plafond 3 1 achat de verres
La table LigneFacture ne fait plus mention de cette facture :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 delete from Facture where factureid = (select FactureId from Facture where FactureNumero = 98765) ;
=>
Code : Sélectionner tout - Visualiser dans une fenêtre à part select * from LigneFacture ;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 FactureId LigneFactureId LigneFactureLibelle 2 1 ravalement du mur 2 2 peinture du plafond
MDA, do you follow me ?
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
Bonsoir Escartefiguer et FSMRel
Piouf beaucoup d'information pour mon pauvre petit cerveau !
ok avec çaPar contre, c'est sans rapport avec l'héritage : dans mon MCD, le client est donneur d'ordre non pas parce qu'il est de tel ou tel sous-type, mais seulement parce qu'il a souscrit au moins une commande.
Normalement un client devient payeur lorsqu'il est référencé sur une factureDe même, il est client payeur uniquement parce qu'il est référencé en tant que tel (FK CLI_ident_payeur) dans la table des clients.
Oui ça peut être un cas de figure > Adr chantier = Donneur d'ordreSoit l'adresse du chantier est l'adresse du client donneur d'ordre auquel cas, il suffit d'utiliser l'adresse de ce client
cela peut être aussi un cas de figure > adr chantier ≠ donneur d'ordre ≠ lieu payeurSoit l'adresse du chantier est particulière, auquel cas on crée une occurrence d'adresse en lien avec la prestation
Oui tout à fait un contact peut être associé à plusieurs clients, plusieurs clients peuvent avoir le même contact.Sauf si une même personne peut être contact de plusieurs clients (cas d'espèce : le mandataire), auquel cas l'identification absolue est requise. Qu'en est-il dans votre cas ?
ok let's check If I follow youMDA, do you follow me ?
Donc j'ai une table client ou l'ID client = Id client payeur > donc il est DO et Lieu payeur à la fois (client unique)
si Id client différent de Id client payeur > le client DO a un lieu payeur différent (deux client distincts)
C'est bien cela ?
Autre point sur la table facture :
Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 create table Facture ( FactureId int identity , FactureNumero int not null , FactureLibelle varchar(64) not null , FactureClient int not null , primary key (FactureId) , foreign key (FactureClient) references client on delete no action ) ;
Dans cette table je ne comprend pas l'attribut "factureClient" : est ce une colonne créé pour servir de clé étrangère qui serait l'Id client de la table client ?
la FK fait référence à l'id client ou à tout la table client ?
Dans Insert tu as inséré dans la colonne facture Client un "select ClientId from Client where ClientNom = 'Fernand'" > c'est pour rechercher le payeur de la table client ?
Première fois que je vois ça dans un insert
Pour les lignes de factures va falloir que je relise plusieurs fois , j'aurai certainement des questions
Merci à vous deux
Ce que je veux dire, c'est que le client est déclaré comme payeur dès qu'un lien payeur est établi au travers de la relation reflexive entre ce client et au moins un autre ou lui-même
La facture ne sera établie vers ce client que justement parce que ce lien existe (c'est comme ça qu'on sait vers quel client émettre la facture)
Stricto sensu, ce client deviendra effectivement payeur quand il aura réglé le montant d'une facture au moins
OK, du coup, on peut bel et bien supprimer la relation réflexive entre adresses
Ce faisant, pas d'identification du contact relativement au client, mais une identification absolue
Je me permets de répondre aux points ci-dessous, bien que les propositions de François en soient à l'origine, il complètera si besoin
Oui
Tout à fait, du fait de la cardinalité 1,1 de facture vers client (une facture concerne un et un seul client), au stade SQL, l'identifiant du client devient clef étrangère de la table facture.
On ne connait souvent qu'un identifiant fonctionnel tel que le numéro de facture ou le numéro de client, rarement l'identifiant technique servant de clef primaire.
La méthode proposée par François est donc très classique pour retrouver l'identifiant technique unique requis lors de l'insertion à partir d'un identifiant fonctionnel, unique lui aussi.
Cette même méthode peut bien évidement être également utilisée dans d'autres cas de figure (recherche de lignes par SELECT, modification de lignes...)
Sur ce point, il faut garder à l'esprit la notion d'entité-type "faible" : ce type d'entité ne peut exister sans l'entité-type forte dont elle dépend.
Ici, l'entité-type forte est la facture, la faible est la ligne de facture : une ligne de facture sans sa facture n'a pas de sens.
D'où la préconisation de François d'utiliser l'instruction ON DELETE CASCADE qui est une option de la déclarative FOREIGN KEY.
Cette instruction garantit que la suppression de l'entête facture supprimera également toutes ses lignes associées portant le même identifiant de facture.
Seul le SGBD peut garantir à 100% ce type d'action, en effet, dans un environnement multi-utilisateur, les accès concurrents font que l'application ne peut faire aussi bien de façon certaine.
Notez qu'il existe d'autres options possibles (ON DELETE NO ACTION, ON DELETE RESTRICT, ON DELETE SET NULL...), mais là on s'éloigne fortement du stade conceptuel
Ok je comprends mieux cete insert version selectOn ne connait souvent qu'un identifiant fonctionnel tel que le numéro de facture ou le numéro de client, rarement l'identifiant technique servant de clef primaire.
La méthode proposée par François est donc très classique pour retrouver l'identifiant technique unique requis lors de l'insertion à partir d'un identifiant fonctionnel, unique lui aussi.
Cette même méthode peut bien évidement être également utilisée dans d'autres cas de figure (recherche de lignes par SELECT, modification de lignes...)
Merciiii
Question : quand tu veux empêcher la suppression d'un client identifié dans une commande tu créé quelle contrainte ?
Je vais préparer un nouveau MCD avec ce que tu as déjà conçu afin d'y rajouter les missions , un catalogue matériel et la facturation;
Avec les contraintes FOREIGN KEY
- on peut vérifier l'absence de FK dépourvues des valeurs de PK correspondantes : par exemple vérifier qu'on ne peut pas avoir de commandes ayant pour identifiant client un client qui n'existe pas.
Cette vérification est opérée par l'instruction CONSTRAINT ... FOREIGN KEY ... REFERENCES.- on peut supprimer automatiquement les lignes enfant rattachées à un parent qu'on supprime par DELETE : par exemple, si on supprime le client, on supprime toutes ses commandes
Cette suppression est opérée par l'instruction ON DELETE CASCADE de la déclarative FOREIGN KEY.
Cette cascade peut opérer sur plusieurs niveaux : le client supprime ses commande, chaque commande supprime ses lignes de commande...- on peut propager la mise à jour d'une valeur de PK dans toutes les occurrences de FK qui lui sont rattachées
Cette propagation est opérée par l'instruction ON UPDATE CASCADE de la déclarative FOREIGN KEY.
Là encore, la propagation peut opérer sur plusieurs niveaux- on peut interdire la suppression d'une ligne parente qui possède encore des lignes enfant
Cette interdiction est opérée par l'instruction ON DELETE RESTRICT ou ON DELETE NO ACTION de la déclarative FOREIGN KEY.
Attention : les instructions supportées (on delete, on update) dépendent du SGBD
Bonjour,
En phase avec Le Capitaine Escartefigue :Envoyé par MDA
Si la table des commandes est dotée d’un attribut faisant référence à la table dont la clé primaire est constituée de l’identifiant de la table des clients, cette table des commandes est à pourvoir d’une clé étrangère ad-hoc (on delete no action).
Exemple :
Ainsi, le SGBD interdira la suppression d'un client référencé par au moins une commande.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 create table Commande ( CommandeId int identity , CommandeNumero int not null , CommandeLibelle varchar(64) not null , CommandeClient int not null , primary key (CommandeId) , foreign key (CommandeClient) references Client on delete no action ) ; Go
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
Attention à bien expliquer le rôle des nouveaux acteurs (notamment les "missions" qui pour l'instant restent obscures pour moi) et à communiquer les règles de gestion pour justifier chaque "patte" des nouvelles associations.
Quelques exemples sont souvent les bienvenus pour éclairer le propos
Pour compléter mon précédent message :
Exemple d’infraction :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 insert into Commande values ( 123 , 'ma commande de whisky' , (select ClientId from Client where ClientNom = 'Raoul') ) ; Go
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 select * from Commande ; Go
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 CommandeId CommandeNumero CommandeLibelle CommandeClient 1 123 ma commande de whisky 4SQL Server rejette la requête :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 delete from client where ClientNom = 'Raoul' ; Go
L'instruction DELETE est en conflit avec la contrainte REFERENCE "FK_Commande_Client".
Le conflit s'est produit dans la base de données "clients", table "dbo.Commande", column 'CommandeClient'.
QED
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
Beaucoup de mal à comprendre cette table reflexiveCe que je veux dire, c'est que le client est déclaré comme payeur dès qu'un lien payeur est établi au travers de la relation reflexive entre ce client et au moins un autre ou lui-même
La facture ne sera établie vers ce client que justement parce que ce lien existe (c'est comme ça qu'on sait vers quel client émettre la facture)
Qu'est ce que tu appelles déclaré comme payeur ?
Comment l'id client payeur trouve sa valeur ?
Est ce qu'il est possible dans cette table qu'une société X créé sous ID client 100 puisse être créé une deuxième fois sous l'Id payeur 101 alors même que c'est la même société ?
Concernant les FK :
Donc dans la table commande j'ai une FK qui fait référence à l'ID client de la table clients, si je veux ajouter un client à ma cde il faut que celui ci ait été créé au préalable dans ma table client.
Donc on est sur une Entité faible la table cde car celle ci dépendra de l'Entité forte la table client.
J'ai lu quelque part ici la notion de "Maitre - Esclave" en parlant du cas des associations de type 1-n , c'est ce que toi tu appelles Entité forte Entité faible je suppose
sinon j'ai compris ce que tu expliques sur les FK faut juste que je retienne qu'ils existent toutes ces possibilités, heureusement google est mon ami !
FSM merci pour les exemples SQL même si je me suis arraché les cheveux à comprendre notamment sur le fait que les FK ne sont pas nommées comme les PK
select
FactureNumero
, FactureLibelle
, ClientNom
from Client join Facture on Client.ClientId = Facture.FactureClient > ICI j'aurai compris si tu avais mis " from Client join Facture on Client.ClientId = Facture.ClientID
Un client est déclaré payeur s'il existe une association réflexive d'un client vers ce client.
Voici un exemple de contenu de la table des clients (dans laquelle j'ai ajouté une colonne nom, pour faciliter la lecture)
Dans cet exemple, le client "Ducran, Lapoigne et Cie" payera les factures pour lui même et pour le client "Gaston SARL", et le client "Prunelle" payera lui même ses factures.
Quand on devra facturer un chantier dont le donneur d'ordre est Gaston SARL, on ira rechercher son client payeur dans la table client, et comme ce client payeur est "Ducran, Lapoigne et Cie", le traitement de facturation émettra la facture à ce nom et l'enverra à l'adresse de facturation associée à ce client payeur. Bien entendu, la facture mentionnera aussi la commande du client "Gaston SARL" justifiant cette facture.
Non : il ne faut jamais créer de redondance dans une base de données.
Par contre, je ne pense pas qu'on puisse récupérer la valeur de l'identifiant attribué par le SGBD avant qu'il ait été créé (et donc effectivement inséré) ce faisant, le marquage "not null" du client payeur est bloquant si le payeur est le client qu'on est en train de créer.
Pour résoudre ce dilemme, il faut dans un premier temps créer le client par INSERT sans valoriser son client payeur, puis, récupérer l'identifiant nouvellement créé (fonction SCOPE_IDENTITY() avec SQL server, LAST_INSERT_ID() avec MySQL...) pour mettre à jour la colonne CLI_ident_payeur de ce client
On peut en effet considérer la commande comme une entité-type faible du client, mais en ce cas, elle devra être identifiée relativement au client
Au niveau conceptuel, on notera donc [CLIENT] 1,n --- (souscrire) --- (1,1) [CONTRAT]
Et au niveau SQL, la PK de la table CTR_contrat sera CLI_ident# + un numéro de séquence
Je ne connais pas cette expression dans ce contexte
Il faut surtout retenir que tout SGBD relationnel digne de ce nom garantit l'intégrité des données.
Les instructions que j'ai mentionnées relativement aux FK explique comment le faire, mais ça c'est un point de détail qu'on trouve facilement dans la doc spécifique à chaque SGBD
Bonjour,
MDA, pour la nième fois, une entité-type faible F est une propriété d’une autre entité-type E. Du point de vue sémantique, la suppression d’une instance de E entraîne la suppression des instances de F, ce qui d’un point de vue concret (SQL) se traduit par l’option "on delete cascade". A l’inverse, coder "on delete no action" signifie que F ne peut pas être perçue comme une entité-type faible. MDA, si pour vous l’entité-type Commande est faible par rapport à l’entité-type Client, cela signifie en réalité qu’une commande ne peut en rien s’opposer à la destruction du client auquel elle se rattache, ce qui la conduit donc elle aussi à sa propre destruction. Je ne pense pas que la maîtrise d’ouvrage appréciera cette idée. Même punition concernant les factures : en l’occurrence seuls les clients ne trouveront rien à redire du fait de ne plus devoir le moindre sou...Envoyé par Le Capitaine
Quant à l’identification relative c’est certes un plus au plan sémantique, mais non déterminant : elle permet de mieux faire comprendre la nature des relations entre entités-types, mais là encore, c’est au stade concret (SQL) qu’elle joue un rôle capital comme l’a très bien rappelé Le Capitaine (effet cluster décisif pour la performance des applications).
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
La suppression d'un client comme celle d'une commande sont des choses exceptionnelles, à la rigueur on les archive, mais on ne les supprime pas, encore moins si des factures s'y rapportent.
Toutefois, si l'on devait supprimer le client, il me semble cohérent de supprimer les commandes qui en dépendent, une commande sans client n'ayant pas de sens.
C'est à ce titre que considérer la commande comme une entité-type faible du client m'apparait cohérente. Qu'en dis tu ?
Les grands maîtres de la modélisation conceptuelle des données, tels Tabourier ou Nanci (RIP), ne sont pas bien bavards quant à la faiblesse des entités-types. Je te renvoie à ce qu’en dit qu’en dit Nanci dans Ingénierie des systèmes d'information.Envoyé par escartefigue
Voir le paragraphe II-D-3-c-i. Le choix de la relation-type
Pou ma part, je considère qu’il n’y a pas d’absolu : une entité-type peut être « en même temps » forte et faible. Ainsi l’entité-type Commande est faible par rapport à l’entité-type Client, mais elle est forte par rapport à l’entité-type LigneDeCmmande...
(a) Faites simple, mais pas plus simple ! (A. Einstein)
(b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
=> La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)
__________________________________
Bases de données relationnelles et normalisation : de la première à la sixième forme normale
Modéliser les données avec MySQL Workbench
Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager