How do I use on delete cascade in mysql? - mysql

I have a database of components. Each component is of a specific type. That means there is a many-to-one relationship between a component and a type. When I delete a type, I would like to delete all the components which has a foreign key of that type. But if I'm not mistaken, cascade delete will delete the type when the component is deleted. Is there any way to do what I described?

Here's what you'd include in your components table.
CREATE TABLE `components` (
`id` int(10) unsigned NOT NULL auto_increment,
`typeId` int(10) unsigned NOT NULL,
`moreInfo` VARCHAR(32),
-- etc
PRIMARY KEY (`id`),
KEY `type` (`typeId`)
CONSTRAINT `myForeignKey` FOREIGN KEY (`typeId`)
REFERENCES `types` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
)
Just remember that you need to use the InnoDB storage engine: the default MyISAM storage engine doesn't support foreign keys.

use this sql
DELETE T1, T2
FROM T1
INNER JOIN T2 ON T1.key = T2.key
WHERE condition

You have to define your Foreign Key constraints as ON DELETE CASCADE.
Note: You need to use InnoDB storage engine, the default MyISAM storage engine not support foreign keys relation.
CREATE TABLE `table2` (
`id` int(11) NOT NULL auto_increment,
`name` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `ids` (`ids`)
CONSTRAINT `foreign` FOREIGN KEY (`ids`)
REFERENCES `table2` (`ids`) ON DELETE CASCADE ON UPDATE CASCADE
)

Step 1. Create the buildings table:
CREATE TABLE buildings (
building_no INT PRIMARY KEY AUTO_INCREMENT,
building_name VARCHAR(255) NOT NULL,
address VARCHAR(255) NOT NULL
);
Step 2. Create the rooms table:
CREATE TABLE rooms (
room_no INT PRIMARY KEY AUTO_INCREMENT,
room_name VARCHAR(255) NOT NULL,
building_no INT NOT NULL,
FOREIGN KEY (building_no)
REFERENCES buildings (building_no)
ON DELETE CASCADE
);
Notice that the ON DELETE CASCADE clause at the end of the foreign key constraint
definition.

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

ER_FK_NO_INDEX_PARENT: Failed to add the foreign key constaint

Hey so I'm on my first project with a complexe database :)
I have created all of my tables and I am now updating them to add the Foreign Keys (I had an issue so I decided to add Foreign Keys after creating all the tables).
Here the ERR Diagram that describe the project : click to open
The exact error i get : ER_FK_NO_INDEX_PARENT: Failed to add the foreign key constaint. Missing index for constraint 'fk_user_in_org__org_roles1' in the referenced table 'org_roles'
I've searched my error but i didn't found a solution to my problem here some of the best I found :
Link 1
Link 2
The tables concerned (simplified) and the update command :
------------------
-- Tables setup --
------------------
-- A role is unique for an org but differents orgs can have a role that have the same label
CREATE TABLE IF NOT EXISTS students.org_roles (
`org_id` INT NOT NULL,
`label` VARCHAR(32) NOT NULL,
PRIMARY KEY (`org_id`, `label`))
ENGINE = InnoDB;
-- The users are unique
CREATE TABLE IF NOT EXISTS students.users (
`id` INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
UNIQUE INDEX id_UNIQUE (`id` ASC));
-- The orgs are unique
CREATE TABLE IF NOT EXISTS students.organizations (
`id` INT NOT NULL AUTO_INCREMENT,
`name` TEXT(64) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX id_UNIQUE (`id` ASC))
ENGINE = InnoDB;
-- The table that match a user in an org with a specified role (= label in the org_role table)
CREATE TABLE IF NOT EXISTS students.user_in_org (
`user_id` INT NOT NULL,
`org_id` INT NOT NULL,
`role` TEXT(32) NOT NULL,
PRIMARY KEY (`user_id`, `org_id`),
UNIQUE INDEX `user_id_UNIQUE` (`user_id` ASC));
------------------------
-- The update command --
------------------------
ALTER TABLE students.user_in_org ADD
(CONSTRAINT fk_user_in_org__users1
FOREIGN KEY (`user_id`) REFERENCES students.users(`id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT fk_user_in_org__organizations1
FOREIGN KEY (`org_id`) REFERENCES students.organizations(`id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT fk_user_in_org__org_roles1
FOREIGN KEY (`role`) REFERENCES students.org_roles(`label`)
ON DELETE RESTRICT
ON UPDATE CASCADE);
Thank you in advance for your help :)
And please forgive me if my english isn't that fluent :/
This can be because the table students.org_roles doesn't have Unique index in the field org_id, it is what error says
For
CONSTRAINT fk_user_in_org__org_roles1
FOREIGN KEY (`role`) REFERENCES students.org_roles(`label`)
You need a index on the table org_roles for the column label
CREATE TABLE IF NOT EXISTS students.org_roles (
`org_id` INT NOT NULL,
`label` VARCHAR(32) NOT NULL,
KEy (`label`),
PRIMARY KEY (`org_id`, `label`))
ENGINE = InnoDB;
In your origi8nal design you have a combined primary key so you can only make a reference to the combined primary key or define a new one for label
CREATE TABLE IF NOT EXISTS org_roles (
`org_id` INT NOT NULL,
`label` VARCHAR(32) NOT NULL,
PRIMARY KEY (`org_id`, `label`))
ENGINE = InnoDB;
-- The users are unique
CREATE TABLE IF NOT EXISTS users (
`id` INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`),
UNIQUE INDEX id_UNIQUE (`id` ASC));
-- The orgs are unique
CREATE TABLE IF NOT EXISTS organizations (
`id` INT NOT NULL AUTO_INCREMENT,
`name` TEXT(64) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX id_UNIQUE (`id` ASC))
ENGINE = InnoDB;
-- The table that match a user in an org with a specified role (= label in the org_role table)
CREATE TABLE IF NOT EXISTS user_in_org (
`user_id` INT NOT NULL,
`org_id` INT NOT NULL,
`role` TEXT(32) NOT NULL,
PRIMARY KEY (`user_id`, `org_id`),
UNIQUE INDEX `user_id_UNIQUE` (`user_id` ASC));
ALTER TABLE user_in_org ADD
(CONSTRAINT fk_user_in_org__users1
FOREIGN KEY (`user_id`) REFERENCES users(`id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT fk_user_in_org__organizations1
FOREIGN KEY (`org_id`) REFERENCES organizations(`id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT fk_user_in_org__org_roles1
FOREIGN KEY (`org_id`,`role`) REFERENCES org_roles(`org_id`,`label`)
ON DELETE RESTRICT
ON UPDATE CASCADE);
db<>fiddle here

How to link one to many relationship with multiple keys pointing on the same table id?

I have a table files and a table users and staff and client.
The file table contain a row made_by a row published_byand a row about_client pointing to a staff, a staff and a client respectively.
One user must be either a staff or a client.
One file can have multiple author (made_by row), but only one user can publish it (published_by), and it can only be about one client (about_client).
First, I put 3 foreign key on files:
CONSTRAINT `made_by_fk` FOREIGN KEY (`made_by`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `published_by_fk` FOREIGN KEY (`published_by`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `about_client_fk` FOREIGN KEY (`about_client`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
but after a little research, I found out that I should put the foreign key on staff / client, and here come the problem, the fk are OPTIONAL. A staff is not obligatory an author of a file, or the client maybe don't have any file attached to it.
I am a bit lost.
DROP TABLE IF EXISTS `files`;
CREATE TABLE IF NOT EXISTS `files` (
`id` INT NOT NULL AUTO_INCREMENT
PRIMARY KEY,
`made_by` INT NOT NULL,
`published_by` INT NOT NULL,
`about_client` INT NOT NULL,
`creation_date` DATETIME NOT NULL,
`modification_date` DATETIME NULL
ON UPDATE CURRENT_TIMESTAMP,
`path` VARCHAR(255) NOT NULL,
`title` VARCHAR(100) NOT NULL UNIQUE,
`category` INT NOT NULL,
`type` VARCHAR(30) NOT NULL,
`size` INT NOT NULL,
CONSTRAINT `made_by_fk` FOREIGN KEY (`made_by`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `published_by_fk` FOREIGN KEY (`published_by`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `about_client_fk` FOREIGN KEY (`about_client`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
)
ENGINE = InnoDB
COLLATE = utf8_unicode_ci;
DROP TABLE IF EXISTS `staff`;
CREATE TABLE IF NOT EXISTS `staff` (
`id` INT NOT NULL AUTO_INCREMENT
PRIMARY KEY,
`job` INT NOT NULL,
`password` VARCHAR(255) NOT NULL
)
ENGINE = InnoDB
COLLATE = utf8_unicode_ci;
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
`id` INT NOT NULL AUTO_INCREMENT
PRIMARY KEY,
`name` VARCHAR(100) NOT NULL,
`surname` VARCHAR(100) NOT NULL,
`email` VARCHAR(50) NOT NULL UNIQUE
)
ENGINE = InnoDB
COLLATE = utf8_unicode_ci;
DROP TABLE IF EXISTS `clients`;
CREATE TABLE IF NOT EXISTS `clients` (
`id` INT NOT NULL AUTO_INCREMENT
PRIMARY KEY,
`phone` VARCHAR(30) NOT NULL,
`age` INT NOT NULL,
`date_of_birth` DATE NOT NULL,
`security_number` VARCHAR(99) NOT NULL UNIQUE
)
ENGINE = InnoDB
COLLATE = utf8_unicode_ci;
If there can be multiple made_by, it can't be a column in the file table, since that can only contain one value.
You need another table, file_made_by that represents the many-to-many relationship between files and authors.
CREATE TABLE file_made_by (
file_id INT NOT NULL,
author_id INT NOT NULL,
PRIMARY KEY (file_id, author_id),
FOREIGN KEY (file_id) REFERENCES files (id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (author_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE
);
The clients and staff tables should also include a user_id column that's a foreign key to users.id.
If about_client has to be about a client, not staff, then it should be a foreign key to clients.id rather than users.id.
And if only staff are allowed to be authors, file_made_by.author_id should be a FK to staff.id rather than users.id. The same with files.published_by.

MySQL ON DELETE CASCADE not work

i have two table (type innoDb) why when i deleting main table row like
+note(im using arch os so my database server type is maria db)
DELETE FROM buildings
WHERE
building_no = 2;
relation table rows dont delete ???
CREATE TABLE buildings (
building_no INT PRIMARY KEY AUTO_INCREMENT,
building_name VARCHAR(255) NOT NULL,
address VARCHAR(255) NOT NULL
);
CREATE TABLE rooms (
room_no INT PRIMARY KEY AUTO_INCREMENT,
room_name VARCHAR(255) NOT NULL,
building_no INT NOT NULL,
FOREIGN KEY (building_no)
REFERENCES buildings (building_no)
ON DELETE CASCADE
);
This syntax works for me on MySQL database but i can't see issues in your query too
CREATE TABLE `rooms` (
room_no INT PRIMARY KEY AUTO_INCREMENT,
room_name VARCHAR(255) NOT NULL,
building_no INT NOT NULL,
CONSTRAINT `FK_rooms_1` FOREIGN KEY (`building_no`) REFERENCES `buildings`
(`building_no`) ON DELETE CASCADE
) ENGINE=InnoDB;
or add the constraint after table creation
ALTER TABLE `rooms`
ADD CONSTRAINT `FK_rooms_1` FOREIGN KEY (`building_no`) REFERENCES `buildings` (`building_no`) ON DELETE CASCADE ON UPDATE CASCADE;

Can't delete tuple in a relationship table when part of the tuple is used in another table (but whole tuple is not in that other table)

I have 4 tables:
studyLkup with StudyID as primary key
interviewerLkup with InterviewerID as primary key
studyInterviewers with StudyID and InterviewerID as primary key
participant with participantID as primary key and StudyID and InterviewerID as foreign keys referencing the studyLkup and studyInterviewers tables respectively.
I want to be able to delete a study/interviewer relationhip if the interviewer is not used in a particular study. I do not want to delete the interviewer out of the interviewerLkup table, just from the studyInterviewers table.
The problem I am having is that if the interviewer is used at all in the participant table (for another study), it won't let me delete the study/interviewer relationship.
Note that I want to delete a specific tuple. I do not want to delete all study/interviewers that are not used in the participant table. I am using the deletion process to delete a specific interviewer that has been incorrectly assigned to a particular study.
Can someone explain how to do this?
The php/mySql code I'm unsuccessfully using is:
$sql1 = "DELETE FROM studyinterviewers
WHERE (StudyID = '".$StudyID."')
AND (InterviewerID = '".$InterviewerID."');";
sql code for this mini schema is given below. Have I set my foreign keys in the participant table correctly?
CREATE TABLE IF NOT EXISTS `interviewcodes`.`studylkup` (
`StudyID` INT(11) NOT NULL AUTO_INCREMENT,
`StudyName` VARCHAR(45) NOT NULL,
PRIMARY KEY (`StudyID`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
CREATE TABLE IF NOT EXISTS `interviewcodes`.`interviewerlkup` (
`InterviewerID` INT(11) NOT NULL AUTO_INCREMENT,
`InterviewerFirstName` VARCHAR(45) NOT NULL,
`InterviewerLastName` VARCHAR(45) NOT NULL,
PRIMARY KEY (`InterviewerID`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
CREATE TABLE IF NOT EXISTS `interviewcodes`.`studyinterviewers` (
`StudyID` INT(11) NOT NULL,
`InterviewerID` INT(11) NOT NULL,
PRIMARY KEY (`StudyID`, `InterviewerID`),
INDEX `fk_StudyInterviewers_InterviewerLkup1_idx` (`InterviewerID` ASC),
CONSTRAINT `fk_StudyInterviewers_InterviewerLkup1`
FOREIGN KEY (`InterviewerID`)
REFERENCES `interviewcodes`.`interviewerlkup` (`InterviewerID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_StudyInterviewers_StudyLkup1`
FOREIGN KEY (`StudyID`)
REFERENCES `interviewcodes`.`studylkup` (`StudyID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
CREATE TABLE IF NOT EXISTS `interviewcodes`.`participant` (
`ParticipantID` INT(11) NOT NULL AUTO_INCREMENT,
`ParticipantCaseID` VARCHAR(45) NOT NULL,
`StudyID` INT(11) NOT NULL,
`InterviewerID` INT(11) NOT NULL,
PRIMARY KEY (`ParticipantID`),
INDEX `fk_participant_studyinterviewers1_idx` (`InterviewerID` ASC),
CONSTRAINT `fk_participant_studyinterviewers1`
FOREIGN KEY (`InterviewerID`)
REFERENCES `interviewcodes`.`studyinterviewers` (`InterviewerID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_participant_studylkup1`
FOREIGN KEY (`StudyID`)
REFERENCES `interviewcodes`.`studylkup` (`StudyID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;
You can use inner join to delete from more than one table.