Mysql on delete cascade not working - mysql

i have the tables:
DROP TABLE IF EXISTS `files`;
CREATE TABLE IF NOT EXISTS `files` (
`id` VARCHAR(36) NOT NULL,
`name` VARCHAR(50) NOT NULL,
`extension` VARCHAR(5) NOT NULL,
`version` INT(11) NOT NULL,
`date` DATE NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
and TagsFiles:
DROP TABLE If EXISTS `tags_files`;
CREATE TABLE IF NOT EXISTS `tags_files` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`tag_id` INT(11) NOT NULL,
`file_id` VARCHAR(36) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT FOREIGN KEY (`file_id`) REFERENCES `files` (`id`) ON DELETE CASCADE
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
if i now delete one or more entries of the tags_files table, there are no entries in files deleted. Can someone tell me why?

The constrain you have now will delete from tags_files when a referenced id will be deleted on files.
If you need to automatically delete from files when you delete from tags_files, then the constrain must be on files table.
Like this:
DROP TABLE IF EXISTS `files`;
CREATE TABLE IF NOT EXISTS `files` (
`id` VARCHAR(36) NOT NULL,
`name` VARCHAR(50) NOT NULL,
`extension` VARCHAR(5) NOT NULL,
`version` INT(11) NOT NULL,
`date` DATE NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT FOREIGN KEY (`id`) REFERENCES `tags_files` (`file_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
and TagsFiles:
DROP TABLE If EXISTS `tags_files`;
CREATE TABLE IF NOT EXISTS `tags_files` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`tag_id` INT(11) NOT NULL,
`file_id` VARCHAR(36) NOT NULL,
PRIMARY KEY (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
Well you get an error in above example because MySQL don't allow constraints for varchar type. If you change it to char you can. But you also need to change the sequence of the execution queries due to constrains. Do like this:
DROP TABLE IF EXISTS `files`;
DROP TABLE If EXISTS `tags_files`;
CREATE TABLE IF NOT EXISTS `tags_files` (
`id` INT(11) NOT NULL,
`tag_id` INT(11) NOT NULL,
`file_id` char(36) NOT NULL,
PRIMARY KEY (`file_id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `files` (
`id` char(36) NOT NULL,
`name` VARCHAR(50) NOT NULL,
`extension` VARCHAR(5) NOT NULL,
`version` INT(11) NOT NULL,
`date` DATE NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT FOREIGN KEY (`id`) REFERENCES `tags_files` (`file_id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Related

Cannot add foreign key constraint

I have created a database "webportal". and this is my "user" table script
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`firstName` varchar(255) DEFAULT NULL,
`lastName` varchar(255) DEFAULT NULL,
`dateRegistered` DATE DEFAULT NULL,
`skypeID` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
and this one is "catalog" table script.
DROP TABLE IF EXISTS `catalog`;
create table catalog(
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`link` VARCHAR(100) NOT NULL,
`comment` VARCHAR(100) NOT NULL,
`inserDate` DATE DEFAULT NULL,
`content` longblob NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_catalog` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
and when I try to execute the second script in the command line, I get this error...
ERROR 1215 (HY000): Cannot add foreign key constraint.
What is wrong with this code?
It seems you are using a old version of MySQL, you can add a INDEX clause to foreign key field to fix the problem:
DROP TABLE IF EXISTS `catalog`;
create table `catalog`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`link` VARCHAR(100) NOT NULL,
`comment` VARCHAR(100) NOT NULL,
`inserDate` DATE DEFAULT NULL,
`content` longblob NOT NULL,
PRIMARY KEY (`id`),
INDEX (`user_id`),
CONSTRAINT `fk_catalog` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Should I use one mapping table for multiple data-type tables, or create different mapping tables for each data-type?

At the moment I have one huge tag table and I use mapping table to map tags with another mapping table to map with data table. The reason I added another mapping-to-data table is that I have multiple different data tables.
There are two data tables:
CREATE TABLE IF NOT EXISTS `cars_list` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) default NULL,
`description` varchar(255) default NULL,
`photo` varchar(45) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `website_list` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) default NULL,
`description` varchar(255) default NULL,
`url` varchar(255) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Both of them I use in my search fields, and they should be linked to one TAG list table
There's tag table:
CREATE TABLE IF NOT EXISTS `tags` (
`tag_id` int(11) NOT NULL auto_increment,
`tag` varchar(255) default NULL,
PRIMARY KEY (`tag_id`),
UNIQUE KEY `tag` (`tag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
And what I do - I use two more tables to map data tables with tags:
Two mapping tables:
CREATE TABLE IF NOT EXISTS `tags_map_type` (
`tmtid` int(11) NOT NULL auto_increment,
`type` enum('cars_list','website_list') NOT NULL,
`type_id` int(11) NOT NULL,
PRIMARY KEY (`tmtid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `tags_map` (
`tmid` int(11) NOT NULL auto_increment,
`map_type_id` int(11) NOT NULL,
`tag_id` int(11) NOT NULL,
PRIMARY KEY (`tmid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `tags_map`
ADD CONSTRAINT `tag_id` FOREIGN KEY (`tag_id`) REFERENCES `tags` (`tag_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `map_type_id` FOREIGN KEY (`map_type_id`) REFERENCES `tags_map_type` (`tmtid`) ON DELETE CASCADE ON UPDATE CASCADE;
And table tags_map_type then links either to cars_list or to website_list
QUESTION:
How can I make a foreign key to link tags_map_type to one of the list tables?
Or should I use another mapping table for each cars_list, website_list, some_other_list table?
Which way is correct and best to use?

how to get autoincrement ID of one table and insert in another table

I have a mysql table whose description is given below
Create Table
CREATE TABLE `question` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`category` varchar(255) DEFAULT NULL,
`is_deleted` bit(1) NOT NULL,
`question` varchar(255) DEFAULT NULL,
`version` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8
I have another table
Create Table
CREATE TABLE `parent_question` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`is_deleted` bit(1) NOT NULL,
`version` int(11) DEFAULT NULL,
`pid` bigint(20) NOT NULL,
`qid` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK8FEA83DBE860AF9` (`pid`),
KEY `FK8FEA83DBF34C20F6` (`qid`),
CONSTRAINT `FK8FEA83DBE860AF9` FOREIGN KEY (`pid`) REFERENCES `parent` (`id`),
CONSTRAINT `FK8FEA83DBF34C20F6` FOREIGN KEY (`qid`) REFERENCES `question` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8
I have the right to insert one row in the question table.So when I add a new row then id will be generated (because it is auto_increment) and I want to store this id in the qid field parent_question table.
Can anybody please tell me how to do it?
Use the last_insert_id() function:
insert into question values (...);
insert into parent_question values (..., last_insert_id(), ...);

Cannot create foreign key in MySQL error: 150

I have created the following tables and have no idea why my foreign key constraint script is not working.
CREATE TABLE IF NOT EXISTS `project` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`project_id` varchar(60) NOT NULL,
`project_name` varchar(500) NOT NULL,
`cons_bal` int(11) NOT NULL,
`non_cons_bal` int(11) NOT NULL,
`budget_head` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
And here is my another table:
CREATE TABLE IF NOT EXISTS `project_map` (
`id` int(11) NOT NULL,
`project_id` varchar(60) NOT NULL,
`head` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
And here is my add constraint line:
alter table project_map add constraint p_map_fk001 foreign key (`project_id`) references project(`project_id`)
Any help would be nice. Thank you.
In the referenced table, there must be an index where the referenced columns are listed as the first columns in the same order.
Refer: http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html
So try:
CREATE TABLE `project` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`project_id` varchar(60) NOT NULL,
`project_name` varchar(500) NOT NULL,
`cons_bal` int(11) NOT NULL,
`non_cons_bal` int(11) NOT NULL,
`budget_head` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
KEY `project_id` (`project_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `project_map` (
`id` int(11) NOT NULL,
`project_id` varchar(60) NOT NULL,
`head` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `project_id` (`project_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
ALTER TABLE `project_map` ADD CONSTRAINT
`p_map_fk001` FOREIGN KEY (`project_id`)
REFERENCES project(`project_id`);

Importing a database schema from a SQL DUMP

I have the following database schema that has a bunch of tables and foreign keys, when i try to import the sql dump i keep getting the following errors.
Can't create table errno 150
I understand that it is trying to create tables with dependencies of tables that are not created yet but i don't understand how to import the schema without butchering out all of the foreign keys and then re-creating them per the answers given on Stack and google.
There has to be an easier way, what do big companies do that have hundreds of tables?
I have the sql statements below and any suggestions would be appreciated. Thanks
#
# Encoding: Unicode (UTF-8)
#
DROP TABLE IF EXISTS `contact_interest`;
DROP TABLE IF EXISTS `contact_seeking`;
DROP TABLE IF EXISTS `interests`;
DROP TABLE IF EXISTS `job_current`;
DROP TABLE IF EXISTS `job_desired`;
DROP TABLE IF EXISTS `job_listings`;
DROP TABLE IF EXISTS `my_contacts`;
DROP TABLE IF EXISTS `profession`;
DROP TABLE IF EXISTS `seeking`;
DROP TABLE IF EXISTS `status`;
DROP TABLE IF EXISTS `zip_code`;
CREATE TABLE `contact_interest` (
`contact_id` int(10) unsigned NOT NULL,
`interest_id` int(10) unsigned NOT NULL,
KEY `mycontacts_contactinterest_fk` (`contact_id`),
KEY `interests_contactinterest_fk` (`interest_id`),
CONSTRAINT `mycontacts_contactinterest_fk` FOREIGN KEY (`contact_id`) REFERENCES `my_contacts` (`contact_id`),
CONSTRAINT `interests_contactinterest_fk` FOREIGN KEY (`interest_id`) REFERENCES `interests` (`interest_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `contact_seeking` (
`contact_id` int(10) unsigned NOT NULL,
`seeking_id` int(10) unsigned NOT NULL,
KEY `contactid_contactseeking_fk` (`contact_id`),
KEY `seeking_contactseeking_fk` (`seeking_id`),
CONSTRAINT `contactid_contactseeking_fk` FOREIGN KEY (`contact_id`) REFERENCES `my_contacts` (`contact_id`),
CONSTRAINT `seeking_contactseeking_fk` FOREIGN KEY (`seeking_id`) REFERENCES `seeking` (`seeking_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `interests` (
`interest_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`interest` varchar(50) DEFAULT NULL,
PRIMARY KEY (`interest_id`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=latin1;
CREATE TABLE `job_current` (
`contact_id` int(10) unsigned NOT NULL,
`title` varchar(20) DEFAULT NULL,
`salary` decimal(8,2) DEFAULT NULL,
`start_date` date DEFAULT NULL,
KEY `mycontacts_jobcurrent_fk` (`contact_id`),
CONSTRAINT `mycontacts_jobcurrent_fk` FOREIGN KEY (`contact_id`) REFERENCES `my_contacts` (`contact_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `job_desired` (
`contact_id` int(10) unsigned NOT NULL,
`title` varchar(20) DEFAULT NULL,
`salary_low` decimal(8,2) DEFAULT NULL,
`salary_high` decimal(8,2) DEFAULT NULL,
`available` date DEFAULT NULL,
`years_exp` int(11) DEFAULT NULL,
KEY `mycontacts_jobdesired_fk` (`contact_id`),
CONSTRAINT `mycontacts_jobdesired_fk` FOREIGN KEY (`contact_id`) REFERENCES `my_contacts` (`contact_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `job_listings` (
`job_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(25) DEFAULT NULL,
`salary` decimal(8,2) DEFAULT NULL,
`zip_code` char(5) DEFAULT NULL,
`description` varchar(50) DEFAULT NULL,
PRIMARY KEY (`job_id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
CREATE TABLE `my_contacts` (
`contact_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`last_name` varchar(30) DEFAULT NULL,
`first_name` varchar(20) DEFAULT NULL,
`phone` char(10) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`gender` char(1) DEFAULT NULL,
`birthday` date DEFAULT NULL,
`prof_id` int(11) unsigned NOT NULL,
`status_id` int(10) unsigned NOT NULL,
`zip_code` char(5) DEFAULT NULL,
PRIMARY KEY (`contact_id`),
KEY `profession_mycontacts_fk` (`prof_id`),
KEY `zipcode_mycontacts_fk` (`zip_code`),
KEY `status_my_contacts_fk` (`status_id`),
CONSTRAINT `profession_mycontacts_fk` FOREIGN KEY (`prof_id`) REFERENCES `profession` (`prof_id`),
CONSTRAINT `status_my_contacts_fk` FOREIGN KEY (`status_id`) REFERENCES `status` (`status_id`),
CONSTRAINT `zipcode_mycontacts_fk` FOREIGN KEY (`zip_code`) REFERENCES `zip_code` (`zip_code`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=latin1;
CREATE TABLE `profession` (
`prof_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`profession` varchar(30) DEFAULT NULL,
PRIMARY KEY (`prof_id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=latin1;
CREATE TABLE `seeking` (
`seeking_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`seeking` varchar(40) DEFAULT NULL,
PRIMARY KEY (`seeking_id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=latin1;
CREATE TABLE `status` (
`status_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`status` varchar(30) DEFAULT NULL,
PRIMARY KEY (`status_id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
CREATE TABLE `zip_code` (
`zip_code` char(5) NOT NULL DEFAULT '',
`city` varchar(20) DEFAULT NULL,
`state` char(2) DEFAULT NULL,
PRIMARY KEY (`zip_code`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I found that I only needed two lines to fix my issue, I added one 0 at the top and 1 at the bottom and I was good. Sorry to waste your time...
SET FOREIGN_KEY_CHECKS = 0;
SET FOREIGN_KEY_CHECKS = 1;
the easiest way would be to do it via commandline like this:
mysql db_name < backup-file.sql
this executes your sql file in one transaction. If you execute your stuff in one transaction then you won't get the foreign key errors.