MYSQL Foreign Key ON DELETE and ON UPDATE - mysql

I have a website which has a users table and a movies table. I am creating a favourites table so that users can save movies to their favourites list. The question is concerning the favourites table which I have been adviced to use the below :
CREATE TABLE Favorites (
user_id INT NOT NULL,
movie_id INT NOT NULL,
PRIMARY KEY (user_id, movie_id),
FOREIGN KEY (user_id) REFERENCES Users(user_id),
FOREIGN KEY (movie_id) REFERENCES Movies(movie_id)
);
I noticed when reading about foreign keys there is an 'ON DELETE' and 'ON UPDATE' option where you can set to restrict, cascade etc...
If a user has favourited many movies, and then one of the movies is deleted from the movie table, what would happen if it the foreign key was set to "CASCADE"? would any rows from the favourites table be deleted also? What would happen if the foreign key was set to "RESTRICT"?
I am just after a basic explanation as I do not currently fully understand this.

13.1.17.3 Using FOREIGN KEY Constraints
...
CASCADE: Delete or update the row from the parent table, and automatically delete or update the matching rows in the child table. Both ON DELETE CASCADE and ON UPDATE CASCADE are supported. Between two tables, do not define several ON UPDATE CASCADE clauses that act on the same column in the parent table or in the child table.
Note
Currently, cascaded foreign key actions do not activate triggers.
...
RESTRICT: Rejects the delete or update operation for the parent table. Specifying RESTRICT (or NO ACTION) is the same as omitting the ON DELETE or ON UPDATE clause.
NO ACTION: A keyword from standard SQL. In MySQL, equivalent to RESTRICT. The MySQL Server rejects the delete or update operation for
the parent table if there is a related foreign key value in the
referenced table. Some database systems have deferred checks, and NO
ACTION is a deferred check. In MySQL, foreign key constraints are
checked immediately, so NO ACTION is the same as RESTRICT.
...

Related

Correct way to remove entry from a SQL table along with the relations

If we have TableA and TableB related by TableAB where TableAB has foreign keys for the first two table, then what's the go-to way of deleting an entry from TableA? Up to now if used a property such as IsActive with a bit to describe if the entry is still valid. However, that makes it a little problematic when there are "ghost entries" in the relation tables, such as TableAB.
How should I proceed?
One chaining table in question.
CREATE TABLE EntradaContadorCliente (
ClaveECC int AUTO_INCREMENT not null,
ClaveCliente int not null,
ClaveContador int not null,
ClaveEntrada int not null,
PRIMARY KEY (ClaveECC),
FOREIGN KEY (ClaveCliente) REFERENCES Cliente(ClaveCliente),
FOREIGN KEY (ClaveContador) REFERENCES Contador(ClaveContador),
FOREIGN KEY (ClaveEntrada) REFERENCES EntradaBitacora(ClaveEntrada)
);
Since TableA and TableB related by TableAB; which means TableAB is a chaining table. One way is to use ON DELETE CASCADE for cascading the delete operation on primary table.
Alternative is to, manually delete the entries from your chaining table once the entry has been deleted from primary table.
You can use a ALTER statement to re-create the FK constraint like
ALTER TABLE `TableAB` DROP FOREIGN KEY FK_KEY_Test;
ALTER TABLE `TableAB` ADD CONSTRAINT FK_KEY_Test FOREIGN KEY ('some_column')
REFERENCES `TableA` ('Test_column1') ON UPDATE CASCADE ON DELETE CASCADE;
From MySQL Documentation:
CASCADE: Delete or update the row from the parent table, and
automatically delete or update the matching rows in the child table.
Both ON DELETE CASCADE and ON UPDATE CASCADE are supported.
first you disable all foreign key with:-
alter table table_name
nocheck constraint fk_constraint
then you delete data in parent table.

error with alter table and foreign key

I have 2 tables :
Installers (Fields: id,company,country,experience,name)
Contacts (Fields: name,phone,address)
I would like to match both names, thereby I could click in one value of the name of Installers and it could show me the values of Contacts table.
However when I am trying to set up the foreign key (my child table will probably be Installers , as I have more tables like that and Contacts would be the parent.) It states this error:
query SQL:
ALTER TABLE `Installers`
ADD FOREIGN KEY (`name`)
REFERENCES `SOLAR_PV`.`Contacts`(`name`)
ON DELETE CASCADE ON UPDATE CASCADE;
MySQL ha dicho: Documentación
1452 - Cannot add or update a child row: a foreign key constraint
fails (SOLAR_PV.#sql-32a_183, CONSTRAINT #sql-32a_183_ibfk_1
FOREIGN KEY (name) REFERENCES Contacts (name) ON DELETE CASCADE
ON UPDATE CASCADE)
Both tables are InnoDB and Contacts.name is indexed as well as Installers.name
Primary Key of Installers is id and Primary Key of Contacs is name.
Any idea about what would be the problem?
It seems your child table contains few records those don't have in master, you can check it by below query-
SELECT id FROM Installers ins
LEFT JOIN SOLAR_PV.Contacts cnt ON ins.name=cnt.name
WHERE cnt.name IS NULL;
Note: Assuming name is int type for better performance as it is primary key in one table.
If you get few records by above query then you can follow below 2 approach-
Approach1: You can either delete these records in child table or insert in master table also and then you can create relationship by this alter command.
Approach2: If you don't want to change in your tables existing data and still want to execute your alter query then use as per below-
SET FOREIGN_KEY_CHECKS=0;
ALTER TABLE `Installers`
ADD FOREIGN KEY (`name`)
REFERENCES `SOLAR_PV`.`Contacts`(`name`)
ON DELETE CASCADE ON UPDATE CASCADE;
SET FOREIGN_KEY_CHECKS=1;

Unable to delete a record from self indexed db object

I am not able to delete a row from a database object. In my case db object is having self indexing.
A field root_id is having a foreign key relation with key_id (Primary key). The referential integrity is designed as ON UPDATE NO ACTION AND ON DELETE NO ACTION. Even still I am not able to delete.
CONSTRAINT `fk_MyTab` FOREIGN KEY (`root_id`) REFERENCES `MyTab` (`key_id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
I have to delete records from this table WHERE key_id = root_id.
When I try to delete I am getting the following.
Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails (`MyTab`, CONSTRAINT `fk_MyTab` FOREIGN KEY (`root_id`) REFERENCES `MyTab` (`key_id`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Point me to the right direction.
That is what NO ACTION does, it prevents deletion of a row with any child rows. If you want to delete the children too, use CASCADE.
You could also preserve the data by setting it to ON DELETE SET NULL, in which case if the parent is deleted the child rows will have their foreign key column set to null.
I think this is a good practice to do when you're designing a database that has lots of foreign keys. If you have tables with ON DELETE CASCADE option which are linked with other field to other tables, the delete cascade option will fail (because mysql could not delete in the same order you create the tables)". A solution for this case is to declare a clause ON DELETE SET NULL in the others foreign keys

MySQL and Foreign Keys

I have a question regarding Foreign Keys in an InnoDB Table. I have 4 tables in my database:
Signup:
UID - Primary Key
Afid
Planid
Industryid
Affiliates:
Afid - Primary Key
Plans:
Planid - Primary Key
Industries:
Industryid - Primary Key
SQL I use to add the keys:
CONSTRAINT `FK_signup_industries` FOREIGN KEY (`industryid`) REFERENCES `industries` (`industryid`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `FK_signup_affiliates` FOREIGN KEY (`afid`) REFERENCES `affiliates` (`afid`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `FK_signup_plans` FOREIGN KEY (`planid`) REFERENCES `plans` (`planid`) ON UPDATE CASCADE ON DELETE CASCADE
What my question is:
If I was to delete a plan or an industry on their respective tables would the user in the signup table be deleted? I have tried to find guides on this and they don't explain it very well.
Basically what I need done is that the row in the signup table never to be deleted no matter what. When I use this query:
CONSTRAINT `FK_signup_plans` FOREIGN KEY (`planid`) REFERENCES `plans` (`planid`) ON UPDATE CASCADE ON DELETE NO ACTION
I get this error:
Cannot delete a parent row.
If you need the row in Signup to stay even if you delete the referenced row in Industries, Affiliates, or Plans, then you have two choices:
Do not declare a foreign key constraint. This removes enforcement of referential integrity, but it allows rows to exist in Signup that reference a parent primary key value that no longer exists.
Use ON DELETE SET NULL. This allows the row to stay, but the foreign key value that references the now-deleted parent will be changed.*
For more details see http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
* The standard SQL specification also defines a rule ON DELETE SET DEFAULT, but InnoDB doesn't support this feature.

mysql delete and foreign key constraint

I'm deleting selected rows from both table in MYSQL, the two tables have foreign keys.
DELETE d,b
FROM A as b
INNER JOIN B as d on b.bid=d.bid WHERE b.name LIKE '%xxxx%';
MYSQL complains about foreign keys even though I'm trying to delete from both tables:
Error: Cannot delete or update a parent row: a foreign key constraint
fails (`yyy/d`, CONSTRAINT `fk_d_bid` FOREIGN KEY (`bid`) REFERENCES
`b` (`bid`) ON DELETE NO ACTION ON UPDATE NO ACTION)
what's the best solution here to delete from both table?
Change this constraint to use ON DELETE CASCADE -- which means that if a row is deleted, then any "child" rows will be automatically deleted as well.
Of course take good care of using CASCADE -- only use it when necessary. If you're overzealous with it, and accidentally do a well-placed DELETE, it might end up deleting half of your database. :)
See documentation on foreign key constraints.
I think I see what you're trying to do
If you can't change the table structure, then you could use 2 statements, the first with a sub-select
delete from B where bid IN (select bid from A where name like '%xxxx%');
delete from A where name like '%xxxx%';