par
devlop78 » 12 juin 2011, 03:02
Attention, c'est un élève qui appartient à une école, et pas l'inverse. Dans ce que tu as fait, c'est l'inverse. En plus, tu mets "id_nom" dans la deuxième table, sans préciser à quelle table il doit faire référence.
Dans PHPMyAdmin :
- Tu dois créer tes tables sous le moteur InnoDB. Celui-ci est plus lent que MyISAM, mais MyISAM n'est ni relationnel, ni transactionnel.
- Tu dois mettre les FK (Foreign Key) en Index. Je crois que c'est obligatoire pour MySQL, ça l'est en tous cas pour PHPMyAdmin.
- Tu vas dans la structure de la table où est la FK, et tu cliques sur "Gestion des relation"
- Tu lies ta FK (qui devient alors vraiment une FK) avec la PK (Primary Key) de la table voulue. Tu peux sur la droite préciser le comportement souhaité en cas de modification de la PK ou de la suppression de la ligne qu'elle représente. Par défaut, sur MySQL, c'est NO ACTION == RESTRICT mais tu peux choisir CASCADE ou SET NULL. Cascade fera, pour une suppression que si tu supprime la ligne de la PK, la ligne de la FK sera supprimée. SET NULL lors de la suppression de la ligne de la PK, mettra la FK à NULL, si NULL est une valeur autorisée.
Tout ces choix sont fait à la modélisation. Si tu as une voiture, un modèle de moteur, que tu as choisi SET NULL, si tu supprime le moteur, la voiture se retrouve en quelque sorte sans moteur, ou sans moteur connu/défini. Cela peut être intolérable comme tout à fait possible dans ton application. Si tu mets cascade, la suppression du moteur entraine la suppression de ta voiture. Dans une application courante, dans ce contexte, ce n'est vraiment pas souhaitable ...
Mais si on imagine un forum, on pourrait avoir une table SUJETS et une table MESSAGES. On crée un sujet comme le tient, et on y répond comme toi et moi. Si on s'en tient à ces deux seules tables, il serait absurde de supprimer un sujet et de laisser les messages en NULL. On aurait alors des messages qui ne seront par personne, dont personne ne connait l'existence, et qui pollue la table. Par ailleurs, si on le laisse à RESTRICT, on sera dans l'incapacité de supprimer le sujet si il y a des messages. Evidemment, il suffit de supprimer les messages avant de supprimer le sujet, c'est un choix tout à fait raisonnable. On a aussi la possibilité de laisser MySQL gérer ça avec CASCADe, qui entrainera la suppression des messages à la suppression du sujet, et en plus, si je ne m'abuse, de façon atomique.
Par contre, mais c'est valable pour tout script, une bonne solution dans un contexte ne l'est pas dans un autre. Si ton message possède des images sur le disque dur, l'opération CASCADE entrainera des images orphelines et sans aucun référencement. Dans le temps, les images s'accumuleront et il faudra alors développer un script pour faire le nettoyage des orphelines.
Pire encore, si tu as une table utilisateurs et une table pages (pour un site web par exemple), et que tu lis en cascade, la suppression de l'utilisateur entrainera la suppression des pages. Ce n'est pas en général l'effet recherché. Il n'y a pas de solutions miracles à ma connaissance, soit tu passes en SET NULL si tu autorises des pages aux utilisateurs inconnus (et encore, là il a été connu, donc ça peut être interprété comme de la corruption de données), soit tu transmets les pages à un autre utilisateur, mais là c'est pire tu changes toute la véracité de l'information, soit tu crées une option de désactivation de l'utilisateur, qui le laissera propriétaire des pages tout en rendant son propriétaire dans l'incapacité de se connecter à son compte. L'option RESTRICT étant donné la dangereusité potentielle est donc par défaut dans cette situation le choix le plus approprié. Rien n'empêche par la suite d'avoir une sorte de Garbage Collector qui supprimera les utilisateurs qui n'ont plus aucun lien avec rien.
Finalement, c'est comme tout, le sujet est complexe. Le problème est aussi que NULL peut avoir beaucoup de signification, tout comme en PHP, il est impossible de différencier une variable inexistante d'une variable initialisée à null, en MySQL NULL peut vouloir dire "non précisé", mais aussi "non lié", ou "n'est plus lié". Donc, c'est aussi à prendre en compte.
Enfin voilà, dans la théorie technique, c'est assez simple, c'est surtout le choix judicieux, logique et cohérent qui le sera moins ^^
Attention, c'est un élève qui appartient à une école, et pas l'inverse. Dans ce que tu as fait, c'est l'inverse. En plus, tu mets "id_nom" dans la deuxième table, sans préciser à quelle table il doit faire référence.
Dans PHPMyAdmin :
- Tu dois créer tes tables sous le moteur InnoDB. Celui-ci est plus lent que MyISAM, mais MyISAM n'est ni relationnel, ni transactionnel.
- Tu dois mettre les FK (Foreign Key) en Index. Je crois que c'est obligatoire pour MySQL, ça l'est en tous cas pour PHPMyAdmin.
- Tu vas dans la structure de la table où est la FK, et tu cliques sur "Gestion des relation"
- Tu lies ta FK (qui devient alors vraiment une FK) avec la PK (Primary Key) de la table voulue. Tu peux sur la droite préciser le comportement souhaité en cas de modification de la PK ou de la suppression de la ligne qu'elle représente. Par défaut, sur MySQL, c'est NO ACTION == RESTRICT mais tu peux choisir CASCADE ou SET NULL. Cascade fera, pour une suppression que si tu supprime la ligne de la PK, la ligne de la FK sera supprimée. SET NULL lors de la suppression de la ligne de la PK, mettra la FK à NULL, si NULL est une valeur autorisée.
Tout ces choix sont fait à la modélisation. Si tu as une voiture, un modèle de moteur, que tu as choisi SET NULL, si tu supprime le moteur, la voiture se retrouve en quelque sorte sans moteur, ou sans moteur connu/défini. Cela peut être intolérable comme tout à fait possible dans ton application. Si tu mets cascade, la suppression du moteur entraine la suppression de ta voiture. Dans une application courante, dans ce contexte, ce n'est vraiment pas souhaitable ...
Mais si on imagine un forum, on pourrait avoir une table SUJETS et une table MESSAGES. On crée un sujet comme le tient, et on y répond comme toi et moi. Si on s'en tient à ces deux seules tables, il serait absurde de supprimer un sujet et de laisser les messages en NULL. On aurait alors des messages qui ne seront par personne, dont personne ne connait l'existence, et qui pollue la table. Par ailleurs, si on le laisse à RESTRICT, on sera dans l'incapacité de supprimer le sujet si il y a des messages. Evidemment, il suffit de supprimer les messages avant de supprimer le sujet, c'est un choix tout à fait raisonnable. On a aussi la possibilité de laisser MySQL gérer ça avec CASCADe, qui entrainera la suppression des messages à la suppression du sujet, et en plus, si je ne m'abuse, de façon atomique.
Par contre, mais c'est valable pour tout script, une bonne solution dans un contexte ne l'est pas dans un autre. Si ton message possède des images sur le disque dur, l'opération CASCADE entrainera des images orphelines et sans aucun référencement. Dans le temps, les images s'accumuleront et il faudra alors développer un script pour faire le nettoyage des orphelines.
Pire encore, si tu as une table utilisateurs et une table pages (pour un site web par exemple), et que tu lis en cascade, la suppression de l'utilisateur entrainera la suppression des pages. Ce n'est pas en général l'effet recherché. Il n'y a pas de solutions miracles à ma connaissance, soit tu passes en SET NULL si tu autorises des pages aux utilisateurs inconnus (et encore, là il a été connu, donc ça peut être interprété comme de la corruption de données), soit tu transmets les pages à un autre utilisateur, mais là c'est pire tu changes toute la véracité de l'information, soit tu crées une option de désactivation de l'utilisateur, qui le laissera propriétaire des pages tout en rendant son propriétaire dans l'incapacité de se connecter à son compte. L'option RESTRICT étant donné la dangereusité potentielle est donc par défaut dans cette situation le choix le plus approprié. Rien n'empêche par la suite d'avoir une sorte de Garbage Collector qui supprimera les utilisateurs qui n'ont plus aucun lien avec rien.
Finalement, c'est comme tout, le sujet est complexe. Le problème est aussi que NULL peut avoir beaucoup de signification, tout comme en PHP, il est impossible de différencier une variable inexistante d'une variable initialisée à null, en MySQL NULL peut vouloir dire "non précisé", mais aussi "non lié", ou "n'est plus lié". Donc, c'est aussi à prendre en compte.
Enfin voilà, dans la théorie technique, c'est assez simple, c'est surtout le choix judicieux, logique et cohérent qui le sera moins ^^