Now that I am a happy user of PHP5 and MySQL5 and using that for writing a new application, which fortunately involves using the newest technologies, I am finally able to solve one of the biggest issues I always had had with DB-driven applications: foreign key contraints.
Constraints and transactions
I am using InnoDB (I know those contraints had been possible before MySQL5) for that and the first time I am also using the foreign key constraints InnoDB provides. And it does make me happier :-). I don’t have to take care of updating and deleting all the referenced table rows myself, the DB’s storage engine does that for me, as I always had wanted it.
I had started out using MyISAM tables and triggers, but when I realized that I am programming the application using transactions I had to switch to InnoDB for it to have any effect at all. Transactions solve the next problem I always had, uncompleted or failed database modifications.
I upgraded my mind too and was able to drop the triggers, doh. Oh man, that was a long process, even though all this knowledge was available already in some corner of my mind.
Watch out
But I actually wanted to write down the one thing that I had been looking for for a while:
Create foreign keys only on columns with the exact same type!
Of course. Yes, of course. Makes sense, but I just wanted to have a go and try the foreign key constraint and didn’t watch out for the types, then I got the error:
ERROR 1005: Can’t create table (errno: 150)
And the manual just told me the standard things, but not this!
Won’t work
CREATE TABLE chapter (
chapter_id int(10) NOT NULL auto_increment,
title varchar(20) NOT NULL,
PRIMARY KEY (chapter_id)
) ENGINE=InnoDB;
CREATE TABLE subchapter (
subchapter_id int(11) unsigned NOT NULL auto_increment,
chapter_id int(11) unsigned NOT NULL,
title varchar(20) NOT NULL,
PRIMARY KEY (subchapter_id),
KEY chapter_id (chapter_id),
FOREIGN KEY (chapter_id) REFERENCES chapter(chapter_id)
ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB;
The two columns chapter_id are of a different type, int(10) and int(11), and one is signed the other unsigned! Only if you get both types exactly right the creation of the foreign key constraint will be successful! Otherwise you get the meaningless error message mentioned above, which does not really help.
Will work
CREATE TABLE chapter (
chapter_id int(11) unsigned NOT NULL auto_increment,
title varchar(20) NOT NULL,
PRIMARY KEY (chapter_id)
) ENGINE=InnoDB;
CREATE TABLE subchapter (
subchapter_id int(11) unsigned NOT NULL auto_increment,
chapter_id int(11) unsigned NOT NULL,
title varchar(20) NOT NULL,
PRIMARY KEY (subchapter_id),
KEY chapter_id (chapter_id),
FOREIGN KEY (chapter_id) REFERENCES chapter(chapter_id)
ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB;
Let’s see what’s coming after InnoDB …