|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 | ||||
|
Candidat au titre de Membre du Club
![]() Inscription : mars 2008 Messages : 47 ![]() |
Bonjour à tous,
Je développe un logiciel libre destiné à l'analyse d'une base de donnée. Pour le moment, le logiciel génère des représentations graphiques "propres" (optimisation du placement des tables pour limiter les croisements entre les relations) du modèle de donnée. Le niveau de détail des représentations est réglable (vue d'ensemble, représentation détaillée, représentation très détaillée). Je m'attaque maintenant à certaines fonctionnalités qui me posent des problèmes. Je réalise que mes connaissances sur les bases de données ne sont pas très poussées, malgré le fait que je les utilise depuis plus de 10 ans. Note : Je tiens à préciser que j'utilise uniquement MySql. Mais le logiciel que je développe est prévu pour s'adapter à toutes les bases. Pour information, il utilise l'API unifiée offerte par JDBC pour l'extraction des informations sur la structure de la base (méta données). Et il est possible de surcharger certaines fonctionnalités pour s'adapter à d'éventuelles particularités. Ma question est la suivante : Sous MySql, il semble qu'une clé étrangère ne peut pointer que vers une clé primaire. Pour fixer les idées, voici un exemple valide de déclaration de clé étrangère. Code :
Et voici un exemple non valide : Code :
Cette règle est-elle valable pour tous les SGBD? Merci, Laurent |
||||
|
|
00
|
|
|
#2 |
|
Membre Expert
![]() Sylvain DevidalChef de projets Générix Inscription : février 2010 Messages : 1 062 ![]() |
La norme SQL dit qu'une clé étrangère doit porter sur un INDEX UNIQUE. C'est le cas d'une clé primaire, mais pas forcément.
J'ai un doute quand à la possibilité de nullité de l'index référencé (je pense qu'il ne peut pas être nullable, donc une simple contrainte d'unicité n'est pas suffisante, si je ne m'abuse -et de toute façon, c'est pas assez performant-). Avec SQL Server par exemple, il est tout à fait possible d'utiliser un index unique pour une FK. A noter aussi qu'une clé étrangère peut être composite (c'est à dire plusieurs colonnes). |
|
|
10
|
|
|
#3 |
|
Candidat au titre de Membre du Club
![]() Inscription : mars 2008 Messages : 47 ![]() |
Merci StringBuilder pour cette réponse rapide.
J'avais effectivement lu la norme du SQL, et j'avais essayé de créer une clé étrangère qui pointe vers un index unique. Mais, sous MySql, ça ne fonctionne pas. Aussi je n'étais pas certain d'avoir bien compris. A+ |
|
|
00
|
|
|
#4 | |
![]() ![]() ![]() Frédéric BROUARDExpert SGBDR & SQL Inscription : mai 2002 Messages : 10 959 ![]() |
Citation:
Une clef étrangère est une contrainte qui réfère une valeur de clef d'une autre table de façon à avoir la certitude que cette référence est unique, donc clef d'entité ou clef subrogée (ou alternative). Elle peut donc être greffée sur une contraintes de clef primaire comme sur une contrainte d'unicité. Ceci n'ayant rien à voir avec les index qui sont inconnus de la norme SQL ! Même si derrière une clef primaire ou une contrainte d'unicité, les SGBDR créent systématiquement un index. A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/ Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp. Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * * |
|
|
10
|
|
|
#5 |
|
Membre Expert
![]() Sylvain DevidalChef de projets Générix Inscription : février 2010 Messages : 1 062 ![]() |
Hmmm, en effet, pas bien réveillé, gueule de bois tout ça...
J'ai un peu oublié qu'on pouvait mettre "NOT NULL" sur une colonne Donc oui, une contrainte d'unicité est suffisante, en revanche, elle doit porter, si je ne m'abuse, sur un tuple de colonnes qui sont toutes "NOT NULL". => Sinon, on ne saurait pas si la valeur NULL fait référence à la table de référence, ou si c'est qu'il n'y a pas de donnée. L'avantage de l'index unique par rapport à la contrainte d'unicité (sous SQL Server tout du moins), c'est qu'il interdit les NULL, d'où mon raccourci d'alcoolique...
|
|
|
00
|
|
|
#6 |
![]() ![]() |
Vous n'êtes pas encore complètement bien réveillé alors, la contrainte d'unicité n'interdit en rien les nulls.
__________________
Email : http://scr.im/waldar |
|
10
|
|
|
#7 | |
![]() ![]() ![]() Frédéric BROUARDExpert SGBDR & SQL Inscription : mai 2002 Messages : 10 959 ![]() |
Citation:
vraiment 2012 commence mal pour toi !!!!! ;-) A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/ Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp. Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * * |
|
|
00
|
|
|
#8 | |
|
Membre Expert
![]() Sylvain DevidalChef de projets Générix Inscription : février 2010 Messages : 1 062 ![]() |
Citation:
UNIQUE CONSTRAINT : Accepte les valeurs nulles UNIQUE INDEX : Edit : En effet, c'est que la PK qui interdit les NULL Edit : Hmmm, donc une FK peut faire référence à une colonne nullable ? Les bras m'en tombent. D'un point de vue sémantique, je trouve ça absurde. Ca veut dire que dans une table, si j'ai une valeur pour une FK qui est nulle, je ne sais pas : - Si c'est que j'ai pas de parent - Ou si j'ai un parent, je ne sais pas lequel parmis les NULL dans la table de référence (???) Testé, et en effet, je suis sur mon derrière. |
|
|
|
00
|
|
|
#9 |
|
Expert Confirmé
![]() Inscription : mai 2002 Messages : 1 655 ![]() |
Bonjour,
le problème c'est que null n'est pas une valeur, mais plutot un état ou l'abscence d'une valeur. http://sqlpro.developpez.com/cours/null/ Donc dans le cas d'une FK, ca ne référence rien du tout. |
|
|
00
|
|
|
#10 | |
|
Membre Expert
![]() Sylvain DevidalChef de projets Générix Inscription : février 2010 Messages : 1 062 ![]() |
Citation:
Mais pour la table de référence, je suis très surpris qu'il puisse y avoir des valeurs nulles. Mais en effet, j'ai testé et ça marche sous SQL Server 2008 R2. En tout cas, je suis pas près de le mettre en pratique ! |
|
|
|
00
|
|
|
#11 |
![]() ![]() |
Pour revenir à la question posée par cette discussion, contentons-nous peut-être de répondre que la bonne pratique est que oui, une clé étrangère doit référencer une clé primaire.
Le petit bémol est que cette clé étrangère peut par contre être une colonne nullable puisque il existe ON DELETE SET NULL. Mais ça non plus c'est un truc que je n'aime pas et que ma rigueur m'interdit.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique. Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework... « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau) À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française ! Linuxiens, comptez-vous ! |
|
00
|
|
|
#12 | |
|
Membre Expert
![]() Sylvain DevidalChef de projets Générix Inscription : février 2010 Messages : 1 062 ![]() |
Citation:
- Lorsqu'on supprimer une donnée dans la table de référence, on a le choix entre supprimer les données filles (ON DELETE CASCADE) ou de les rendre orphelines (ON DELETE SET NULL). => Moi, ce qui me chagrine, c'est que dans la table de référence, il puisse y avoir des NULL (et donc perte de l'unicité, et confusion possible lorsque les données filles font référence à NULL : sont-elles orphelines, ou référencent-elle les lignes à NULL dans la table de référence ?) |
|
|
|
00
|
|
|
#13 |
|
Membre Expert
![]() Responsable de service informatique Inscription : janvier 2009 Messages : 1 099 ![]() |
Pour moi, vu que NULL n'est pas une valeur, les lignes en question sont orphelines. Les lignes de la table fillesdont la FK est null ne font référence à aucune ligne de la table mère.
Tatayo. |
|
|
00
|
|
|
#14 | |
![]() ![]() |
Citation:
En respectant la bonne pratique consistant à toujours faire référence à une clé primaire dans une clé étrangère, comme une clé primaire ne peut pas être à NULL, on n'aura pas non plus de clé étrangère faisant référence à NULL !
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique. Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework... « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau) À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française ! Linuxiens, comptez-vous ! |
|
|
00
|
|
|
#15 | |
![]() ![]() ![]() Cédric DuprezInscription : avril 2002 Messages : 3 823 ![]() |
Citation:
Et ça n'a rien d'une mauvaise pratique.
__________________
Rédacteur / Modérateur SGBD Mes tutoriels et la FAQ MySQL ---------------------------------------------------- Pensez aux balises code et au tag Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça
|
|
|
|
20
|
|
|
#16 |
![]() ![]() |
Une clé alternative est généralement signifiante et susceptible d'être modifiée. Je sais qu'il existe ON UPDATE CASCADE mais ça non plus je n'aime pas !
Faire référence à une clé alternative rend inutile la clé primaire alors ! Selon moi, ce n'est pas de la bonne modélisation, désolé.
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique. Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework... « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau) À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française ! Linuxiens, comptez-vous ! |
|
01
|
|
|
#17 |
![]() ![]() ![]() Cédric DuprezInscription : avril 2002 Messages : 3 823 ![]() |
Bonne modélisation ou pas (ce qui serait un autre débat...), ça répond bien à la question posée : une clé étrangère ne pointe pas "forcément" sur une clé primaire...
Le recours à la clé alternative, d'un point de vue purement pratique (et non pas théorique, sur lequel je suis d'accord avec toi), peut s'avérer utile. J'y ai eu recours sur une base de données dont les tables sont presque toutes identifiées par des clés concaténées. Impossible de changer le modèle de données sans démolir toute la machinerie applicative autour de cette base. Du coup, la mise en place d'une clé alternative avec un identifiant numérique unique, puis le référencement de cette clé numérique, allège considérablement les tables qui pointent sur ces clés (quand la clé est la concaténation de 4 colonnes, le fait de la remplacer par une seule colonne est quand même plus léger). Encore une fois, il faut bien distinguer "la théorie" de "la pratique"...
__________________
Rédacteur / Modérateur SGBD Mes tutoriels et la FAQ MySQL ---------------------------------------------------- Pensez aux balises code et au tag Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça
|
|
|
10
|
|
|
#18 |
|
Membre chevronné
![]() Administrateur de base de données Inscription : août 2009 Messages : 404 ![]() |
Dans la thèorie relationnelle la notion de "clè primaire" est en train de disparaitre.
Une clé primaire c'est une clé (dite "candidate", ou "alternative", etc..) choisie parmis d'autres. Rien de plus. La théorie relationnelle n'impose donc pas aux clés étrangères de faire référence à une clé primaire (même si ce fût le cas plus tôt dans son histoire, comme dans l'article de Codd en 1970). L'objet de référence d'une clé étrangère c'est une clé. Voir Clé primaire Bien sûr on se place dans un context où NULL n'existe pas. Les indexs non plus, cela a déjà était dit par SQLPro plus haut. |
|
|
10
|
|
|
#19 | |
![]() ![]() ![]() Frédéric BROUARDExpert SGBDR & SQL Inscription : mai 2002 Messages : 10 959 ![]() |
Citation:
En effet les contraintes de type FK permettent de faire du MATCH PARTIAL, SIMPLE ou FULL. Je donne un exemple dans mon livre avec une table de date composée de 3 colonnes AN, MOIS, JOUR. Historiquement, il existe des événement dont on ne connais pas la date certaine. Dans ce genre de table de datation on ajoute des année sans mois ni jour et des année + mois sans jour, afin de dater par exemple un événement survenu en août 1238... Voilà un exemple typique de référence partielle. Dans l'industrie vous en trouverez de nombreux. Par exemple dans la grande production (prenons les voitures par exemple) on à des références majeures, mineures, des options, sous options... Tout ce qui constitue une référence précise. Mais certains pièces peuvent être montée sur toute une gamme de véhicule et d'autres plus spécifiques sur un modèle précis avec des options particulières... Si vous n'avez pas mon livre, lisez le paragraphe 5.2.2 de l'article que j'ai écrit sur les contraintes : http://sqlpro.developpez.com/contrai...aintes_SQL.pdf Bref, il vous reste beaucoup à apprendre visiblement ! A +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/ Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp. Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * * |
|
|
00
|
|
|
#20 | |||||||||||||||
|
Candidat au titre de Membre du Club
![]() Inscription : mars 2008 Messages : 47 ![]() |
Citation:
Exemple qui fonctionne Une jointure de A(FK) vers B(PK) tableA.fkb pointe vers une clé *PRIMAIRE* (tableB.id). Code :
tableA.fkb pointe vers un un *index unique* (tableB.otherField). Code :
tableA.fkb pointe vers un un *index PAS unique* (tableB.otherField). Code :
Code :
Code :
Ne fonctionne pas ??? Code :
Code :
|
|||||||||||||||
|
|
00
|
Copyright © 2000-2012 - www.developpez.com