Als je dat doet:
DELETE FROM `jobs` WHERE `job_id` =1 LIMIT 1
Het geeft een fout:
#1451 - Cannot delete or update a parent row: a foreign key constraint fails
(paymesomething.advertisers, CONSTRAINT advertisers_ibfk_1 FOREIGN KEY
(advertiser_id) REFERENCES jobs (advertiser_id))
Hier zijn mijn tabellen:
CREATE TABLE IF NOT EXISTS `advertisers` (
`advertiser_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`password` char(32) NOT NULL,
`email` varchar(128) NOT NULL,
`address` varchar(255) NOT NULL,
`phone` varchar(255) NOT NULL,
`fax` varchar(255) NOT NULL,
`session_token` char(30) NOT NULL,
PRIMARY KEY (`advertiser_id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
INSERT INTO `advertisers` (`advertiser_id`, `name`, `password`, `email`, `address`, `phone`, `fax`, `session_token`) VALUES
(1, 'TEST COMPANY', '', '', '', '', '', '');
CREATE TABLE IF NOT EXISTS `jobs` (
`job_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`advertiser_id` int(11) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`shortdesc` varchar(255) NOT NULL,
`longdesc` text NOT NULL,
`address` varchar(255) NOT NULL,
`time_added` int(11) NOT NULL,
`active` tinyint(1) NOT NULL,
`moderated` tinyint(1) NOT NULL,
PRIMARY KEY (`job_id`),
KEY `advertiser_id` (`advertiser_id`,`active`,`moderated`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;
INSERT INTO `jobs` (`job_id`, `advertiser_id`, `name`, `shortdesc`, `longdesc`, `address`, `active`, `moderated`) VALUES
(1, 1, 'TEST', 'TESTTEST', 'TESTTESTES', '', 0, 0);
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`) REFERENCES `jobs` (`advertiser_id`);
Zoals het nu is, moet je de rij uit de adverteerders tabel verwijderen voordat je de rij in de vacaturetabel waar die naar verwijst kunt verwijderen. Dit:
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`)
REFERENCES `jobs` (`advertiser_id`);
...is eigenlijk het tegenovergestelde van wat het zou moeten zijn. Zoals het is, betekent het dat je'een record in de jobtabel zou moeten hebben vóór de adverteerders. Dus moet je gebruiken:
ALTER TABLE `jobs`
ADD CONSTRAINT `advertisers_ibfk_1` FOREIGN KEY (`advertiser_id`)
REFERENCES `advertisers` (`advertiser_id`);
Zodra je de vreemde sleutel relatie hebt gecorrigeerd, zal je delete statement werken.
Volgens uw huidige (mogelijk gebrekkige) ontwerp, moet u de rij uit de adverteerders tabel verwijderen voor u de rij in de vacaturetabel waarnaar ze verwijst kunt verwijderen.
Als alternatief zou je je foreign key zo kunnen instellen dat een delete in de parent tabel automatisch rijen in child tabellen verwijdert. Dit wordt een cascade verwijdering genoemd. Het ziet er ongeveer zo uit:
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1`
FOREIGN KEY (`advertiser_id`) REFERENCES `jobs` (`advertiser_id`)
ON DELETE CASCADE;
Dat gezegd hebbende, zoals anderen al hebben opgemerkt, je foreign key voelt alsof het andersom zou moeten gaan, aangezien de adverteerders tabel echt de primaire sleutel bevat en de jobs tabel de foreign key bevat. Ik zou het als volgt herschrijven:
ALTER TABLE `jobs`
ADD FOREIGN KEY (`advertiser_id`) REFERENCES `advertisers` (`advertiser_id`);
En de cascade verwijdering zal niet nodig zijn.
Als er meer dan één job is met dezelfde adverteerder_id, dan moet je foreign key zijn:
ALTER TABLE `jobs`
ADD CONSTRAINT `advertisers_ibfk_1`
FOREIGN KEY (`advertiser_id`)
REFERENCES `advertisers` (`advertiser_id`);
Anders (als het andersom is in jouw geval), als je wilt dat de rijen in de adverteerder automatisch worden verwijderd als de rij in de job wordt verwijderd, voeg dan de 'ON DELETE CASCADE' optie toe aan het einde van je foreign key:
ALTER TABLE `advertisers`
ADD CONSTRAINT `advertisers_ibfk_1`
FOREIGN KEY (`advertiser_id`)
REFERENCES `jobs` (`advertiser_id`)
ON DELETE CASCADE;
Kijk op Foreign Key constraints