Je fais une petite base de données avec MySQL Workbench. J'ai une table principale, appelée "Immobili", qui a une clé primaire composée de quatre colonnes: (Comune, Via, Civico, Immobile).
Maintenant, j'ai aussi trois autres tables, qui ont la même clé primaire (Comune, Via, Civico, Immobile), mais ces champs sont également référencés à la table Immobili.
Première question: Puis-je créer une clé primaire qui est aussi une clé étrangère?
Deuxième question: lorsque j'essaie d'exporter les modifications, il est écrit: Exécuter un script SQL sur le serveur
# ERROR: Error 1005: Can't create table 'dbimmobili.condoni' (errno: 150)
CREATE TABLE IF NOT EXISTS `dbimmobili`.`Condoni` (
`ComuneImmobile` VARCHAR(50) NOT NULL ,
`ViaImmobile` VARCHAR(50) NOT NULL ,
`CivicoImmobile` VARCHAR(5) NOT NULL ,
`InternoImmobile` VARCHAR(3) NOT NULL ,
`ProtocolloNumero` VARCHAR(15) NULL ,
`DataRichiestaSanatoria` DATE NULL ,
`DataSanatoria` DATE NULL ,
`SullePartiEsclusive` TINYINT(1) NULL ,
`SullePartiComuni` TINYINT(1) NULL ,
`OblazioneInEuro` DOUBLE NULL ,
`TecnicoOblazione` VARCHAR(45) NULL ,
`TelefonoTecnico` VARCHAR(15) NULL ,
INDEX `ComuneImmobile` (`ComuneImmobile` ASC) ,
INDEX `ViaImmobile` (`ViaImmobile` ASC) ,
INDEX `CivicoImmobile` (`CivicoImmobile` ASC) ,
INDEX `InternoImmobile` (`InternoImmobile` ASC) ,
PRIMARY KEY (`ComuneImmobile`, `ViaImmobile`, `CivicoImmobile`, `InternoImmobile`) ,
CONSTRAINT `ComuneImmobile`
FOREIGN KEY (`ComuneImmobile` )
REFERENCES `dbimmobili`.`Immobile` (`ComuneImmobile` )
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `ViaImmobile`
FOREIGN KEY (`ViaImmobile` )
REFERENCES `dbimmobili`.`Immobile` (`ViaImmobile` )
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `CivicoImmobile`
FOREIGN KEY (`CivicoImmobile` )
REFERENCES `dbimmobili`.`Immobile` (`CivicoImmobile` )
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `InternoImmobile`
FOREIGN KEY (`InternoImmobile` )
REFERENCES `dbimmobili`.`Immobile` (`InternoImmobile` )
ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE = InnoDB
Affichage de l'état du moteur:
Erreur dans la contrainte de clé étrangère de la table dbimmobili/valutazionimercato:
Impossible de trouver un index dans la table référencée où les colonnes référencées apparaissent en tant que premières colonnes, ou des colonnes typse dans la table et la table référencée ne correspondent pas pour la contrainte. Notez que le type de stockage interne ENUM et SET a changé dans les tables créées avec> = InnoDB-4.1.12, et de telles colonnes dans les anciennes tables ne peuvent pas être référencées par de telles colonnes dans de nouveaux tableaux.
Où je vais mal?
Lors de la création d'une contrainte de clé étrangère, MySQL requiert un index utilisable à la fois sur la table de référence et sur la table référencée. L'index de la table de référence est créé automatiquement s'il n'en existe pas, mais celui de la table référencée doit être créé manuellement ( Source ). Le vôtre semble manquer.
Cas de test:
CREATE TABLE tbl_a (
id int PRIMARY KEY,
some_other_id int,
value int
) ENGINE=INNODB;
Query OK, 0 rows affected (0.10 sec)
CREATE TABLE tbl_b (
id int PRIMARY KEY,
a_id int,
FOREIGN KEY (a_id) REFERENCES tbl_a (some_other_id)
) ENGINE=INNODB;
ERROR 1005 (HY000): Can't create table 'e.tbl_b' (errno: 150)
Mais si nous ajoutons un index sur some_other_id
:
CREATE INDEX ix_some_id ON tbl_a (some_other_id);
Query OK, 0 rows affected (0.11 sec)
Records: 0 Duplicates: 0 Warnings: 0
CREATE TABLE tbl_b (
id int PRIMARY KEY,
a_id int,
FOREIGN KEY (a_id) REFERENCES tbl_a (some_other_id)
) ENGINE=INNODB;
Query OK, 0 rows affected (0.06 sec)
Ce n'est souvent pas un problème dans la plupart des situations, car le champ référencé est souvent la clé primaire de la table référencée et la clé primaire est indexée automatiquement.
Vérifiez bien que les clés étrangères ont exactement le même type que le champ que vous avez dans cette table. Par exemple, les deux doivent être Integer (10) ou Varchar (8), même le nombre de caractères.
Je réalise que ceci est un ancien message, mais il figure en bonne place dans Google. J'ajoute donc ce que j'ai calculé pour mon problème. Si vous avez un mélange de types de table (par exemple, MyISAM et InnoDB), vous obtiendrez également cette erreur. Dans ce cas, InnoDB est le type de table par défaut, mais une table nécessitait une recherche en texte intégral, elle a donc été migrée vers MyISAM. Dans cette situation, vous ne pouvez pas créer de clé étrangère dans la table InnoDB faisant référence à la table MyISAM.
Si votre clé est un CHAR/VARCHAR ou quelque chose de ce type, un autre problème possible est un classement différent. Vérifiez si le jeu de caractères est le même.
J'ai eu cette erreur et j'ai trouvé la raison de l'erreur dans mon cas ... Je réponds toujours à cet ancien message car il figure en bonne place sur Google.
Les variables de la colonne que je souhaitais lier étaient des entiers, mais l'un des entiers avait été non signé. Décocher simplement cela a corrigé mon erreur.
Je commençais à avoir la même erreur. J'ai découvert la solution que j'avais créée la clé primaire dans la table principale en tant que BIGINT UNSIGNED et que je la déclarais comme clé étrangère dans la seconde table en tant que BIGINT uniquement.
Lorsque j'ai déclaré ma clé étrangère en tant que BIGINT UNSIGED dans la deuxième table, tout a bien fonctionné, même aucun index n'a été créé.
Il s'agissait donc d'une incompatibilité de type de données entre la clé primaire et la clé étrangère :)
J'ai eu exactement le même problème, mais la solution à mon problème était totalement différente. J'avais, quelque part dans la base de données, une clé étrangère du même nom. Cela a causé l'erreur 1005.
Renommer ma clé étrangère en un nom plus spécifique à cette situation a résolu le problème.
Dans mon cas, l'erreur était due à la table referencing
est MyISAM
alors que la table referring
était InnoDB
.
Le moteur de table Converted
de MyISAM to InnoDB
résout le problème pour moi.
ALTER TABLE table_name ENGINE=InnoDB;
Je n'ai pas encore la réputation de voter sur la suggestion de Steve, mais cela a résolu mon problème.
Dans mon cas, j'ai reçu cette erreur parce que les deux tables ont été créées à l'aide de moteurs de base de données différents: Innodb et MyISAM.
Vous pouvez changer le type de base de données en utilisant: ALTER TABLE t ENGINE = MYISAM;
@see http://dev.mysql.com/doc/refman/5.1/en/storage-engine-setting.html
MySQL est notoirement grincheux, surtout en ce qui concerne les clés étrangères et les déclencheurs. Je suis en train de peaufiner l'une de ces bases de données et j'ai rencontré ce problème. Ce n'est pas évident ou intuitif, alors voici:
En plus de vérifier si les deux colonnes que vous souhaitez référencer dans la relation ont le même type de données, vous devez également vous assurer que la colonne de la table que vous référencez est un index. Si vous utilisez MySQL Workbench, sélectionnez l'onglet "Index" juste à côté de "Colonnes" et assurez-vous que la colonne référencée par la clé étrangère est un index. Sinon, créez-en un, donnez-lui un nom significatif et attribuez-lui le type "INDEX".
Une bonne pratique consiste à nettoyer les tables impliquées dans les relations pour vous assurer que les tentatives précédentes n'ont pas créé d'index que vous ne souhaitez ni dont vous n'avez pas besoin.
J'espère que cela a aidé, certaines erreurs MySQL sont difficiles à suivre.
En ce qui me concerne, j’essayais de faire correspondre un champ indexé normal d’une table enfant à une clé primaire de la table parent. Par défaut, certaines interfaces graphiques de MySQL comme Sequel Pro définissent la clé primaire comme non signée. Vous devez donc vous assurer que que le champ de la table enfant est lui aussi non signé (à moins que ces champs ne contiennent des données négatives, assurez-vous qu'ils sont tous les deux signés).
Ce n'est pas votre cas particulier, mais il est utile de noter pour quiconque que cette erreur peut se produire si vous essayez de référencer des champs d'une table qui ne sont pas la clé primaire entière de cette table. Évidemment ce n'est pas permis.
Première question: Puis-je créer une clé primaire qui est aussi une clé étrangère?
Oui. En fait, pour MySQL, je n'ai pris l'habitude d'utiliser que des clés primaires pour les clés étrangères. Réduit vraiment les erreurs aléatoires reçues, comme l’erreur: 150 énoncée dans la question.
# ERREUR: erreur 1005: impossible de créer la table 'dbimmobili.condoni' (numéro de code: 150)
Cela a quelque chose à voir avec les index, ou plus précisément à la façon dont MySQL Workbench les interprète et fonctionne avec eux. Cela devient vraiment confus si vous modifiez beaucoup dans le modèle (clés étrangères, index, commandes de colonnes, par exemple) au cours de la même opération d'ingénierie directe, surtout s'il existe déjà une base de données à l'autre extrémité . Par exemple, je ne pense pas que les index créés automatiquement aient été supprimés automatiquement après la suppression d'une clé étrangère.
Voici ce que j'ai fait pour corriger l'erreur que vous recevez. Notez que cela semble fastidieux, mais comparé au temps que j'ai passé à utiliser d'autres méthodes, ce n'est pas le cas.
1. Faites en sorte que toutes les clés étrangères soient des clés primaires dans la table de recherche (le 1 dans le 1 en plusieurs).
Dans mon cas, cela impliquait de changer l'id en tant que pk en nom d'utilisateur dans tbl_users, en nom d'utilisateur ET société en tbl_companies, et en nom d'utilisateur ET société ET contact dans tbl_company_contacts. Il s'agit d'une application permettant à plusieurs utilisateurs d'entrer plusieurs contacts de l'entreprise, ce qui permet de superposer et de cacher les contacts d'autres utilisateurs.
2. Supprimez toutes les relations de diagramme et tous les index de table qui ne sont pas des clés primaires.
Cela corrige la plupart des problèmes d'index causés par un workbench buggy.
3. Si vous faites cela du début à la fin, déposez le schéma sur le serveur afin que mysql workbench ne soit pas dérouté par les index existants et ne soit pas masqué dans le modèle (le problème est causé par la relation entre index et clé étrangère, index seul).
Cela réduit énormément les décisions que doivent prendre la base de données, le serveur et Mysql. Ces décisions sur la manière de transférer un projet d’ingénierie sont complexes et intelligentes, mais imparfaites.
4. Maintenant, je considère que cela revient à la case départ (généralement après une conception beaucoup trop rapide sans processus en étapes). J'ai toujours toutes les tables, mais elles sont propres à ce stade. Maintenant vous venez:
Tout d’abord, assurez-vous que les tables (sans relations) fonctionnent comme prévu.
Suivez la chaîne de relations à travers les clés primaires, en commençant par la table la plus en haut (je suis mon cas tbl_users à tbl_companies). Après chaque relation, faites toujours passer un ingénieur avant pour vous assurer qu'il exécute, puis enregistrez le modèle et fermez-le, puis effectuez un reverse engineering du modèle pour vous assurer qu'il prend. Cela vous permet d'isoler rapidement les problèmes au fur et à mesure qu'ils se présentent, dans mon cas, l'indice laissé utilisé par les anciennes clés étrangères supprimées (arrivé 2 ou 3 fois).
Et tadda, là où tu devais être.
Quand il y a 2 colonnes pour les clés primaires, elles constituent une clé primaire composite, vous devez donc vous assurer que dans la table référencée, il y a aussi 2 colonnes du même type de données.
Faites attention aux paramètresCHARSETetASSEMBLERlorsque vous créez un tableau. En termes de clé étrangère problèmes quelque chose comme ça:
CREATE TABLE yourTableName (
....
....
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
Dans mon cas, je ne pouvais pas créer la table avec des références FOREIGN KEY. D'abord, j'ai le code d'erreur 1005 qui ne dit pratiquement rien. Puis j’ai ajouté COLLATE et enfin le message d’erreur se plaindre de CHARSET.
Error Code: 1253. COLLATION 'utf8_unicode_ci' is not valid for CHARACTER SET 'latin1'
Après cette correction, mon problème a été résolu.
Si quelqu'un a cette erreur avec des relations FK/PK apparemment bien formées et que vous avez utilisé l'outil visuel, essayez de supprimer les colonnes fk incriminées et de les ajouter à nouveau dans l'outil. Je recevais continuellement cette erreur jusqu'à ce que je redessine les liens, ce qui clarifiait les problèmes.