Il y a pas mal de choses qui peuvent causer l'erreur 150, donc pour les personnes qui recherchent ce sujet, voici ce que je pense être une liste presque exhaustive (source Causes de Errno 150 ):
Pour l'errno 150 ou l'errno 121, en tapant simplement SHOW ENGINE INNODB STATUS, il y a une section appelée "LATEST FOREIGN KEY ERROR". En dessous, cela vous donnera un message d'erreur très utile, qui vous dira généralement tout de suite quel est le problème. Vous avez besoin de privilèges SUPER pour l'exécuter, donc si vous ne l'avez pas, vous devrez simplement tester les scénarios suivants.
1) Les types de données ne correspondent pas: les types de colonnes doivent être les mêmes
2) Colonnes parentes non indexées (ou indexées dans le mauvais ordre)
3) Les classements de colonnes ne correspondent pas
4) Utilisation de SET NULL sur une colonne NOT NULL
5) Les classements de table ne correspondent pas: même si les classements de colonnes correspondent, sur certaines versions de MySQL, cela peut être un problème.
6) La colonne parent n'existe pas réellement dans la table parent. Vérifiez l'orthographe (et peut-être un espace au début ou à la fin de la colonne)
7) L'un des index de l'une des colonnes est incomplet ou la colonne est trop longue pour un index complet. Notez que MySQL (sauf si vous le modifiez) a une longueur maximale de clé de colonne unique de 767 octets (cela correspond à une colonne UTF varchar (255))
Dans le cas où vous obtenez un numéro d'erreur 121, voici quelques causes:
1) Le nom de la contrainte que vous avez choisi est déjà pris
2) Sur certains systèmes, s'il y a une différence de casse dans votre déclaration et les noms de table. Cela peut vous mordre si vous passez d'un serveur à un autre qui a des règles de gestion des cas différentes.