2017-07-25 5 views
0

J'ai utilisé le code PHP pour préserver l'intégrité de la base de données pendant des années, mais maintenant je passe de MyISAM à InnoDB et j'ai pensé qu'il serait bien d'utiliser des contraintes de clés étrangères. Mais je veux confirmer avec l'utilisateur avant de faire une cascade, donc les contraintes seraient déclarées comme ON DELETE RESTRICT. Lorsque j'obtiens l'erreur, je signale à l'utilisateur qu'il y a des enregistrements dépendants et combien, et s'ils disent: «Bien sûr, supprimez-les», il serait bon de laisser la base de données effectuer une suppression en cascade. Est-il possible de dire à une instruction spécifique d'aller de l'avant et de cascader? Je m'attendais à une option ou quelque chose sur la commande DELETE (par exemple pseudocode DELETE FROM table WHERE ... CASCADE TO child-table), mais je n'ai rien vu.MariaDB/MySQL contrainte de clé étrangère: possible de demander une cascade au moment de la suppression?

Exemple (très standard many-to-many):

CREATE TABLE `person` (
    `PersonID` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 
    `FullName` varchar(100) CHARACTER SET utf8mb4 NOT NULL DEFAULT '', 
    <many other fields>, 
    PRIMARY KEY (`PersonID`), 
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 
CREATE TABLE `category` (
    `CategoryID` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 
    `Category` varchar(60) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', 
    PRIMARY KEY (`CategoryID`), 
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 
CREATE TABLE `percat` (
    `PersonID` mediumint(8) unsigned NOT NULL DEFAULT 0, 
    `CategoryID` mediumint(8) unsigned NOT NULL DEFAULT 0, 
    PRIMARY KEY (`PersonID`,`CategoryID`), 
    FOREIGN KEY (`PersonID`) REFERENCES `person`(`PersonID`) ON DELETE RESTRICT, 
    FOREIGN KEY (`CategoryID`) REFERENCES `category`(`CategoryID`) ON DELETE RESTRICT 
) ENGINE=InnoDB DEFAULT CHARSET=ascii COLLATE=ascii_bin; 

Je trouve How to cascade-delete temporarily or on-demand? mais: (a) il est pour SQLServer, MySQL pas (bien, techniquement j'utilise MariaDB 10.2.4, si cela fait une différence), donc je ne sais pas si j'ai des options supplémentaires à ma disposition, et (b) ce code de procédure stockée ne serait pas plus simple que le code PHP que j'ai déjà (et moins visible quand je suis en développement), donc je ne vois pas l'intérêt d'en échanger une pour l'autre.

+0

Voulez-vous dire que vous ne connaissez pas 'ON DELETE CASCADE', ou que vous Voulez-vous passer temporairement de RESTRICT à CASCADE? PS mise en œuvre en supprimant la restriction, ajouter la cascade, mettre à jour, supprimer la suppression, ajouter la cascade pousse le plus possible dans le SGBD. – philipxy

+0

Je connais 'ON DELETE CASCADE' - je parle d'un changement temporaire, ou plus exactement, d'une * exception locale *. Je suis préoccupé par la conversion en cascade par 'ALTER TABLE', qui affecterait tout le système et pourrait causer des cascades involontaires par d'autres utilisateurs simultanés. En outre, si quelque chose meurt pendant une étape entre les deux instructions 'ALTER TABLE', il peut ne pas être restauré à RESTRICT. Donc, votre suggestion semble risquée pour moi. – OsakaWebbie

Répondre

1

Réponse courte: Non

réponse plus longue:

La réponse est simple d'esprit: sont simples FKs d'esprit. Quand vous demandez plus que des actions triviales, vous demandez trop de FK, et vous devez construire la «logique métier» dans votre application.

Idem pour les déclencheurs. MySQL (et MariaDB) ont toujours été "maigres et méchants" par rapport aux gros frappeurs. Les FK existent pour vérifier une liste de caractéristiques "oui, nous avons aussi des FK". Donc, tout ce qui est ésotérique dans les détails des FK est très probablement manquant.

Parfois, la syntaxe est implémentée sans aucun code réel derrière elle - CHECK; INDEX(x DESC). (Ce dernier est finalement implémenté en 8.0, mais j'estime que le nombre de cas d'utilisation se situe autour de un sur mille.)

+0

D'accord, merci. Je commençais à penser que c'était la réponse, mais je voulais une confirmation. Je continuerai à utiliser PHP pour faire de mon mieux pour tout attraper et ajouter les FK comme filet de sécurité. Je suis satisfait de "maigre et méchant" - je veux que ma DB soit rapide. – OsakaWebbie

+0

N'utilisez ensuite pas de clés FK si vous savez déjà qu'il n'y a pas de risque de violation FK. Vérification d'un FK prend un certain effort. –

+0

"... si vous savez déjà que ce n'est pas une chance ..." Je ne peux pas dire si vous êtes ironique ou si vous avez plus de confiance que moi dans ma capacité à écrire du code sans bug! ;-) – OsakaWebbie