create a table relation on itself in mysql - mysql

I have a table like so:
CREATE TABLE `jngi_category` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`Name` varchar(50) NOT NULL,
`parent` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
and i want, when a parent delete all of it's child delete so.
if there is any relations that defines by foreign-key so it do that automatically is good.

Add a foreign key constraint on this column parent with ON DELETE CASCADE:
CONSTRAINT `FK_ParentCategory` FOREIGN KEY (`parent`)
REFERENCES jngi_category(id) ON DELETE CASCADE ON UPDATE CASCADE
SQL Fiddle Demo

Try this sql
CREATE TABLE jngi_category (
id int(11) NOT NULL auto_increment,
Name varchar(50) NOT NULL,
parent int(11),
PRIMARY KEY (id),
foreign key (parent) references jngi_category(id) on delete cascade
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 ;

Related

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.

SQLSTATE[HY000] error when creating a table?

This is my SQL:
CREATE TABLE mytable (
`id` int(11) NOT NULL AUTO_INCREMENT,
`customer_id` int(10) NOT NULL,
`token` varchar(100),
`created_at` datetime,
PRIMARY KEY (`id`),
CONSTRAINT `FK_PASSWORD_RECOVERY_CUSTOMER` FOREIGN KEY (`customer_id`) REFERENCES `customer_entity` (`entity_id`) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1
Its always giving me: Can't create table 'mytable' (errno: 150) SQL.sql
As posted in my comment to your question, the error you are getting has to do with the constraint definition. You should then check the proper syntax for the constraint.
I think the problem is that you are not indexing the customer_id column. Try to index it:
CREATE TABLE mytable (
`id` int(11) NOT NULL AUTO_INCREMENT,
`customer_id` int(10) NOT NULL,
`token` varchar(100),
`created_at` datetime,
PRIMARY KEY (`id`),
INDEX cust_id(customer_id), -- ADD THIS
FOREIGN KEY (`customer_id`)
REFERENCES `customer_entity` (`entity_id`)
ON UPDATE CASCADE
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
(just as a precaution and dumb-check, verify that customer_entity is also an InnoDB table)

MySQL Nullable FK and the 150 error

I have a problem with create table statement in MySQL.
The scenario is, I want to have a table P_CDP wchich stores some informations, and the table P_CDPFiles which stores the data of the uploaded files.
The column SelectedCDPFileID by default should be NULL unless the user selects some file. Then that column is filled by the file ID. But, I'm still getting the errno 150, why ? I think the FK names are set properly
CREATE TABLE `P_CDP` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`P_OrderID` int(11) NOT NULL DEFAULT '0',
`SelectedCDPFileID` int(11) NULL,
PRIMARY KEY (`ID`),
KEY `FK_P_CDP_P_Orders` (`P_OrderID`),
KEY `FK_P_CDP_P_CDPFiles` (`SelectedCDPFileID`),
CONSTRAINT `FK_P_CDP_P_Orders` FOREIGN KEY (`P_OrderID`) REFERENCES `P_Orders` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_P_CDP_P_CDPFiles` FOREIGN KEY (`SelectedCDPFileID`) REFERENCES `P_CDPFiles` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
CREATE TABLE `P_CDPFiles` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`FileID` int(11) NOT NULL DEFAULT '0',
`P_CDPID` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `FK_P_CDPFiles_File` (`FileID`),
KEY `FK_P_CDPFiles_P_CDP` (`P_CDPID`),
CONSTRAINT `FK_P_CDPFiles_File` FOREIGN KEY (`FileID`) REFERENCES `File` (`FileID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_P_CDPFiles_P_CDP` FOREIGN KEY (`P_CDPID`) REFERENCES `P_CDP` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
You're attempting to reference a table that does not yet exist.
If you must have references in both directions between these two tables (which generally indicates quite poor design), you will have to:
Create the first table without any reference to the as-yet-undefined table:
CREATE TABLE `P_CDP` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`P_OrderID` int(11) NOT NULL DEFAULT '0',
`SelectedCDPFileID` int(11) NULL,
PRIMARY KEY (`ID`),
KEY `FK_P_CDP_P_Orders` (`P_OrderID`),
KEY `FK_P_CDP_P_CDPFiles` (`SelectedCDPFileID`),
CONSTRAINT `FK_P_CDP_P_Orders` FOREIGN KEY (`P_OrderID`)
REFERENCES `P_Orders` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Create the second table, including its reference to the first table:
CREATE TABLE `P_CDPFiles` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`FileID` int(11) NOT NULL DEFAULT '0',
`P_CDPID` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `FK_P_CDPFiles_File` (`FileID`),
KEY `FK_P_CDPFiles_P_CDP` (`P_CDPID`),
CONSTRAINT `FK_P_CDPFiles_File` FOREIGN KEY (`FileID`)
REFERENCES `File` (`FileID`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_P_CDPFiles_P_CDP` FOREIGN KEY (`P_CDPID`)
REFERENCES `P_CDP` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Alter the first table to add the intended constraint:
ALTER TABLE `P_CDP`
ADD CONSTRAINT `FK_P_CDP_P_CDPFiles` FOREIGN KEY (`SelectedCDPFileID`)
REFERENCES `P_CDPFiles` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION;

MySQL foreign keys with non-identifying relationships

All I need is to create 2 tabeles with next structure:
The SQL:
CREATE TABLE IF NOT EXISTS `ds_cats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE IF NOT EXISTS `module_news_cats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent` int(11) NOT NULL,
`cat_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_module_news_cats_module_news_cats` (`parent`),
KEY `fk_module_news_cats_ds_cats1` (`cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
ALTER TABLE `module_news_cats`
ADD CONSTRAINT `fk_module_news_cats_ds_cats1` FOREIGN KEY (`cat_id`) REFERENCES `ds_cats` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_module_news_cats_module_news_cats` FOREIGN KEY (`parent`) REFERENCES `module_news_cats` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;
But when I try to insert first row to my table "module_news_cats", I recive next error:
#1452 - Cannot add or update a child row: a foreign key constraint fails (`empty`.`module_news_cats`, CONSTRAINT `fk_module_news_cats_module_news_cats` FOREIGN KEY (`parent`) REFERENCES `module_news_cats` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Question:
How I can create table which will have an index with non-identifying relationship to the anther index in the same table? Some rows will have parents, and some not.
I think you just need to allow NULLs in module_news_cats.parent:
CREATE TABLE IF NOT EXISTS `module_news_cats` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent` int(11) NULL, -- Change this
`cat_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_module_news_cats_module_news_cats` (`parent`),
KEY `fk_module_news_cats_ds_cats1` (`cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
and then if there isn't a parent, create the row with a NULL in parent.
Your 'parent' field cannot be empty (NULL) if you insert a record, which means that every record you insert should refer to a parent ID (which is impossible if there are no entries in your table yet).
If you make the 'parent' field in the module_news_cats table nullable:
ALTER TABLE `module_news_cats` CHANGE `parent` `parent` INT( 11 ) NULL DEFAULT NULL
you should be able to insert records that have no parent ID associated (just supply NULL instead of a value).
You could make the parent column in the module_news_cats table nullable.
Then for rows that have no parents populate the parent column with null.

How to update foreign key value in mysql database

I have three tables: categories, languages and categories_languages. Categories_languages is many to many table which links together categories and languages. I would like to update a foregin key value in table languages but it throws me error #1451 - Cannot delete or update a parent row: a foreign key constraint fails!
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(11) unsigned NOT NULL auto_increment,
`name` varchar(20) NOT NULL,
`modified` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `languages` (
`id` char(2) NOT NULL,
`name` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `categories_languages` (
`id` int(11) unsigned NOT NULL auto_increment,
`category_id` int(11) unsigned NOT NULL,
`language_id` char(2) NOT NULL,
`translation` varchar(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `fk_category_id_language_id` (`category_id`,`language_id`),
KEY `fk_language_id` (`language_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
ALTER TABLE `categories_languages`
ADD CONSTRAINT `categories_languages_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE,
ADD CONSTRAINT `categories_languages_ibfk_2` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`) ON DELETE CASCADE;
The error is clear to me, but how can I update a key value in this case? I tried adding ON UPDATA CASCADE:
ALTER TABLE `categories_languages`
ADD CONSTRAINT `categories_languages_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `categories_languages_ibfk_2` FOREIGN KEY (`language_id`) REFERENCES `languages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
but that also fails with message: MySQL said: Documentation #1005 - Can't create table './db_dodo/#sql-c2f_80e6f.frm' (errno: 121)
You can temporarily suspend foreign key checking:
SET foreign_key_checks = 0;
UPDATE languages SET id='xyz' WHERE id='abc';
UPDATE categories_languages SET language_id='xyz' WHERE language_id='abc';
SET foreign_key_checks = 1;
EDIT: As for the foreign key problem: is the data stored on a local or a remote file system? errno 121 is EREMOTEIO (Remote I/O error). Perhaps there are permission problems on the target file system or it doesn't support the # character in filenames?
If you are looking for a temp solution you can also change the ON UPDATE action to CASCADE and modify your ids