web-dev-qa-db-fra.com

La contrainte MySQL FOREIGN KEY est mal formée

J'ai la définition de table suivante:

CREATE TABLE `async_task` (
  `idasync_task` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `idasync_type` int(10) unsigned NOT NULL,
  `priority` tinyint(3) NOT NULL,
  `status` enum('todo','doing','failed') NOT NULL DEFAULT 'todo',
  `iduser` int(11) NOT NULL,
  `date_added` datetime NOT NULL,
  PRIMARY KEY (`idasync_task`),
  KEY `priority_id` (`priority`,`idasync_task`),
  KEY `status_type` (`status`,`idasync_type`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

J'ai ajouté une colonne à la table my notification sur laquelle je veux pointer async_task:

ALTER TABLE `notification` ADD COLUMN `async_task_id` BIGINT(20)

Et quand j'ajoute la clé étrangère suivante:

ALTER TABLE `notification` ADD CONSTRAINT `fk_notification_async_task` 
    FOREIGN KEY (`async_task_id`) REFERENCES `async_task`(`idasync_task`);

Je reçois:

ERROR 1005 (HY000): Can't create table `my_database`.`#sql-182_2d` 
(errno: 150 "Foreign key constraint is incorrectly formed")

J'ai cherché ailleurs mais je trouve que les erreurs sont:

  1. La table à laquelle vous faites référence n'est pas créée (pas le cas)
  2. La table à laquelle vous faites référence n'est pas InnoDB (pas le cas, notification et async_task sont InnoDB)
  3. Vous ne faites pas référence à la clé primaire entière (pas le cas, la seule clé primaire est la colonne ID).

Quoi d'autre cela pourrait-il être?

5
Daniel Gray

Les colonnes de référence et référencées doivent être du même type (et la même chose dans ce cas inclut l'attribut unsigned).

Vous n'avez pas défini notification.async_task_id comme non signé, il a donc été créé avec le (par défaut) signed. Corrigez cela et la clé étrangère ne soulèvera aucune erreur.

10
ypercubeᵀᴹ