web-dev-qa-db-fra.com

MySQL: ERROR 1215 (HY000): Impossible d'ajouter une contrainte de clé étrangère

J'ai lu Concepts de système de base de données , 6ème édition, Silberschatz. Je vais implémenter le système de base de données d'universités présenté au chapitre 2 sur OS X sous MySQL. Mais j'ai un problème avec la création de la table course. la table department ressemble à

mysql> select * from department
    -> ;
+------------+----------+-----------+
| dept_name  | building | budget    |
+------------+----------+-----------+
| Biology    | Watson   |  90000.00 |
| Comp. Sci. | Taylor   | 100000.00 |
| Elec. Eng. | Taylor   |  85000.00 |
| Finance    | Painter  | 120000.00 |
| History    | Painter  |  50000.00 |
| Music      | Packard  |  80000.00 |
| Physics    | Watson   |  70000.00 |
+------------+----------+-----------+

mysql> show columns from department
    -> ;
+-----------+---------------+------+-----+---------+-------+
| Field     | Type          | Null | Key | Default | Extra |
+-----------+---------------+------+-----+---------+-------+
| dept_name | varchar(20)   | NO   | PRI |         |       |
| building  | varchar(15)   | YES  |     | NULL    |       |
| budget    | decimal(12,2) | YES  |     | NULL    |       |
+-----------+---------------+------+-----+---------+-------+

La création de la table course provoque l'erreur suivante.

mysql> create table course
    -> (course_id varchar(7),
    -> title varchar (50),
    -> dept_name varchar(20),
    -> credits numeric(2,0),
    -> primary key(course_id),
    -> foreign key (dept_name) references department);
ERROR 1215 (HY000): Cannot add foreign key constraint

après avoir recherché sur Google la contrainte de clé étrangère, je viens d’apprendre que le mot "contrainte de clé étrangère" indique que les données de la colonne de clé étrangère de la table course doivent exister dans la colonne de clé primaire de la table department. Mais j'aurais dû rencontrer cette erreur lors de l'insertion de données. 

Sinon, pourquoi l'auteur me fait-il exécuter cette instruction SQL? 

Si j'exécute réellement une instruction SQL erronée, dois-je désigner dept_name dans la table de cours comme clé étrangère après avoir inséré des données?

EDIT: taper set foreign_key_checks=0 dans mysql> ne corrige pas l'erreur.

------------------------
LATEST FOREIGN KEY ERROR
------------------------
2013-09-21 16:02:20 132cbe000 Error in foreign key constraint of table university/course:
foreign key (dept_name) references department):
Syntax error close to:
)
mysql> set foreign_key_checks=0
    -> ;
Query OK, 0 rows affected (0.00 sec)
mysql> create table course
    -> (course_id varchar(7),
    -> title varchar(50),
    -> dept_name varchar(20),
    -> credits numeric(2,0),
    -> primary key(course_id),
    -> foreign key (dept_name) references department);
ERROR 1215 (HY000): Cannot add foreign key constraint
49
inherithandle

La syntaxe de FOREIGN KEY pour CREATE TABLE est structurée comme suit:

FOREIGN KEY (index_col_name)
        REFERENCES table_name (index_col_name,...)

Donc, votre DDL MySQL devrait être:

 create table course (
        course_id varchar(7),
        title varchar(50),
        dept_name varchar(20),
        credits numeric(2 , 0 ),
        primary key (course_id),
        FOREIGN KEY (dept_name)
            REFERENCES department (dept_name)
    );

De plus, dans la table department, dept_name devrait être VARCHAR(20)

Plus d'informations peuvent être trouvées dans documentation MySQL

45
Strik3r

Lorsque vous obtenez ce message d'erreur vague, vous pouvez trouver l'erreur plus spécifique en exécutant 

SHOW ENGINE INNODB STATUS;

Les raisons les plus courantes sont que lors de la création d'une clé étrangère, le champ référencé et le champ de clé étrangère doivent correspondre:

  • Engine devrait être identique p. Ex. InnoDB 
  • Type de données devrait être identique et de même longueur.
    par exemple. VARCHAR (20) ou INT (10) UNSIGNED 
  • Collation devrait être le même. par exemple. utf8 
  • Unique - La clé étrangère doit faire référence à un champ unique (généralement privé) dans la table de référence.

Une autre cause de cette erreur est:
Vous avez défini une condition SET NULL bien que certaines des colonnes soient définies comme NOT NULL.

59
Andrew

Peut-être que vos colonnes dept_name ont des jeux de caractères différents.

Vous pouvez essayer de modifier l’un ou les deux:

ALTER TABLE department MODIFY dept_name VARCHAR(20) CHARACTER SET utf8;
ALTER TABLE course MODIFY dept_name VARCHAR(20) CHARACTER SET utf8;
23
workflo
foreign key (dept_name) references department

Cette syntaxe n'est pas valide pour MySQL. Il devrait plutôt être:

foreign key (dept_name) references department(dept_name)

MySQL nécessite que dept_name soit utilisé deux fois . Une fois pour définir la colonne étrangère et une fois pour définir la colonne principale.

13.1.17.2. Utilisation des contraintes FOREIGN KEY

... la syntaxe essentielle pour une définition de contrainte de clé étrangère dans une instruction CREATE TABLE ou ALTER TABLE se présente comme suit:

[CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name, ...)
    [ON DELETE reference_option]
    [ON UPDATE reference_option]

reference_option:
    RESTRICT | CASCADE | SET NULL | NO ACTION
6
ta.speot.is

ERREUR 1215 (HY000): Impossible d'ajouter une contrainte de clé étrangère

Il convient également de noter que vous obtenez cette erreur lorsque le type de la colonne qui est une clé étrangère dans une autre capacité ne correspond pas explicitement à la colonne de la table correcte.

Par exemple:

alter table schoolPersons
         add index FKEF5AB5E532C8FBFA (student_id),
         add constraint FKEF5AB5E532C8FBFA
         foreign key (student_id)
         references student (id);
ERROR 1215 (HY000): Cannot add foreign key constraint

En effet, le champ student_id a été défini comme suit:

mysql> desc schoolPersons;
+--------------------+------------+------+-----+---------+----------------+
| Field              | Type       | Null | Key | Default | Extra          |
+--------------------+------------+------+-----+---------+----------------+
| student_id         | bigint(20) | YES  |     | NULL    |                |

alors que le champ id de la table student était défini comme suit:

mysql> desc persons;
+--------------+----------------------+------+-----+-------------------+-----------------+
| Field        | Type                 | Null | Key | Default           | Extra           |
+--------------+----------------------+------+-----+-------------------+-----------------+
| id           | int(10) unsigned     | NO   | PRI | NULL              | auto_increment  |

La bigint(20) (générée à partir de Java long par hibernate) n'est pas compatible avec int(10) unsigned (Java int).

3
Gray

Il est également possible d'obtenir cette erreur si la clé étrangère n'est pas une clé primaire dans sa propre table.

J'ai fait un ALTER TABLE et supprimé accidentellement l'état de la clé primaire d'une colonne, et j'ai eu cette erreur.

3
Jack Davidson

Je ne rencontre pas le problème comme toi. Mais je reçois le même message d'erreur. Donc, je le note ici pour la convience des autres.

Vérifiez le jeu de caractères de la table si le type de colonne est char ou varchar. J'utilise un charset=gbk, mais je crée une nouvelle table dont le charset=utf8 par défaut. Donc, le jeu de caractères n'est pas le même.

ERROR 1215 (HY000): Cannot add foreign key constraint

Le résoudre consiste à utiliser le même jeu de caractères. Par exemple utf8.

2
g10guang

Ajoutez simplement 'unsigned' pour la contrainte FOREIGN

`FK` int(11) unsigned DEFAULT NULL,
1
vedavyasa

Le code ci-dessous a fonctionné pour moi

set @@foreign_key_checks=0;
ALTER TABLE  `table1` ADD CONSTRAINT `table1_fk1` FOREIGN KEY (`coloumn`) REFERENCES `table2` (`id`) ON DELETE CASCADE;
1
Anjaneyulu Batta

Je ne vois personne le déclarer explicitement et j'ai eu le même message d'erreur et mon problème était que j'essayais d'ajouter une clé étrangère à une table temporaire. Ce qui est refusé comme indiqué dans le manuel

Les relations de clé étrangère impliquent une table parent contenant les valeurs de données centrales et une table enfant avec des valeurs identiques renvoyant à son parent. La clause FOREIGN KEY est spécifiée dans la table enfant. Les tables parent et enfant doivent utiliser le même moteur de stockage. Ils ne doivent pas être des tables TEMPORARY.

(c'est moi qui souligne)

0
EdgeCaseBerg

Dans mon cas, charset, type de données tout était correct. Après enquête, j'ai trouvé que dans la table mère, il n'y avait pas d'index sur la colonne de clé étrangère. Une fois le problème ajouté résolu.

 enter image description here 

0
DEV

Je suis tombé sur le même problème aussi. Vous ne savez pas pourquoi cela fonctionne, mais cela fonctionne:.

mysql> create table course
-> (course_id varchar(7),
-> title varchar (50),
-> dept_name varchar(20),
-> credits numeric(2,0),
-> primary key(course_id),
-> foreign key (dept_name) references department) ENGINE INNODB;
0
Shiyao

Même si cela n’est pas directement lié à votre situation, cela peut aider les lecteurs à noter que vous pouvez obtenir exactement le même résultat lorsque vous tapez show engine innodb mstatus si vous ne respectez pas l’ordre de création des tables de la base de données; Cela signifie que vous ne devez pas ajouter de contrainte étrangère référençant une table qui n'existe pas encore. La table de référence doit exister avant la table qui la désigne. 

Cela est également vrai lorsque l'ordre de création de la table est respecté, mais pas les colonnes impliquées dans la contrainte de clé étrangère.

0
Begueradj

Il convient de noter que cette erreur peut également se produire si la table ou la colonne cible que vous utilisez dans la partie REFERENCES n'existe tout simplement pas.

0
Amalgovinus