2010-05-11 8 views
3

Ceci est ma table:MySQL contrainte de clé étrangère disparaissant

/* oefenreeks leerplan */ 
CREATE TABLE leerplan_oefenreeks ( 
    leerplan_oefenreeks_id INT PRIMARY KEY AUTO_INCREMENT NOT NULL, 
    leerplan_id   INT NOT NULL, 
    oefenreeks_id   INT NOT NULL, 
    plaats     INT NOT NULL 
); 

/* fk */ 
ALTER TABLE leerplan_oefenreeks ADD CONSTRAINT fk_leerp_oefenr_leerplan 
FOREIGN KEY(leerplan_id) REFERENCES leerplan (leerplan_id) ON DELETE CASCADE; 

ALTER TABLE leerplan_oefenreeks ADD CONSTRAINT fk_leerp_oefenr_oefenreeks 
FOREIGN KEY(oefenreeks_id) REFERENCES oefenreeks (oefenreeks_id) ON DELETE CASCADE; 

/* when I execute the nexline, my fk_leerp_oefenr_leerplan constraint vanishes/disappears*/ 
ALTER TABLE leerplan_oefenreeks ADD CONSTRAINT un_leerp_oefenr UNIQUE(leerplan_id, oefenreeks_id); 

ALTER TABLE leerplan_oefenreeks ADD CONSTRAINT un_leerp_oefenr_plaats UNIQUE(leerplan_id, plaats); 

Quand je vais vérifier que trois contraintes existent. fk_leerp_oefenr_leerplan disparaît. Je ne comprends pas pourquoi cela arrive.

+0

Quelle est la définition de la table leerplan? Recevez-vous une erreur lors de la création de la contrainte fk_leerp_oefenr_leerplan? –

Répondre

0

Juste pour clarifier les choses, voici comment la table ressemble après que les clés étrangères ont été mises en place:

CREATE TABLE `leerplan_oefenreeks` (
    `leerplan_oefenreeks_id` int(11) NOT NULL AUTO_INCREMENT, 
    `leerplan_id` int(11) NOT NULL, 
    `oefenreeks_id` int(11) NOT NULL, 
    `plaats` int(11) NOT NULL, 
    PRIMARY KEY (`leerplan_oefenreeks_id`), 
    KEY `fk_leerp_oefenr_leerplan` (`leerplan_id`), 
    KEY `fk_leerp_oefenr_oefenreeks` (`oefenreeks_id`), 
    CONSTRAINT `fk_leerp_oefenr_oefenreeks` FOREIGN KEY (`oefenreeks_id`) REFERENCES `oefenreeks` (`oefenreeks_id`) ON DELETE CASCADE, 
    CONSTRAINT `fk_leerp_oefenr_leerplan` FOREIGN KEY (`leerplan_id`) REFERENCES `leerplan` (`leerplan_id`) ON DELETE CASCADE 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ; 

Avis les index fk_leerp_oefenr_leerplan et fk_leerp_oefenr_oefenreeks MySQL ajoute automatiquement.

Après avoir ajouté la première contrainte de clé unique:

ALTER TABLE leerplan_oefenreeks ADD CONSTRAINT un_leerp_oefenr UNIQUE(leerplan_id, oefenreeks_id); 

Mysql supprime l'index fk_leerp_oefenr_leerplan car il ne sera plus nécessaire de soutenir les contrôles clés étrangers sur colonne leerplan_id. À ce stade, la table ressemble à ceci:

CREATE TABLE `leerplan_oefenreeks` (
    `leerplan_oefenreeks_id` int(11) NOT NULL AUTO_INCREMENT, 
    `leerplan_id` int(11) NOT NULL, 
    `oefenreeks_id` int(11) NOT NULL, 
    `plaats` int(11) NOT NULL, 
    PRIMARY KEY (`leerplan_oefenreeks_id`), 
    UNIQUE KEY `un_leerp_oefenr` (`leerplan_id`,`oefenreeks_id`), 
    KEY `fk_leerp_oefenr_oefenreeks` (`oefenreeks_id`), 
    CONSTRAINT `fk_leerp_oefenr_leerplan` FOREIGN KEY (`leerplan_id`) REFERENCES `leerplan` (`leerplan_id`) ON DELETE CASCADE, 
    CONSTRAINT `fk_leerp_oefenr_oefenreeks` FOREIGN KEY (`oefenreeks_id`) REFERENCES `oefenreeks` (`oefenreeks_id`) ON DELETE CASCADE 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ; 

Longue histoire courte, SQLYog montre que les indices dans son arborescence à gauche, si vous voulez voir les clés étrangères, sélectionnez la table dans l'arborescence et appuyez sur F10.

0

En plus de Konerak's suggestion, notez que les contraintes de clé étrangère ne sont pas créées lors de l'utilisation de MyISAM, qui est le moteur de stockage par défaut de MySQL. Vous pouvez utiliser InnoDB à la place, en spécifiant dans la déclaration CREATE TABLE:

CREATE TABLE leerplan_oefenreeks ( 
    leerplan_oefenreeks_id INT PRIMARY KEY AUTO_INCREMENT NOT NULL, 
    leerplan_id   INT NOT NULL, 
    oefenreeks_id   INT NOT NULL, 
    plaats     INT NOT NULL 
) ENGINE=InnoDB; 

Test Case avec le moteur de stockage par défaut, MyISAM:

CREATE TABLE t1 (id int PRIMARY KEY); 
CREATE TABLE t2 (id int, t1_id int); 

ALTER TABLE t2 ADD CONSTRAINT fk_t1t2 
FOREIGN KEY(t1_id) REFERENCES t1 (id) ON DELETE CASCADE; 

SELECT * 
FROM  information_schema.KEY_COLUMN_USAGE 
WHERE table_name ='t2' AND 
     constraint_name <>'PRIMARY' AND referenced_table_name is not null; 

Empty set (0.08 sec) 

Test Case avec InnoDB moteur:

CREATE TABLE t1 (id int PRIMARY KEY) ENGINE=InnoDB; 
CREATE TABLE t2 (id int, t1_id int) ENGINE=InnoDB; 

ALTER TABLE t2 ADD CONSTRAINT fk_t1t2 
FOREIGN KEY(t1_id) REFERENCES t1 (id) ON DELETE CASCADE; 

SELECT * 
FROM  information_schema.KEY_COLUMN_USAGE 
WHERE table_name ='t2' AND 
     constraint_name <>'PRIMARY' AND referenced_table_name is not null; 

+--------------------+-------------------+-----------------+---------------+ 
| CONSTRAINT_CATALOG | CONSTRAINT_SCHEMA | CONSTRAINT_NAME | TABLE_CATALOG | 
+--------------------+-------------------+-----------------+---------------+ 
| NULL    | test    | fk_t1t2   | NULL   | 
+--------------------+-------------------+-----------------+---------------+ ... 
1 row in set (0.00 sec) 
0

Essayez de cette façon:

ALTER TABLE leerplan_oefenreeks ADD UNIQUE KEY `un_leerp_oefenr` (leerplan_id, oefenreeks_id); 

ALTER TABLE leerplan_oefenreeks ADD UNIQUE KEY `un_leerp_oefenr_plaats` (leerplan_id, plaats); 

ALTER TABLE leerplan_oefenreeks ADD CONSTRAINT fk_leerp_oefenr_leerplan 
FOREIGN KEY(leerplan_id) REFERENCES leerplan (leerplan_id) ON DELETE CASCADE; 

ALTER TABLE leerplan_oefenreeks ADD CONSTRAINT fk_leerp_oefenr_oefenreeks 
FOREIGN KEY(oefenreeks_id) REFERENCES oefenreeks (oefenreeks_id) ON DELETE CASCADE; 

ÉDITÉ Après le commentaire OP

J'ai essayé votre code et votre résultat ne se répliquent pas. I simplifié les tableaux de leerplan et oefenreeks:

CREATE TABLE leerplan_oefenreeks ( 
    leerplan_oefenreeks_id INT PRIMARY KEY AUTO_INCREMENT NOT NULL, 
    leerplan_id   INT NOT NULL, 
    oefenreeks_id   INT NOT NULL, 
    plaats     INT NOT NULL 
) engine=innodb; 


CREATE TABLE leerplan ( 
    leerplan_id INT PRIMARY KEY AUTO_INCREMENT NOT NULL, 
    leerplan_data   INT NOT NULL 
)engine=innodb; 


CREATE TABLE oefenreeks ( 
    oefenreeks_id INT PRIMARY KEY AUTO_INCREMENT NOT NULL, 
    oefenreeks_data   INT NOT NULL 
)engine=innodb; 

Puis je courais toutes les instructions alter table, et après:

show create table leerplan_oefenreeks; 


CREATE TABLE `leerplan_oefenreeks` (
    `leerplan_oefenreeks_id` int(11) NOT NULL AUTO_INCREMENT, 
    `leerplan_id` int(11) NOT NULL, 
    `oefenreeks_id` int(11) NOT NULL, 
    `plaats` int(11) NOT NULL, 
    PRIMARY KEY (`leerplan_oefenreeks_id`), 
    UNIQUE KEY `un_leerp_oefenr` (`leerplan_id`,`oefenreeks_id`), 
    UNIQUE KEY `un_leerp_oefenr_plaats` (`leerplan_id`,`plaats`), 
    KEY `fk_leerp_oefenr_oefenreeks` (`oefenreeks_id`), 
    CONSTRAINT `fk_leerp_oefenr_leerplan` FOREIGN KEY (`leerplan_id`) REFERENCES `leerplan` (`leerplan_id`) ON DELETE CASCADE, 
    CONSTRAINT `fk_leerp_oefenr_oefenreeks` FOREIGN KEY (`oefenreeks_id`) REFERENCES `oefenreeks` (`oefenreeks_id`) ON DELETE CASCADE 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

J'utilise: la version du serveur: 5.1.39-log MySQL Serveur de communauté (GPL) 64bit, kubuntu 9.04.

Quoi d'autre pourrait-il être différent de votre côté?

+0

ssry, il exécute sans problèmes, mais quand je vérifie le fk_leerp_oefenr_leerplan n'a pas été ajouté. après cela, j'ai essayé d'exécuter cette contrainte séparée, mais cela n'aide pas. Je reçois (4 ligne (s) touchée) mais toujours pas ajouté – Bramjam

+0

ty man. Je pense que j'ai trouvé le problème. il semble que le fk est réellement là, mais j'utilise sqlyog et le gui ne le montre pas pour une raison quelconque. mais quand j'insère un recod avec un leerplan_id non existant, je reçois une erreur m'indiquant que fk_leerp_oefenr_leerplan est défectueux (= preuve qu'il est en place). – Bramjam

Questions connexes