8736 sujets

Développement web côté serveur, CMS

Bonsoir à tous

Mes connaissance en SQL étant proches de zéro, je cherche la solution au problème suivant :

J'ai trois tables, Table1, Table 2, Table3 selon le schéma suivant
upload/1713025753-48769-tables.png

Une ligne de Table1 a 0 ou 1 lien vers une ligne de Table3
de même, une ligne de Table2 a 0 ou 1 lien vers une ligne de Table3
Il n'y a pas de lignes de Table3 qui soient liées à la fois à Table1 et Table2

Ce que je voudrais c'est que quand on détruit une ligne de Table1 ou Table2, la ligne correspondante de Table3, si elle existe, soit également détruite.

J'ai vainement essayé de créer des contraintes externes pour résoudre ce problème : phpMySQL refuse de créer ces contraintes, comme d'habitude sans expliquer pourquoi.

Quelqu'un pourrait-il m'expliquer comment faire ?
Merci de votre aide.
Salut Papy,

Je suis plutôt branché Postgres, mais pour MySQL il me semble que cela reste identique pour ce cas de figure : il faut utiliser l'option `ON DELETE CASCADE` sur des contraintes de clés étrangères.

Exemple :
CREATE TABLE Table1 (
    id INT PRIMARY KEY,
    -- autres colonnes...
    table3_id INT,
    FOREIGN KEY (table3_id) REFERENCES Table3(id) ON DELETE CASCADE
);

CREATE TABLE Table2 (
    id INT PRIMARY KEY,
    -- autres colonnes...
    table3_id INT,
    FOREIGN KEY (table3_id) REFERENCES Table3(id) ON DELETE CASCADE
);

CREATE TABLE Table3 (
    id INT PRIMARY KEY,
    -- autres colonnes...
);

Edit : j'ai laissé les noms des tables suggérées par ta question telles quelles, mais sur le principe je ne l'aurais pas fait pour moi-même. En effet, MySQL sera insensible à la case dans un environnement Windows, mais sensible à la case sous Linux...
Bien sûr, un dev' connait son environnement d'exécution, mais perso je préfère éviter.
"learnsql.fr" a écrit :
Par défaut, il dépend du système d'exploitation et de sa sensibilité à la casse. Cela signifie que MySQL est insensible à la casse dans Windows et macOS, alors qu'il est sensible à la casse dans la plupart des systèmes Linux. Vous pouvez toutefois modifier ce comportement en changeant la collation.

Modifié par Olivier C (14 Apr 2024 - 07:21)
Merci de ta réponse
C’est bien ce que j’ai essayé de faire, mais depuis la console phpMySQL il refuse d’ajouter certaines contraintes externes. Je vais essayer à nouveau dans la journée
J'ai complètement perdu le fil avec MySQL mais le choix du moteur de stockage est peut-être important : de mémoire le moteur MyISAM par défaut est rapide en lecture mais comporte des limitations dans ses fonctionnalités. Il faudrait vérifier la documentation sur ce point.

Peut-être faudra-t-il switcher sur InnoDB le cas échéant ?
J'avais du temps à tuer et je viens de vérifier : effectivement le moteur par défaut MyISAM n'acceptera pas les clefs étrangères. En fait, pour MySQL il faut immaginer ce moteur comme étant scopé pour une table, dès que l'on passe à un besoin au-delà (90% du temps chez moi) il faudrait utiliser InnoDB (avec Postgres je n'ai pas ce problème) :
CREATE TABLE name (
  -- the code... 
) ENGINE=InnoDB;
Ah ! Ok. Effectivement je vois que MyISAM n'est plus le moteur par défaut des tables depuis MySQL 8, donc depuis 2020. Je ne suis définitivement plus à jour sur MySQL...

En tous les cas le problème demeure : peut-être que la version MySQL de Papy est plus ancienne ? Lui seul peut nous le dire.
Merci de vos réponses

Je n'aurais pas dû poser la question avant d'aller dormir !

Ce matin j'ai trouvé la raison de ce comportement :
La structure de la Table3 comporte un champ "Table1_ID" et un champ "Table2_ID" sur lesquels je mets les contraintes externes correspondantes.
Le problème était que la valeur par défaut de ces champs était à "aucun".
En la mettant à "NULL" le problème est réglé.