IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Tutoriel : Gérez l'héritage des données dans une base de données Access
Par Christophe WARIN

Le , par Tofalu

0PARTAGES

3  0 
Bonjour,

Je vous propose un nouveau tutoriel concernant la notion d'héritage des données au sein des tables Access.

Plusieurs questions reviennent fréquemment sur ce forum et j'espère en avoir fait une bonne synthèse.

http://warin.developpez.com/tutoriel...onnees-access/

En termes de modélisation, une question qui revient sur les forums des différents SGBD-R est la suivante :

Comment conserver la notion d'héritage lors du passage du modèle conceptuel au modèle relationnel ?

Il n'existe pas de règle pouvant répondre à coup sûr à la problématique. Merise a bien défini des méthodes pour transformer par exemple un identifiant en clé primaire, ou bien encore une association avec des cardinalités maximales à N en une table, mais rien à ce sujet. La raison est simple : tout dépend de la structure des entités concernées par l'héritage, du volume de données mis en jeu, des requêtes attendues, des compétences du moteur, etc.

A travers ce document, je vous propose d'étudier les différentes possibilités (elles sont au nombre de trois) en détaillant les raisons qui pourraient favoriser un tel choix plutôt qu'un autre et les incidences sur le reste du développement et plus particulièrement les requêtes.
pour vos éventuelles remarques
Vous avez lu gratuitement 149 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de f-leb
Responsable Arduino et Systèmes Embarqués https://www.developpez.com
Le 02/11/2009 à 18:43
Re,

Il semblerait que le problème soit réglé en écrivant :

Code sql : Sélectionner tout
1
2
3
4
5
ALTER TABLE tblSalarie ADD CONSTRAINT Unicite CHECK ( 
( SELECT COUNT(*)=0 FROM tblIndependant WHERE tblIndependant.ID=tblSalarie.ID)) 
  
ALTER TABLE tblIndependant ADD CONSTRAINT Unicite2 CHECK ( 
( SELECT COUNT(*)=0 FROM tblSalarie WHERE tblSalarie.ID=tblIndependant.ID))

En fait quand tu écris:
Code sql : Sélectionner tout
1
2
ALTER TABLE tblSalarie ADD CONSTRAINT Unicite CHECK (  
( SELECT Count(*) FROM tblSalarie T1…
Un début d’explication serait qu’on ne sait pas trop dans quel état est la copie tblSalarie T1, non ?

Mystère…
1  0 
Avatar de f-leb
Responsable Arduino et Systèmes Embarqués https://www.developpez.com
Le 09/07/2009 à 23:32
bonsoir,

merci pour cette synthèse qui donne un nouvel éclairage sur la généralisation/spécialisation d’entités-type sous Access.
Je n’ai pas manqué (entre autres) la contrainte CHECK du paragraphe VI-C. Spécialisation sur le modèle du MCD qui va enfin m’assurer de manière infaillible l’intégrité de mes données pour un héritage(XT) de mes contacts.

Le hasard faisant bien les choses, le lecteur pourra compléter l’analyse grâce au post de cette discussion toute fraiche ici: Héritage ou pas héritage ? sur un cas particulier d’héritage où les entités filles sont associées (Tiens ! voilà une suggestion pour un éventuel futur complément/mise à jour de l’article)

En tout cas, « chapeau bas » pour la qualité de tes synthèses. J’en redemande.
0  0 
Avatar de f-leb
Responsable Arduino et Systèmes Embarqués https://www.developpez.com
Le 01/11/2009 à 21:32
Bonsoir,

J’ai un problème d’héritage.

Dans le cas d’un héritage XT, j’ai donc implanté les contraintes sur les deux tables tblSalarié et tblIndépendant (http://warin.developpez.com/tutoriel...-access/#LVI-C )

Code sql : Sélectionner tout
1
2
3
ALTER TABLE tblSalarie ADD CONSTRAINT Unicite CHECK … 
  
ALTER TABLE tblIndependant ADD CONSTRAINT Unicite CHECK
Une fois les contraintes mises en place, les insertions marchent nickel et prennent bien en compte la contrainte XT, MAIS (il y a toujours un MAIS) :

Si je supprime par exemple toutes les lignes de tblSalarie puis ensuite je commence par supprimer toutes les lignes de tblIndependant, ça coince : impossible de supprimer la dernière ligne (violation de la contrainte « Unicite »).
Ce qui est logique puisque lorsque les deux tables tblSalarie et tblIndependant sont vides, la requête :
Code : Sélectionner tout
SELECT count(*) FROM tblSalarie… + SELECT count(*) FROM tblIndependant…
retourne 0 et viole donc la contrainte « unicite ».

C’est un peu embêtant tout ça, non ? Comment pourrait-on prendre en compte ce cas particulier ?
0  0 
Avatar de Tofalu
Expert éminent sénior https://www.developpez.com
Le 02/11/2009 à 12:48
Salut

Euh, dans un modèle XT, tu ne peux pas avoir les tables independants et salariés vide, sinon, cela veut dire que tu as des intervenant qui ne sont ni independant, ni salarié. Tu ne couvres donc plus la totalité.

Il faut supprimer les intervenants en cascade, mais il se peut là aussi que la contrainte gène à voir
0  0 
Avatar de f-leb
Responsable Arduino et Systèmes Embarqués https://www.developpez.com
Le 02/11/2009 à 15:02
Citation Envoyé par Tofalu Voir le message
Euh, dans un modèle XT, tu ne peux pas avoir les tables independants et salariés vide...
Oui pardon, j’avais pris un raccourci car la suppression en cascade à partir de la table mère tblIntervenant ne résout rien : Impossible de supprimer le dernier intervenant pour la même raison.

Faut-il se résoudre à écrire un code qui supprime la règle de validation juste avant de supprimer le dernier intervenant ? (Certes, ce n’est pas très compliqué mais le phénomène est tout de même à prendre en compte).
0  0 
Avatar de Tofalu
Expert éminent sénior https://www.developpez.com
Le 02/11/2009 à 15:16
En fait, je ne comprend pas pourquoi ça le fait sur le dernier intervenant et pas sur les autres. Si ça pose soucis sur le dernier, ça devrait le poser pour tous. Tu es sûr que tu n'as pas fait une boulette quelque part ?

Tu as essayé au sein d'une transaction ?

Si le moteur considère la suppression en cascade comme non atomique, c-à-d composé des suppressions successives alors, pourquoi il ne signale rien quand on supprime un autre enregistrement que le dernier. A un moment donné, celui-ci aussi se retrouve être ni salarié ni indépendant.
0  0 
Avatar de Tofalu
Expert éminent sénior https://www.developpez.com
Le 02/11/2009 à 16:23
Salut,

Bon ben au sein d'une transaction c'est pareil, la suppression est assez aléatoire et je me demande si on va réussir à gérer cette notion de totalité. Peut être faudrait-il mieux remplacer le =1 par <=1. Mais bon, on perd une notion de l'héritage (quoique de toute façon à la création de l'intervenant, rien dans le système ne peut garantir qu'il va évoluer en salarié ou en indépendant).
0  0 
Avatar de Tofalu
Expert éminent sénior https://www.developpez.com
Le 02/11/2009 à 19:18
Ouais, en fait je me suis fait la même reflexion et je voulais tester ce que tu as mis mais je sais plus pourquoi je suis parti sur une autre piste ... infructueuse

L'idée serait donc de tester seulement si la donnée existe bien dans la table "concurrente". Mais finalement, on en revient à ce que je disais, on perd la totalité c-à-d le =1 et non =0

Si on met :

Code : Sélectionner tout
1
2
ALTER TABLE tblSalarie ADD CONSTRAINT Unicite CHECK (
( SELECT COUNT(*) FROM tblIndependant WHERE tblIndependant.ID=tblSalarie.ID)=0)
ça irait aussi ?

Je préferais, c'est plus propre, tu trouves pas ?

Un début d’explication serait qu’on ne sait pas trop dans quel état est la copie tblSalarie T1, non ?
Oui, je crois aussi.

Ce qui est curieux, c'est qu'à plusieurs reprises tout à l'heure ça marchait... puis aprés plus rien, puis aprés, ça marche puis ... Donc si la piste que tu as donné semble fiable autant la préférer.
0  0 
Avatar de f-leb
Responsable Arduino et Systèmes Embarqués https://www.developpez.com
Le 02/11/2009 à 22:00
Re,
Citation Envoyé par Tofalu  Voir le message
Code : Sélectionner tout
1
2
ALTER TABLE tblSalarie ADD CONSTRAINT Unicite CHECK ( 
( SELECT COUNT(*) FROM tblIndependant WHERE tblIndependant.ID=tblSalarie.ID)=0)
ça irait aussi ?
Je préferais, c'est plus propre, tu trouves pas ?

Oui et ça marche aussi.

En fait, la contrainte CHECK étant une contrainte liée à une table, on ne devrait pas pouvoir consulter la table pendant sa propre mise à jour.

J’ai lu quelque part que certains SGBD (pas Access) permettaient les assertions comme :
Code sql : Sélectionner tout
1
2
3
CREATE ASSERTION unicite CHECK  
(NOT EXISTS (SELECT tblSalarie.ID FROM tblSalarie S INNER JOIN tblIndependant  I 
ON S.ID = I.ID))

Alors sur le même modèle j’ai essayé :
Code sql : Sélectionner tout
1
2
3
4
5
6
7
ALTER Table Salarie ADD CONSTRAINT Unicite CHECK  
(NOT EXISTS (SELECT Salarie.ID FROM Salarie S INNER JOIN Independant I 
ON S.ID = I.ID)) 
  
ALTER Table Independant ADD CONSTRAINT Unicite2 CHECK  
(NOT EXISTS (SELECT Independant.ID FROM Independant I INNER JOIN Salarie S 
 ON S.ID = I.ID))
Et ben ça marche quand même??!! Comprends pô pourquoi ça marche, mais ça marche nickel.

Pas claire cette histoire, y m’reste des aspirines si tu veux.
0  0 
Avatar de Tofalu
Expert éminent sénior https://www.developpez.com
Le 03/11/2009 à 8:15
En fait, la contrainte CHECK étant une contrainte liée à une table, on ne devrait pas pouvoir consulter la table pendant sa propre mise à jour.
Ben pourtant ça marche à l'update et à l'insert, y a que le delete qui semble poser parfois problème.
0  0