J’ai lu les concepts du système de firebase database , 6ème édition, Silberschatz . Je vais implémenter le système de firebase database universitaire présenté au chapitre 2 sur OS X sur MySQL. Mais j’ai du mal à créer le course
la table. le department
la table 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 du course
la table 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é Google pour 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 dans le course
la table doivent exister dans la colonne de clé primaire du department
table. 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 dept_name
vraiment une instruction SQL erronée, dois-je désigner dept_name
dans la table de cours en tant que clé étrangère après l’insertion de certaines 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
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 même, dans la table dept_name
le nom dept_name
doit être VARCHAR(20)
Plus d’informations peuvent être trouvées dans la documentation MySQL
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:
Une autre cause de cette erreur est:
Vous avez défini une condition SET NULL si certaines des colonnes sont définies comme NOT NULL.
Peut-être que vos colonnes dept_name
ont des jeux de caractères différents.
Vous pouvez essayer d’en modifier 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;
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 exige que dept_name
soit utilisé deux fois . Une fois pour définir la colonne étrangère et une fois pour définir la colonne primaire.
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
ouALTER TABLE
ressemble à ceci:[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
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 j’ai accidentellement supprimé le statut de clé primaire d’une colonne et j’ai obtenu cette erreur.
ERROR 1215 (HY000): impossible d’append une contrainte de clé étrangère
Il est également intéressant 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 dans 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
Cela était dû au fait que le champ student_id
était 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 des student
était défini comme suit:
mysql> desc persons; +--------------+----------------------+------+-----+-------------------+-----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+----------------------+------+-----+-------------------+-----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment |
Le bigint(20)
(généré à partir de Java long
par mise en veille prolongée) n’est pas compatible avec int(10) unsigned
(Java int
).
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;
Il est à 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.
Ajoutez simplement ‘unsigned’ pour la contrainte FOREIGN
`FK` int(11) unsigned DEFAULT NULL,
Je ne rencontre pas le problème comme toi. Mais je reçois le même message d’erreur. Donc je le marque ici pour la convience des autres.
Vérifiez le jeu de caractères de deux tables 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 charset=utf8
. Donc, le jeu de caractères n’est pas le même.
ERROR 1215 (HY000): Cannot add foreign key constraint
Pour le résoudre, il faut utiliser le même jeu de caractères. Par exemple, utf8
.
Je ne vois personne dire cela explicitement et j’avais le même message d’erreur et mon problème était que j’essayais d’append une clé étrangère à une table TEMPORARY. Ce qui est interdit 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 TEMPORAIRES.
(emphase le mien)
Je suis également tombé sur le même problème. Vous ne savez pas pourquoi cela fonctionne, mais cela fonctionne bien: Essayez d’append ENGINE INNODB après votre requête de création.
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;
CONSTRAINT vendor_tbfk_1 FOREIGN KEY (V_CODE) REFERENCES vendor (V_CODE) ON UPDATE CASCADE
voici comment cela pourrait être … regardez la partie de la colonne de référence. (V_code)