mysql foreign key references same table field - mysql

I have this table
CREATE TABLE `product_category` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL,
`category_id` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `category_id` (`category_id`),
CONSTRAINT `category_id` FOREIGN KEY (`category_id`) REFERENCES `product_category` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB
What I'm trying to get is to delete on cascade every record which category_id fields equals to id field, but I cant insert any record, it gives me an error
cannot add or update a child row: a foreign key constraint fails('database/product_category', CONSTRAINT 'category_id FOREIGN KEY('category_id') REFERENCES product_category('id') ON DELETE CASCADE ON UPDATE CASCADE

Your foreigh key value must point to existing product_category (id), but there are no allowable rows in table. So make
category_id int(11) NULL,
instead your definition and insert first row like
INSERT INTO product_category SET name='test1';

Related

How to cascade delete from same MySQL table

Is it possible to cascade delete from same MySQL table? I want to cascade delete in a table that references itself in relations.
Example:
I have a comments table that has comment_id and parent_id, where parent_id is the same id in comment_id.
Parent_id could be either another comment_id or null if it's a root
comment.
I want to be able to select any node in this tree and delete it. In the process, all child nodes and sub-child nodes should be deleted.
I have tried to alter my table using this query
ALTER TABLE `comment`
ADD FOREIGN KEY (`comment_id`)
REFERENCES `comment`(`parent_id`) ON DELETE CASCADE ON UPDATE RESTRICT;
but I end up with an error
Cannot add or update a child row: a foreign key constraint fails
(zendaya001.#sql-6c1_1044ab, CONSTRAINT comment_ibfk_3 FOREIGN
KEY (comment_id) REFERENCES comment (parent_id) ON DELETE
CASCADE ON UPDATE RESTRICT)
For reproduction, this is my comment table:
CREATE TABLE `comment` (
`comment_id` int NOT NULL,
`post_id` int UNSIGNED NOT NULL,
`user_id` int NOT NULL,
`parent_id` int DEFAULT NULL,
`content` text NOT NULL,
`type` varchar(50) DEFAULT NULL,
`count_replies` int NOT NULL DEFAULT '0',
`count_likes` int NOT NULL DEFAULT '0',
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Indexes for table `comment`
--
ALTER TABLE `comment`
ADD PRIMARY KEY (`comment_id`),
ADD KEY `user_id` (`user_id`),
ADD KEY `post_id` (`post_id`),
ADD KEY `parent_id` (`parent_id`);
You try to create the foreign key with incorrect direction.
Must be:
ALTER TABLE `comment`
ADD FOREIGN KEY (`parent_id`)
REFERENCES `comment`(`comment_id`) ON DELETE CASCADE ON UPDATE RESTRICT;
https://dbfiddle.uk/iJRlziwL
comment_id must be defined at least UNIQUE (maybe PRIMARY KEY).
I cannot insert a new record into the table even if ON UPDATE RESTRICT is also set to CASCADE – Freesoul
You do something wrongly.
https://dbfiddle.uk/rcUupB2b

Adding multiple foreign key constraints

I am having trouble adding multiple foreign key constraints to this table. I get an error saying
Foreign key constraint is incorrectly formed
Both id's referenced are primary keys in their respective tables. What am I doing wrong?
CREATE TABLE `works_on` (
`eid` int(11) DEFAULT NULL,
`pid` int(11) DEFAULT NULL,
`start_date` date NOT NULL,
PRIMARY KEY (`eid`, `pid`),
CONSTRAINT `works_on_ibfk_1` FOREIGN KEY (`eid`)
REFERENCES `employee` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT `works_on_ibfk_2` FOREIGN KEY (`pid`)
REFERENCES `project` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB
You have a paradox here - you cannot have a primary key where any of the elements has a null values AND therefore you cannot on delete SET NULL..
You should also be seeing an error message telling you that the primary key is invalid..

MySQL multiple foreign key constraints on single table

I have 2 unrelated tables but each one has the same column type I called 'somefield'
CREATE TABLE `table1` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`somefield` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `somefield` (`somefield`),
)
CREATE TABLE `table2` (
`id` int(5) NOT NULL AUTO_INCREMENT,
`somefield` int(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `somefield` (`somefield`)
)
After I insert into either of these tables, I insert into this table the 'somefield' value.
CREATE TABLE `table3` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`somefield` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `somefield` (`somefield`),
CONSTRAINT `FK_table3` FOREIGN KEY (`somefield`) REFERENCES `table1` (`somefield`) ON DELETE CASCADE ON UPDATE CASCADE
)
At the moment, if i delete a row in table1, the same row is deleted in table3. I can insert into table1 and do an insert on table3 without any problems but if i insert into table2 and try to insert into table3 i get this error
Integrity constraint violation: 1452 Cannot add or update a child row:
a foreign key constraint fails
I know this is to do with the foreign key constraint in that it expects the 'somefield' value to be present in table1. What I want to know is how to add another constraint.
ALTER TABLE table3 ADD CONSTRAINT FK_table3 FOREIGN KEY (`somefield`) REFERENCES `table2` (`somefield`) ON DELETE CASCADE ON UPDATE CASCADE;
Would i need to create 2 tables to act as a go between for table1/table3 and table2/table3?
I was able to sort this by creating a table which the other 3 tables all link to.
If a row is deleted in the new table, the resulting rows are deleted in the other tables.
CREATE TABLE IF NOT EXISTS `table1` (
`id` tinyint(3) NOT NULL AUTO_INCREMENT,
`somefield` varchar(12) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `somefield` (`somefield`)
);
CREATE TABLE IF NOT EXISTS `table2` (
`id` tinyint(3) NOT NULL AUTO_INCREMENT,
`somefield` varchar(12) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `somefield` (`somefield`)
);
CREATE TABLE IF NOT EXISTS `table3` (
`id` tinyint(3) NOT NULL AUTO_INCREMENT,
`somefield` varchar(12) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `somefield` (`somefield`)
);
CREATE TABLE IF NOT EXISTS `supertable` (
`somefield` varchar(12) NOT NULL DEFAULT '',
PRIMARY KEY (`somefield`),
UNIQUE KEY `somefield` (`somefield`)
);
ALTER TABLE `table1`
ADD CONSTRAINT `FK_table1` FOREIGN KEY (`somefield`) REFERENCES `supertable` (`somefield`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `table2`
ADD CONSTRAINT `FK_table2` FOREIGN KEY (`somefield`) REFERENCES `supertable` (`somefield`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `table3`
ADD CONSTRAINT `FK_table3` FOREIGN KEY (`somefield`) REFERENCES `supertable` (`somefield`) ON DELETE CASCADE ON UPDATE CASCADE;

error upload db to mysql

-- Constraints for table `variation`
--
ALTER TABLE `variation`
ADD FOREIGN KEY (`parent`) REFERENCES `variation` (`id`),
ADD FOREIGN KEY (`scale`) REFERENCES `scale` (`id`),
ADD FOREIGN KEY (`user`) REFERENCES `users` (`user_id`);
--
error
ERROR 1452 (23000) at line 277: Cannot add or update a child row: a
foreign key constraint fails (getsy.#sql-f44_2a, CONSTRAINT
#sql-f44_2a_ibfk_2 FOREIGN KEY (scale) REFERENCES scale (id))
this table variation
CREATE TABLE IF NOT EXISTS `variation` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`parent` bigint(20) DEFAULT NULL,
`scale` bigint(20) DEFAULT NULL,
`value` varchar(255) NOT NULL,
`user` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `parent` (`parent`,`scale`,`value`,`user`),
KEY `scale` (`scale`),
KEY `user` (`user`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=101 ;
help me ..
thanks
Looks like that in variation table column scale contains values that are missing in table scale column id.
You can check missing values with following query:
SELECT DISTINCT a.scale FROM
variation AS a LEFT JOIN scale AS b ON a.scale = b.id
WHERE b.id IS NULL;

Foreign key constraint fails even when data types are the same

I'm building a table with a two part foreign key that references a two part key in another table. It isn't working, and I can't see why because the data types line up.
Can't create table 'tsugi.video_comments' (errno: 150)
Here's the code I'm trying to run:
CREATE TABLE `video_comments` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`video_id` varchar(11) NOT NULL DEFAULT '',
`link_id` int(11) NOT NULL,
`videoTime` int(11) NOT NULL,
`comment` text NOT NULL,
`parent` int(11) unsigned DEFAULT NULL,
`private` tinyint(1) DEFAULT NULL,
`replies` int(11) unsigned DEFAULT '0',
`reports` int(11) DEFAULT '0',
`user_id` int(11) NOT NULL,
`displayname` varchar(2048) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `video_ibfk_1` (`link_id`),
KEY `video_ibfk_2` (`user_id`),
CONSTRAINT `video_comments_ibfk_1` FOREIGN KEY (`parent`) REFERENCES `video_comments` (`id`) ON DELETE CASCADE,
CONSTRAINT `video_ibfk_1` FOREIGN KEY (`link_id`) REFERENCES `lti_link` (`link_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `video_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `lti_user` (`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `video_key` FOREIGN KEY (`link_id`, `video_id`) REFERENCES `video_ids` (`link_id`, `video_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=285 DEFAULT CHARSET=utf8;
The command runs successfully if I delete the last constraint, so that's where the problem is, not in the other constraints.
Here's the table it's referencing:
CREATE TABLE `video_ids` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`video_id` varchar(11) NOT NULL DEFAULT '',
`link_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `video_key` (`video_id`,`id`),
KEY `link_id` (`link_id`),
KEY `id` (`id`,`video_id`),
CONSTRAINT `video_ids_ibfk_1` FOREIGN KEY (`link_id`) REFERENCES `t_lti_link` (`link_id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
To make sure that the video_id and link_id fields are exactly the same, I copied them directly from the existing table's code to the code for creating the new table. I expected that to solve it, but it did not. Here's the error log:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
141114 22:04:09 Error in foreign key constraint of table tsugi/video_comments:
FOREIGN KEY (`link_id`, `video_id`) REFERENCES `video_ids` (`link_id`, `video_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=285 DEFAULT CHARSET=utf8:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
Foreign key references need to be to unique or primary keys. So, you can fix this just by having a unique declaration in video_ids:
CREATE TABLE `video_ids` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`video_id` varchar(11) NOT NULL DEFAULT '',
`link_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `video_key` (`video_id`,`id`),
KEY `link_id` (`link_id`),
KEY `id` (`id`,`video_id`),
UNIQUE (link_id, video_id),
CONSTRAINT `video_ids_ibfk_1` FOREIGN KEY (`link_id`) REFERENCES `t_lti_link` (`link_id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
Here is a SQL Fiddle with an example.