I'm adding a functionality to a database I have previously created. I have a table named "Test" which holds data about a series of questions. This data can include a number of dynamic fields added by the user, so I have a table named Test_Header_Values which will hold data about which header field is being fulfilled and the test it is part of.
So far so good, I have created both tables but have an Error 1215 when creating a Foreign Key. I had an error 1005 previously, but I tried on another database and it throws the 1215. I have checked infinite times the typing, the relationship, the indexes, and it should work, but I can't get it done.
Here you have the tables:
CREATE TABLE `test` (
`fk_id_checklist` int(10) unsigned NOT NULL,
`sent_date` date NOT NULL,
`fk_id_user` int(10) unsigned NOT NULL,
`fk_id_user_company` int(10) unsigned NOT NULL,
`start_date` date DEFAULT NULL,
PRIMARY KEY (`fk_id_checklist`,`sent_date`,`fk_id_user`,`fk_id_user_company`),
KEY `fk_user_test_idx` (`fk_id_user`,`fk_id_user_company`),
CONSTRAINT `fk_test_user` FOREIGN KEY (`fk_id_user`, `fk_id_user_company`)
REFERENCES `user` (`id_user`, `fk_id_company`)
ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_test_checklist` FOREIGN KEY (`fk_id_checklist`)
REFERENCES `checklist` (`id_checklist`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `test_header_values` (
`fk_id_checklist` int(10) unsigned NOT NULL,
`fk_sent_date` date NOT NULL,
`fk_id_field` int(10) unsigned NOT NULL,
`fk_id_user` int(10) unsigned NOT NULL,
`fk_id_user_company` int(10) unsigned NOT NULL,
`value` varchar(64) NOT NULL,
PRIMARY KEY (`fk_id_checklist`,`fk_id_field`,`fk_id_user`,`fk_id_user_company`,`fk_sent_date`),
KEY `fk_field_idx` (`fk_id_field`),
KEY `fk_values_test_idx` (`fk_id_checklist`,`fk_sent_date`,`fk_id_user`,`fk_id_user_company`),
CONSTRAINT `fk_values_field` FOREIGN KEY (`fk_id_field`) REFERENCES `fields` (`id_field`)
ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_values_test` FOREIGN KEY (`fk_id_checklist` , `fk_id_user` , `fk_id_user_company` , `fk_sent_date`)
REFERENCES `test` (`fk_id_checklist` , `fk_id_user` , `fk_id_user_company` , `sent_date`)
ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
If I remove the constraint fk_values_test it works perfectly. With this line, it returns the aforementioned error.
I have followed this guide and all the questions I found on SO but I have been unable to find the error.
I have been able to solve the problem.
Seemingly, the index for the foreign key must have the same column order that the constraint, which is something that I didn't find specified.
Changing the constraint to `fk_id_checklist` , `fk_id_user` , `fk_id_user_company` , `fk_sent_date` solves this error.
Related
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
I have a marks table which holds the foreign key to an associates message. I used ON DELETE with the expectation that deleting an entry in the marks table would also delete the associated message. It is not working as expected though. I checked out all the other post and can't find any relevant to this one.
I can insert into the database successfully
DELETE FROM marks WHERE x = 37.7836
but when I delete a mark the message that is associated with it is not deleted. Any insights as to what I am doing wrong here?
Edit:
Here is an image of me demonstrating my deletion process:
schema
DROP DATABASE uncovery;
CREATE DATABASE uncovery;
SET foreign_key_checks=0;
USE uncovery;
CREATE TABLE marks (
id int(5) AUTO_INCREMENT,
x float(10, 6),
y float(10, 6),
z float(10, 6),
timestamp timestamp DEFAULT CURRENT_TIMESTAMP,
messageId int(5),
FOREIGN KEY (messageId)
REFERENCES messages(id)
ON DELETE CASCADE,
PRIMARY KEY (id)
);
CREATE TABLE messages (
id int(5) AUTO_INCREMENT,
messageString text,
PRIMARY KEY (id)
);
EDIT 2: Schema Refactor
Here is my newly updated schema:
As you can see I am getting an error that this is invalid when I try to run it:
The foreign key as you've created it won't work the way you expect. Under your schema, if an entry is deleted from messages, it will delete all corresponding entries from the marks table, not the other way around.
Also, you must ensure that you are using the InnoDB storage engine for your tables, or your foreign keys won't work at all. They are not supported in the MyISAM engine type.
To get your schema working such that deleting a mark will cause a message to be deleted, you need to have a markId as a foreign key in the messages table, like so:
CREATE TABLE `messages` (
`id` int(5) NOT NULL auto_increment,
`messageString` text,
`markId` int(5) default NULL,
PRIMARY KEY (`id`),
KEY `markId` (`markId`),
CONSTRAINT `messages_ibfk_1` FOREIGN KEY (`markId`) REFERENCES `marks` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB;
CREATE TABLE `marks` (
`id` int(5) NOT NULL auto_increment,
`x` float(10,6) default NULL,
`y` float(10,6) default NULL,
`z` float(10,6) default NULL,
`timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
I've two InnoDB tables in a MySQL database. Now I like to link one table to the other with a FOREIGN KEY. But it aborts with the error code 1005 - Can't create table.
I've found plenty of information about this error. For example this post and answer here on SO. Although even this answer did not help in my case. I think every point which is mentioned to be checked is not true in my case.
I've created a MySQLFiddle you can checkout with the schema which fails: http://sqlfiddle.com/#!2/b9dc43
(Please note that the failing ALTER TABLE for adding the FOREIGN KEY is not included. See the schema below for the FOREIGN KEY query.)
There's also a FK for cms_element_instance.page_IDFK which references column page.ID but I removed this FK for posting my problem here on SO.
What can be the problem here?
Here the schema in plain text:
CREATE TABLE `cms_element_instance` (
`ID` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`page_IDFK` mediumint(8) unsigned DEFAULT NULL,
`revision` varchar(16) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `page_IDFK` (`page_IDFK`)
) ENGINE=InnoDB AUTO_INCREMENT=1692 DEFAULT CHARSET=utf8;
CREATE TABLE `element_faq_list` (
`element_instance_IDFK` mediumint(8) unsigned NOT NULL,
`page_IDFK` mediumint(8) unsigned NOT NULL,
`mod_faq_collection_IDFK` mediumint(8) unsigned NOT NULL,
PRIMARY KEY (`element_instance_IDFK`,`page_IDFK`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Create FK: This throws error 1005
ALTER TABLE element_faq_list
ADD CONSTRAINT element_instance_fk
FOREIGN KEY (element_instance_IDFK, page_IDFK)
REFERENCES cms_element_instance( ID , page_IDFK);
You are adding (element_instance_IDFK, page_IDFK) as a foreign key constraints which refers to ID , page_IDFK columns from cms_element_instance so for this case you need a primary key based on ID , page_IDFK columns
ALTER TABLE `cms_element_instance` CHANGE `page_IDFK` `page_IDFK`
MEDIUMINT(8) UNSIGNED NOT NULL, DROP PRIMARY KEY,
ADD PRIMARY KEY (`ID`, `page_IDFK`);
Demo
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`)
I have two tables I have created and I'm adding the foreign key constraint after the fact.
The two tables are defined as such:
CREATE TABLE `user` (
`user_id` int(11) NOT NULL auto_increment,
`user_ad_id` varchar(500) default NULL,
`user_name` varchar(100) NOT NULL,
`login_id` varchar(100) default NULL,
`email` varchar(256) NOT NULL,
`personal_config` int(10) NOT NULL,
PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
and
CREATE TABLE IF NOT EXISTS personal_config (
config_id INT(10) NOT NULL AUTO_INCREMENT,
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
configuration TEXT(25600) NOT NULL,
PRIMARY KEY (config_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE personal_config ADD CONSTRAINT personal_config_fk_user FOREIGN KEY
(config_id) REFERENCES user(personal_config);
And I keep getting the same error but can't figure it out. I've searched all the related threads to this.
Your FK config_id can't be an autoincrement field, that doesn't make much sense right? That field reflects a value in the foreign table, it cannot be set arbitrarily in the local table.
I think this is what you want:
ALTER TABLE user ADD CONSTRAINT personal_config_fk_user FOREIGN KEY (personal_config) REFERENCES personal_config(config_id);
Your ALTER TABLE statement is backward. Since personal_config.config_id is an auto_increment primary key, the foreign key should be defined in the users table against personal_config, not in personal_config against the users table.
ALTER TABLE users ADD CONSTRAINT user_fk_personal_config
FOREIGN KEY (personal_config)
REFERENCES personal_config(config_id);
if you set your user table field personal_config is primary key then it is possible to execute
CREATE TABLE IF NOT EXISTS personal_config (
config_id INT(10) NOT NULL AUTO_INCREMENT,
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
configuration TEXT(25600) NOT NULL,
PRIMARY KEY (config_id), FOREIGN KEY
(config_id) REFERENCES user(personal_config)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;