Can't add foreign key in MySQL Database - mysql

Trying to create a simple relation between two fields in two tables - 'Task' table with the field 'USER_TOKEN' and the 'USER' table with the field 'TOKEN'. The two fields are the same structure. As you can see the error and other things that may assist you to help me understand the problem and fix it.
System: MacOS 10.12.3 | DB : MySQL 5.7.17 | DBM : Sequel Pro
Error : MySQL said: Cannot add foreign key constraint
CREATE TABLE `TASK` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`USER_TOKEN` int(11) unsigned NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `USER` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`TOKEN` int(11) unsigned NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE USER
ADD CONSTRAINT TOKENS
FOREIGN KEY (`TOKEN`) REFERENCES `category`(`USER_TOKEN`)
Thanks.

If you really want to create a foreign key to a non-primary key, it MUST be a column that has a unique constraint on it.
A FOREIGN KEY constraint does not have to be linked only to a PRIMARY KEY constraint in another table; it can also be defined to reference the columns of a UNIQUE constraint in another table.
So your USER_TOKEN column of table TASK and TOKEN column of USER table must be UNIQUE. So run the following query:
CREATE TABLE `TASK` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`USER_TOKEN` int(11) unsigned NOT NULL UNIQUE,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `USER` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`TOKEN` int(11) unsigned NOT NULL UNIQUE,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `USER`
ADD CONSTRAINT `TOKENS`
FOREIGN KEY (`TOKEN`) REFERENCES `TASK`(`USER_TOKEN`);
Check Demo here

Related

How to make working: FOREIGN KEY error during addition

I have two tables, books and borrowing requests - I am making a study project to learn MySQL. Trying to link these two tables using a FK, and constantly get an error:
"SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint")
Apart from documentation, I searched virtually all of the related topics here on SO, however, no success. Types are the same, columns both unsigned, one primary key, etc. - to my understanding I have respected all of the provisions. But it does not work! What am I missing?
Here are the two tables and the fk addition query:
CREATE TABLE `books` (
`book_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`book_title` VARCHAR(100) NOT NULL,
`author_id` INT(11) NOT NULL,
`book_condition` INT(5) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=23453 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
CREATE TABLE `borrowing_requests` (
`request_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`user_id` INT(11) NOT NULL,
`book_id` INT(11) UNSIGNED NOT NULL,
`due_date` VARCHAR(55) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=23453 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
FK Query:
ALTER TABLE `books` ADD CONSTRAINT books_fk FOREIGN KEY (`book_id`)
REFERENCES `borrowing_requests`(`book_id`)
ON DELETE NO ACTION ON UPDATE NO ACTION
You have the foreign key "backwards" - the borrowing request should reference a book, not the other way round:
ALTER TABLE `borrowing_requests` ADD CONSTRAINT books_fk FOREIGN KEY (`book_id`)
REFERENCES `books`(`book_id`)
ON DELETE NO ACTION ON UPDATE NO ACTION

MySQL composite unique key and foreign key bug

It seems that adding composite unique key with foreign keys included breaks the table: unable to drop unique key:
drop index test_unq on order_test
Error:
Cannot drop index 'test_unq': needed in a foreign key constraint
Steps to reproduce:
create table product_test (
id bigint unsigned not null auto_increment primary key
);
create table order_test (
id bigint unsigned not null auto_increment primary key,
product_id bigint unsigned not null,
foreign key (product_id) references product_test(id)
);
alter table order_test add some_field int not null;
alter table order_test add unique test_unq(product_id, some_field);
Running
SHOW CREATE TABLE order_test
returns
CREATE TABLE `order_test` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`product_id` bigint(20) unsigned NOT NULL,
`some_field` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `test_unq` (`product_id`,`some_field`),
CONSTRAINT `order_test_ibfk_1` FOREIGN KEY (`product_id`) REFERENCES
`product_test` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Result looks invalid, there is a constraint but no key for product_id.
Any ideas how to recover table without dropping and creating it again?
Thanks!
EDIT:
Removing all other foreign keys does not help! Structure after removing:
CREATE TABLE `order_test` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`product_id` bigint(20) unsigned NOT NULL,
`some_field` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `test_unq` (`product_id`,`some_field`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Same error when I try to drop index.
drop index test_unq on order_test
Error:
Cannot drop index 'test_unq': needed in a foreign key constraint

Mysql Foreign Key constraint fails to create with unexisting constraint

So I have two tables, customers and appointments.
Im trying to create a very simple FK relation between appointments.customer_id and customers.id, however when I do my ALTER TABLE trying to add the FK im getting this error:
MySQL said: Cannot add or update a child row: a foreign key constraint fails (wax.#sql-2c5_100, CONSTRAINT customer_fk FOREIGN KEY (id) REFERENCES customers (id) ON DELETE CASCADE ON UPDATE CASCADE)
This constraint "#sql-2c5_100" seems to be some randomly generated constraint, that I can not find ANYWHERE. I've looked on every table on the database, ive looked on all the tables on the information schema and it simply does not exist.
Thanks!
Edit:
Here's the create table outputs
CREATE TABLE `appointments` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`customer_id` int(11) unsigned NOT NULL,
`name` varchar(255) DEFAULT NULL
PRIMARY KEY (`id`),
KEY `customer_id` (`customer_id`)
) ENGINE=InnoDB AUTO_INCREMENT=290958 DEFAULT CHARSET=utf8;
CREATE TABLE `customers` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`first_name` varchar(255) NOT NULL DEFAULT '',
`last_name` varchar(255) NOT NULL DEFAULT '',
`phone` varchar(20) DEFAULT NULL
PRIMARY KEY (`id`),
KEY `sf_id` (`sf_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

MySQL Foreign Key Error

I want to create a database and connect it with two database. But I don't know when i create the Foreign Key to the second database (time_shift table) it always result error 150;
Here is the structure of table outlet:
And this is structure of table time_shift:
And this the query to create new table tide_cart:
create table `tide_chart` (
`id` int(10) not null auto_increment primary key,
`date` date null,
`outletId` int(11) not null,
`timeShiftId` int(11) not null,
`value` varchar(255) not null,
unique (`date`, `outletId`, `timeShiftId`),
foreign key (`outletId`) references `outlet`(`id`)
ON update cascade ON delete cascade,
foreign key (`timeShiftId`) references `time_shift`(`id`)
ON update cascade ON delete cascade
) engine=innoDB;
Please explain to me, why i get error when try to make foreign key connect to table time_shift?
Update: add dump export structure table for outlet and time_shift:
CREATE TABLE `outlet` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
CREATE TABLE `time_shift` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`time_start` time NOT NULL,
`time_end` time NOT NULL,
`is_active` tinyint(4) NOT NULL DEFAULT '1',
`ref_area` int(11) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`),
KEY `ref_area` (`ref_area`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;
You need to use the InnoDB engine for your tables. time_shift is using MyISAM.
You must define indexes for outletId and timeShiftId (either UNIQUE or KEY as needed) in order to be able to create a foreign key using that field.

Mysql FOREIGN KEY error 150

CREATE TABLE IF NOT EXISTS `questions` (
`question_id` int(11) NOT NULL AUTO_INCREMENT,
`createddate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updateddate` timestamp NULL DEFAULT NULL,
`active_flag` tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`question_id`),
UNIQUE KEY `id_UNIQUE` (`question_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE `alarts` (
`alart_id` BIGINT(20) unsigned NOT NULL AUTO_INCREMENT,
`alart_name` varchar(45) NOT NULL,
`interval` int(10) unsigned NOT NULL,
`alart_sent_counter` int(10) unsigned NOT NULL,
`alart_types_id` BIGINT(20) unsigned NOT NULL,
`contact_group_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`alart_id`),
FOREIGN KEY (`alart_types_id`) REFERENCES alart_types(`alart_types_id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
I want to create new table with two FOREIGN KEY like this:
CREATE TABLE `alart_question_mapping` (
`alart_question_mapping_id` BIGINT(20) unsigned NOT NULL AUTO_INCREMENT,
`question_id` int(11) NOT NULL,
`alart_id` BIGINT(20) unsigned NOT NULL,
PRIMARY KEY (`alart_question_mapping_id`),
FOREIGN KEY (`question_id`) REFERENCES questions(`question_id`),
FOREIGN KEY (`alart_id`) REFERENCES alart_types(`alart_id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
but I am getting error:
Error Code: 1005. Can't create table 'alart_question_mapping' (errno: 150)
How can I create this table ?
Thank's.
Chane the statement:
FOREIGN KEY (`alart_id`) REFERENCES alart_types(`alart_id`)
to
FOREIGN KEY (`alart_id`) REFERENCES alarts(`alart_id`)
The only thing I can see is you are referencing a table in your CREATE TABLE statement that is not present in what you provided:
FOREIGN KEY (`alart_id`) REFERENCES alart_types(`alart_id`)
If you remove this reference the table will create. See SQL Fiddle with Demo
Edit #1, based on your update the problem is you are referencing the wrong field in your last table:
Change this:
CREATE TABLE `alart_question_mapping` (
`alart_question_mapping_id` BIGINT(20) unsigned NOT NULL AUTO_INCREMENT,
`question_id` int(11) NOT NULL,
`alart_id` BIGINT(20) unsigned NOT NULL,
PRIMARY KEY (`alart_question_mapping_id`),
FOREIGN KEY (`question_id`) REFERENCES questions(`question_id`),
FOREIGN KEY (`alart_id`) REFERENCES alart_types(`alart_id`)
)
To this:
CREATE TABLE `alart_question_mapping` (
`alart_question_mapping_id` BIGINT(20) unsigned NOT NULL AUTO_INCREMENT,
`question_id` int(11) NOT NULL,
`alart_id` BIGINT(20) unsigned NOT NULL,
PRIMARY KEY (`alart_question_mapping_id`),
FOREIGN KEY (`question_id`) REFERENCES questions(`question_id`),
FOREIGN KEY (`alart_id`) REFERENCES alart_types(`alart_types_id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
So you are changing this line:
FOREIGN KEY (`alart_id`) REFERENCES alart_types(`alart_id`)
to this:
FOREIGN KEY (`alart_id`) REFERENCES alart_types(`alart_types_id`)
If you are referencing the alart_types table then you will want to reference the alart_types_id not the alart_id
see SQL Fiddle with Demo
It can't find table alart_types.
From MySQL Foreign Key Constraints
If you re-create a table that was dropped, it must have a definition
that conforms to the foreign key constraints referencing it. It must
have the right column names and types, and it must have indexes on the
referenced keys, as stated earlier. If these are not satisfied, MySQL
returns error number 1005 and refers to error 150 in the error
message.
I think you mean
FOREIGN KEY (`alart_id`) REFERENCES alart(`alart_id`)
instead of
FOREIGN KEY (`alart_id`) REFERENCES alart_types(`alart_id`)
Hope this makes sense.
In this table
CREATE TABLE alart_types (
alart_types_id BIGINT(20) unsigned NOT NULL AUTO_INCREMENT,
alarts_types_name varchar(45) NOT NULL,
PRIMARY KEY (alart_types_id)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
it doesn't really make sense to have an autoincrement id number without also having a unique constraint on alarts_types_name. Without that unique constraint, you're almost certain to end up with a table whose data looks like this.
1 Warning
2 Critical
3 Warning
4 Warning
This constraint references a column that doesn't exist.
FOREIGN KEY (`alart_id`) REFERENCES alart_types(`alart_id`)
It should be
FOREIGN KEY (`alart_id`) REFERENCES alart_types(`alart_types_id`)