I am trying to create a table in MySQL with two foreign keys, which reference the primary keys in 2 other tables, but I am getting an errno: 150 error and it will not create the table.
Here is the SQL for all 3 tables:
CREATE TABLE role_groups (
`role_group_id` int(11) NOT NULL `AUTO_INCREMENT`,
`name` varchar(20),
`description` varchar(200),
PRIMARY KEY (`role_group_id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `roles` (
`role_id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50),
`description` varchar(200),
PRIMARY KEY (`role_id`)
) ENGINE=InnoDB;
create table role_map (
`role_map_id` int not null `auto_increment`,
`role_id` int not null,
`role_group_id` int not null,
primary key(`role_map_id`),
foreign key(`role_id`) references roles(`role_id`),
foreign key(`role_group_id`) references role_groups(`role_group_id`)
) engine=InnoDB;
Any help would be greatly appreciated.
MySQL’s generic “errno 150” message “means that a foreign key constraint was not correctly formed.” As you probably already know if you are reading this page, the generic “errno: 150” error message is really unhelpful. However:
You can get the actual error message by running
SHOW ENGINE INNODB STATUS;
and then looking forLATEST FOREIGN KEY ERROR
in the output.For example, this attempt to create a foreign key constraint:
fails with the error
Can't create table 'test.t2' (errno: 150)
. That doesn’t tell anyone anything useful other than that it’s a foreign key problem. But runSHOW ENGINE INNODB STATUS;
and it will say:It says that the problem is it can’t find an index.
SHOW INDEX FROM t1
shows that there aren’t any indexes at all for tablet1
. Fix that by, say, defining a primary key ont1
, and the foreign key constraint will be created successfully.Helpful tip, use
SHOW WARNINGS;
after trying yourCREATE
query and you will receive the error as well as the more detailed warning:So in this case, time to re-create my table!
I've found another reason this fails... case sensitive table names.
For this table definition
This table definition works
whereas this one fails
The fact that it worked on Windows and failed on Unix took me a couple of hours to figure out. Hope that helps someone else.
Definitely it is not the case but I found this mistake pretty common and unobvious. The target of a
FOREIGN KEY
could be notPRIMARY KEY
. Te answer which become useful for me is:A FOREIGN KEY always must be pointed to a PRIMARY KEY true field of other table.
Also worth checking that you aren't accidentally operating on the wrong database. This error will occur if the foreign table does not exist. Why does MySQL have to be so cryptic?
(Side notes too big for a Comment)
There is no need for an
AUTO_INCREMENT
id in a mapping table; get rid of it.Change the
PRIMARY KEY
to(role_id, role_group_id)
(in either order). This will make accesses faster.Since you probably want to map both directions, also add an
INDEX
with those two columns in the opposite order. (There is no need to make itUNIQUE
.)More tips: http://mysql.rjweb.org/doc.php/index_cookbook_mysql#speeding_up_wp_postmeta