web-dev-qa-db-fra.com

MySQL: Créer une table avec une erreur FK (errno 150)

J'ai créé un modèle avec MySQL Workbench et je tente maintenant de l'installer sur un serveur mysql.

Utilisation de Fichier> Exporter> Forward Engineer SQL CREATE Script ... il génère un gros fichier Nice pour moi, avec tous les paramètres que je demande. Je bascule vers Outils d'interface graphique MySQL (le navigateur de requêtes en particulier) et charge ce script (notez que je vais créer un outil MySQL officiel à un autre). Cependant, lorsque j'essaie d'exécuter ce fichier, la même erreur se répète 

SQLSTATE [HY000]: erreur générale: 1005 Impossible de créer la table './Srs_dev/location.frm' (errno: 150)

"OK", me dis-je, quelque chose ne va pas avec la table de localisation. Je vérifie donc la définition dans le fichier de sortie.

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';

-- -----------------------------------------------------
-- Table `state`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `state` ;

CREATE  TABLE IF NOT EXISTS `state` (
  `state_id` INT NOT NULL AUTO_INCREMENT ,
  `iso_3166_2_code` VARCHAR(2) NOT NULL ,
  `name` VARCHAR(60) NOT NULL ,
  PRIMARY KEY (`state_id`) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `brand`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `brand` ;

CREATE  TABLE IF NOT EXISTS `brand` (
  `brand_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `name` VARCHAR(45) NOT NULL ,
  `domain` VARCHAR(45) NOT NULL ,
  `manager_name` VARCHAR(100) NULL ,
  `manager_email` VARCHAR(255) NULL ,
  PRIMARY KEY (`brand_id`) )
ENGINE = InnoDB;

-- -----------------------------------------------------
-- Table `location`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `location` ;

CREATE  TABLE IF NOT EXISTS `location` (
  `location_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
  `name` VARCHAR(255) NOT NULL ,
  `address_line_1` VARCHAR(255) NULL ,
  `address_line_2` VARCHAR(255) NULL ,
  `city` VARCHAR(100) NULL ,
  `state_id` TINYINT UNSIGNED NULL DEFAULT NULL ,
  `postal_code` VARCHAR(10) NULL ,
  `phone_number` VARCHAR(20) NULL ,
  `fax_number` VARCHAR(20) NULL ,
  `lat` DECIMAL(9,6) NOT NULL ,
  `lng` DECIMAL(9,6) NOT NULL ,
  `contact_url` VARCHAR(255) NULL ,
  `brand_id` TINYINT UNSIGNED NOT NULL ,
  `summer_hours` VARCHAR(255) NULL ,
  `winter_hours` VARCHAR(255) NULL ,
  `after_hours_emergency` VARCHAR(255) NULL ,
  `image_file_name` VARCHAR(100) NULL ,
  `manager_name` VARCHAR(100) NULL ,
  `manager_email` VARCHAR(255) NULL ,
  `created_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  PRIMARY KEY (`location_id`) ,
  CONSTRAINT `fk_location_state`
    FOREIGN KEY (`state_id` )
    REFERENCES `state` (`state_id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_location_brand`
    FOREIGN KEY (`brand_id` )
    REFERENCES `brand` (`brand_id` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

CREATE INDEX `fk_location_state` ON `location` (`state_id` ASC) ;

CREATE INDEX `fk_location_brand` ON `location` (`brand_id` ASC) ;

CREATE INDEX `idx_lat` ON `location` (`lat` ASC) ;

CREATE INDEX `idx_lng` ON `location` (`lng` ASC) ;

Ca me va bien. Je suppose que le navigateur de requêtes a peut-être un problème, je mets donc ce fichier sur le serveur et essaie de le charger de cette façon.

] mysql -u admin -p -D dbname < path/to/create_file.sql

Et je reçois la même erreur. Je commence donc à examiner ce problème sur Google et à trouver toutes sortes de comptes faisant état d'une erreur avec les tables de style InnoDB qui échouent avec des clés étrangères. Le correctif consiste à ajouter "SET FOREIGN_KEY_CHECKS = 0;" au script SQL. Comme vous pouvez le constater, cela fait déjà partie du fichier créé par MySQL Workbench.

Ma question est donc la suivante: pourquoi cela ne fonctionne-t-il pas quand je fais ce que je pense que je suis censé faire?

Informations de version:

  • MySQL: 5.0.45

  • Outils d'interface graphique: 1.2.17
  • Établi: 5.0.30
18
Peter Bailey

Le type du champ dans une clé étrangère doit être identique au type de la colonne à laquelle il fait référence. Vous avez ce qui suit (coupe):

CREATE  TABLE IF NOT EXISTS `state` (
  `state_id` INT NOT NULL AUTO_INCREMENT ,
...
CREATE  TABLE IF NOT EXISTS `brand` (
  `brand_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
...
CREATE  TABLE IF NOT EXISTS `location` (
...
  `state_id` TINYINT UNSIGNED NULL DEFAULT NULL ,
...
  `brand_id` TINYINT UNSIGNED NOT NULL ,

vous essayez donc de faire référence aux champs INT (dans les tables state et brand) avec les champs TINYINT dans la table location. Je pense que c'est l'erreur dont il se plaint. Vous ne savez pas comment cela est arrivé en premier lieu, ou pourquoi la remise à zéro de FOREIGN_KEY_CHECKS n'empêche pas MySQL de diagnostiquer l'erreur, mais que se passe-t-il si vous corrigez cette incompatibilité de type?

40
Alex Martelli

Pour les autres personnes qui consultent ce fil de discussion, de nombreuses raisons peuvent expliquer cette erreur:

Voir le lien suivant pour une liste complète des erreurs errno 150, 121 et autres erreurs de clés étrangères MySQL:

Erreurs de clé étrangère MySQL et Errno 150

9
juacala

vient de vérifier la réponse de @juacala. Mais ne m'a pas aidé. Voici le message que j'ai envoyé à @ELIACOM quand j'ai trouvé ma source de problèmes.

Je lisais cette excellente source de solutions, mais mon problème n’est pas abordé . J'essayais d'ajouter un FK dans un tableau INNODB pointant vers un PK Dans un MyISAM. Après avoir réglé le MyIsam sur INNODB, cela a fonctionné. J'ai Vérifié toute votre liste avant de m'en rendre compte. À votre santé.

0
juanmf