2017-07-05 4 views
0

J'ai défini 2 tables et une contrainte de clé foriegn entre eux comme suit:Comment déboguer contrainte de clé mysql étrangère, ON SUPPRIMER CASCADE ne pas supprimer les lignes de la table des enfants sur l'environnement de production

| users | CREATE TABLE `users` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `account_master_id` int(11) NOT NULL, 
    `user_type_id` int(11) NOT NULL, 
    `user_group_id` int(11) NOT NULL, 
    `user_type_code` char(1) NOT NULL, 
    `membership_number` varchar(40) NOT NULL, 
    `password` varchar(60) NOT NULL, 
    `email` varchar(200) NOT NULL, 
    `isd` varchar(10) NOT NULL, 
    `mobile` varchar(20) NOT NULL, 
    `passenger_id` int(11) NOT NULL, 
    `added_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `updated_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    `added_by` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `email` (`email`), 
    KEY `account_master_id` (`account_master_id`), 
    CONSTRAINT `acMaster_to_user` FOREIGN KEY (`account_master_id`) REFERENCES `account_master` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION 
) ENGINE=InnoDB AUTO_INCREMENT=189 DEFAULT CHARSET=utf8 | 


user_oauth | CREATE TABLE `user_oauth` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `user_id` int(11) NOT NULL, 
    `service` varchar(30) NOT NULL, 
    `auth_id` varchar(100) NOT NULL, 
    `email` varchar(100) NOT NULL, 
    `auto_share` tinyint(4) NOT NULL, 
    `photo` varchar(255) NOT NULL, 
    `auth_token_short` varchar(255) DEFAULT NULL, 
    `auth_details` text NOT NULL, 
    `device_type` varchar(60) NOT NULL, 
    `login_date` datetime NOT NULL, 
    `login_ip` varchar(20) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `user` (`user_id`), 
    CONSTRAINT `user_to_oauth` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION 
) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=latin1 | 

sur la suppression d'une ligne de table users, supprime les entrées correspondantes de la table user_oauth dans les environnements LOCAL et Staging. mais cependant la même chose ne fonctionne pas dans l'environnement de PRODUCTION. Je veux savoir comment puis-je déboguer cela.

mise à jour:

  • les deux tables sont InnoDB
  • mysql en cours d'exécution en mode strict
+1

Est-ce que 'select @@ foreign_key_checks;' (quand ce comportement se produit). S'il est 0, réparez vos données, réglez-le à 1, puis lancez le feu à quelqu'un (à moins que ce ne soit vous-même, puis balayez-le sous le tapis). Si cela dit 1, vous devrez chercher d'autres idées. – Solarflare

+0

merci mon pote, c'était la différence. Pouvez-vous me dire comment vous l'avez compris? je n'essaie pas d'obtenir juste la réponse, mais apprenez à connaître le problème et comment déboguer de telles choses. – Gunnrryy

+0

Je vais ajouter quelques informations sur l'option en guise de réponse. COMMENT le comprendre est difficile à dire. Si vous savez que cette option existe, ce n'est pas magique. Si vous ne le faites pas, c'est un peu. Vous pourriez être en mesure de déduire quelque chose comme cela doit exister et sont en mesure de le trouver dans le manuel. Malheureusement, pour certaines informations, trouver la bonne réponse dans le manuel MySQL nécessiterait aussi de la magie. (Pas pour tous cependant, beaucoup d'aspects y compris les détails techniques sont bien faits). Je suppose qu'une solution réaliste est de google pour cela ou demander à quelqu'un qui le sait (par exemple sur stackoverflow). – Solarflare

Répondre

1

Les raisons pour lesquelles les clés étrangères peuvent ne pas fonctionner sont:

  • ils ne sont pas pris en charge (par exemple sur les tables MyISAM)
  • ils sont disa saigné

MySQL vous permet de désactiver la clé étrangère par les contraintes définissant la variable système foreign_key_checks-0. Cela vous permettra de violer toutes les contraintes de clé étrangère (par exemple, supprimer un parent ou ajouter des enfants sans parent). Mais à son tour, il désactivera également des fonctionnalités connexes comme les cascades, qui sont là pour empêcher automatiquement les violations de contraintes spécifiques (par exemple en supprimant les enfants) - ce qui bien sûr ne se produira plus si l'option est désactivée.

L'idée est de vous aider avec certaines tâches d'administration, par ex. importer des données lorsque les données référencées ne sont pas encore là, mais ne devraient généralement pas être utilisées pendant le fonctionnement normal. Si le paramètre réapparaît, vous pouvez vérifier vos applications si vous définissez cette option par accident, car elle est activée après le démarrage par défaut de chaque serveur et doit être désactivée explicitement.

Vous pouvez vérifier le réglage actuel par ex. en utilisant

select @@foreign_key_checks; 

Vous pouvez utiliser

SET foreign_key_checks = 1; 

pour lui permettre à nouveau, mais sachez qu'il ne vérifie pas vos données actuelles:

Réglage FOREIGN_KEY_CHECKS 1 ne déclenche pas une analyse des données de table existantes. Par conséquent, les lignes ajoutées à la table while foreign_key_checks = 0 ne seront pas vérifiées pour la cohérence.

Vous devrez donc vérifier et réparer vous-même. Vous pouvez le faire avant ou après avoir réactivé le paramètre, bien qu'il soit plus facile de le faire auparavant. Pour déclencher une nouvelle vérification, vous pouvez et devez supprimer et recréer la clé étrangère, juste pour vous assurer que tout est cohérent maintenant.

+0

merci pour l'explication. Je pense que cela est arrivé en raison de l'exportation de phpMyadmin en sélectionnant "Désactiver les contrôles de clés étrangères" et copier manuellement coller le code via le terminal et en oubliant d'activer "Vérifications clés étrangères" à la fin. C'était vraiment utile. – Gunnrryy