How to handle association table and cascade constraints in MYSQL - mysql

I think this is a common problem but I was not able to find correct keywords to perform a search on StackOverflow.
In mysql, I have two entites : organization and scale.
One organization can only have one scale but a scale can belong to many organizations.
So I created a third entity organization_scale.
for instance :
organization
------------
org_id | name
1 | Mickey
2 | Donald
3 | Dingo
scale
----------
sc_id | name
1 | miniScale
2 | maxiScale
organization_scale
--------------
org_id | sc_id
1 | 1
2 | 1
3 | 2
Both fields of the organization_scale entity are foreign keys + cascade on update and delete
The problem is the following:
If I delete from organization where org_id = 3,the third line from organization_scale are properly deleted (since org_id = 3 does not exist anymore)
BUT
the scale with sc_id = 2 is not deleted. And I do not understand why. No one references to this scale, and this should be removed otherwise, with a big amount of data, a lot of "scales" will be orphean.
(same thing happens if I do not use an extra table, and I add a scale_id column directly in organization)

I think the problem is this: The ON DELTE CASCADE in the definition of the organization_scale table only works in one direction: when deleting something in scale or organization then don't ask and delete the rows in organization_scale.
But you seem to want the other direction: When deleting something in organization_scale delete the row in scale if there is no reference to it anymore.
This works for me: I added a trigger on organization.
DROP DATABASE IF EXISTS test;
CREATE DATABASE test;
USE test;
CREATE TABLE organization (org_id INT UNSIGNED PRIMARY KEY, name VARCHAR(255));
CREATE TABLE scale (sc_id INT UNSIGNED PRIMARY KEY, name VARCHAR(255));
CREATE TABLE organization_scale (org_id INT UNSIGNED, sc_id INT UNSIGNED,
FOREIGN KEY (org_id)
REFERENCES organization(org_id)
ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (sc_id)
REFERENCES scale(sc_id)
ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE TRIGGER delete_unused_sc_id AFTER DELETE ON organization FOR EACH ROW DELETE FROM scale WHERE NOT EXISTS (SELECT * FROM organization_scale WHERE organization_scale.sc_id = scale.sc_id);
INSERT INTO organization VALUES
(1,"Mickey"),
(2,"Donald"),
(3,"Dingo");
INSERT INTO scale VALUES
(1,"miniScale"),
(2,"maxiScale");
INSERT INTO organization_scale VALUES
(1,1),
(2,1),
(3,2);
SELECT * FROM organization_scale;
SELECT * FROM scale;
DELETE FROM organization WHERE org_id=3;
SELECT * FROM organization_scale;
SELECT * FROM scale;
DROP DATABASE test;

Related

How do I drop rows that is equivalent to an select statement [duplicate]

I want to use foreign keys to keep the integrity and avoid orphans (I already use innoDB).
How do I make a SQL statment that DELETE ON CASCADE?
If I delete a category then how do I make sure that it would not delete products that also are related to other categories.
The pivot table "categories_products" creates a many-to-many relationship between the two other tables.
categories
- id (INT)
- name (VARCHAR 255)
products
- id
- name
- price
categories_products
- categories_id
- products_id
If your cascading deletes nuke a product because it was a member of a category that was killed, then you've set up your foreign keys improperly. Given your example tables, you should have the following table setup:
CREATE TABLE categories (
id int unsigned not null primary key,
name VARCHAR(255) default null
)Engine=InnoDB;
CREATE TABLE products (
id int unsigned not null primary key,
name VARCHAR(255) default null
)Engine=InnoDB;
CREATE TABLE categories_products (
category_id int unsigned not null,
product_id int unsigned not null,
PRIMARY KEY (category_id, product_id),
KEY pkey (product_id),
FOREIGN KEY (category_id) REFERENCES categories (id)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (product_id) REFERENCES products (id)
ON DELETE CASCADE
ON UPDATE CASCADE
)Engine=InnoDB;
This way, you can delete a product OR a category, and only the associated records in categories_products will die alongside. The cascade won't travel farther up the tree and delete the parent product/category table.
e.g.
products: boots, mittens, hats, coats
categories: red, green, blue, white, black
prod/cats: red boots, green mittens, red coats, black hats
If you delete the 'red' category, then only the 'red' entry in the categories table dies, as well as the two entries prod/cats: 'red boots' and 'red coats'.
The delete will not cascade any farther and will not take out the 'boots' and 'coats' categories.
comment followup:
you're still misunderstanding how cascaded deletes work. They only affect the tables in which the "on delete cascade" is defined. In this case, the cascade is set in the "categories_products" table. If you delete the 'red' category, the only records that will cascade delete in categories_products are those where category_id = red. It won't touch any records where 'category_id = blue', and it would not travel onwards to the "products" table, because there's no foreign key defined in that table.
Here's a more concrete example:
categories: products:
+----+------+ +----+---------+
| id | name | | id | name |
+----+------+ +----+---------+
| 1 | red | | 1 | mittens |
| 2 | blue | | 2 | boots |
+---++------+ +----+---------+
products_categories:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 1 | 2 | // blue mittens
| 2 | 1 | // red boots
| 2 | 2 | // blue boots
+------------+-------------+
Let's say you delete category #2 (blue):
DELETE FROM categories WHERE (id = 2);
the DBMS will look at all the tables which have a foreign key pointing at the 'categories' table, and delete the records where the matching id is 2. Since we only defined the foreign key relationship in products_categories, you end up with this table once the delete completes:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
There's no foreign key defined in the products table, so the cascade will not work there, so you've still got boots and mittens listed. There's just no 'blue boots' and no 'blue mittens' anymore.
I got confused by the answer to this question, so I created a test case in MySQL, hope this helps
-- Schema
CREATE TABLE T1 (
`ID` int not null auto_increment,
`Label` varchar(50),
primary key (`ID`)
);
CREATE TABLE T2 (
`ID` int not null auto_increment,
`Label` varchar(50),
primary key (`ID`)
);
CREATE TABLE TT (
`IDT1` int not null,
`IDT2` int not null,
primary key (`IDT1`,`IDT2`)
);
ALTER TABLE `TT`
ADD CONSTRAINT `fk_tt_t1` FOREIGN KEY (`IDT1`) REFERENCES `T1`(`ID`) ON DELETE CASCADE,
ADD CONSTRAINT `fk_tt_t2` FOREIGN KEY (`IDT2`) REFERENCES `T2`(`ID`) ON DELETE CASCADE;
-- Data
INSERT INTO `T1` (`Label`) VALUES ('T1V1'),('T1V2'),('T1V3'),('T1V4');
INSERT INTO `T2` (`Label`) VALUES ('T2V1'),('T2V2'),('T2V3'),('T2V4');
INSERT INTO `TT` (`IDT1`,`IDT2`) VALUES
(1,1),(1,2),(1,3),(1,4),
(2,1),(2,2),(2,3),(2,4),
(3,1),(3,2),(3,3),(3,4),
(4,1),(4,2),(4,3),(4,4);
-- Delete
DELETE FROM `T2` WHERE `ID`=4; -- Delete one field, all the associated fields on tt, will be deleted, no change in T1
TRUNCATE `T2`; -- Can't truncate a table with a referenced field
DELETE FROM `T2`; -- This will do the job, delete all fields from T2, and all associations from TT, no change in T1
I think (I'm not certain) that foreign key constraints won't do precisely what you want given your table design. Perhaps the best thing to do is to define a stored procedure that will delete a category the way you want, and then call that procedure whenever you want to delete a category.
CREATE PROCEDURE `DeleteCategory` (IN category_ID INT)
LANGUAGE SQL
NOT DETERMINISTIC
MODIFIES SQL DATA
SQL SECURITY DEFINER
BEGIN
DELETE FROM
`products`
WHERE
`id` IN (
SELECT `products_id`
FROM `categories_products`
WHERE `categories_id` = category_ID
)
;
DELETE FROM `categories`
WHERE `id` = category_ID;
END
You also need to add the following foreign key constraints to the linking table:
ALTER TABLE `categories_products` ADD
CONSTRAINT `Constr_categoriesproducts_categories_fk`
FOREIGN KEY `categories_fk` (`categories_id`) REFERENCES `categories` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `Constr_categoriesproducts_products_fk`
FOREIGN KEY `products_fk` (`products_id`) REFERENCES `products` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
The CONSTRAINT clause can, of course, also appear in the CREATE TABLE statement.
Having created these schema objects, you can delete a category and get the behaviour you want by issuing CALL DeleteCategory(category_ID) (where category_ID is the category to be deleted), and it will behave how you want. But don't issue a normal DELETE FROM query, unless you want more standard behaviour (i.e. delete from the linking table only, and leave the products table alone).

How to add a relation if parent deleted then child should automatically delete in mysql [duplicate]

I want to use foreign keys to keep the integrity and avoid orphans (I already use innoDB).
How do I make a SQL statment that DELETE ON CASCADE?
If I delete a category then how do I make sure that it would not delete products that also are related to other categories.
The pivot table "categories_products" creates a many-to-many relationship between the two other tables.
categories
- id (INT)
- name (VARCHAR 255)
products
- id
- name
- price
categories_products
- categories_id
- products_id
If your cascading deletes nuke a product because it was a member of a category that was killed, then you've set up your foreign keys improperly. Given your example tables, you should have the following table setup:
CREATE TABLE categories (
id int unsigned not null primary key,
name VARCHAR(255) default null
)Engine=InnoDB;
CREATE TABLE products (
id int unsigned not null primary key,
name VARCHAR(255) default null
)Engine=InnoDB;
CREATE TABLE categories_products (
category_id int unsigned not null,
product_id int unsigned not null,
PRIMARY KEY (category_id, product_id),
KEY pkey (product_id),
FOREIGN KEY (category_id) REFERENCES categories (id)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (product_id) REFERENCES products (id)
ON DELETE CASCADE
ON UPDATE CASCADE
)Engine=InnoDB;
This way, you can delete a product OR a category, and only the associated records in categories_products will die alongside. The cascade won't travel farther up the tree and delete the parent product/category table.
e.g.
products: boots, mittens, hats, coats
categories: red, green, blue, white, black
prod/cats: red boots, green mittens, red coats, black hats
If you delete the 'red' category, then only the 'red' entry in the categories table dies, as well as the two entries prod/cats: 'red boots' and 'red coats'.
The delete will not cascade any farther and will not take out the 'boots' and 'coats' categories.
comment followup:
you're still misunderstanding how cascaded deletes work. They only affect the tables in which the "on delete cascade" is defined. In this case, the cascade is set in the "categories_products" table. If you delete the 'red' category, the only records that will cascade delete in categories_products are those where category_id = red. It won't touch any records where 'category_id = blue', and it would not travel onwards to the "products" table, because there's no foreign key defined in that table.
Here's a more concrete example:
categories: products:
+----+------+ +----+---------+
| id | name | | id | name |
+----+------+ +----+---------+
| 1 | red | | 1 | mittens |
| 2 | blue | | 2 | boots |
+---++------+ +----+---------+
products_categories:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 1 | 2 | // blue mittens
| 2 | 1 | // red boots
| 2 | 2 | // blue boots
+------------+-------------+
Let's say you delete category #2 (blue):
DELETE FROM categories WHERE (id = 2);
the DBMS will look at all the tables which have a foreign key pointing at the 'categories' table, and delete the records where the matching id is 2. Since we only defined the foreign key relationship in products_categories, you end up with this table once the delete completes:
+------------+-------------+
| product_id | category_id |
+------------+-------------+
| 1 | 1 | // red mittens
| 2 | 1 | // red boots
+------------+-------------+
There's no foreign key defined in the products table, so the cascade will not work there, so you've still got boots and mittens listed. There's just no 'blue boots' and no 'blue mittens' anymore.
I got confused by the answer to this question, so I created a test case in MySQL, hope this helps
-- Schema
CREATE TABLE T1 (
`ID` int not null auto_increment,
`Label` varchar(50),
primary key (`ID`)
);
CREATE TABLE T2 (
`ID` int not null auto_increment,
`Label` varchar(50),
primary key (`ID`)
);
CREATE TABLE TT (
`IDT1` int not null,
`IDT2` int not null,
primary key (`IDT1`,`IDT2`)
);
ALTER TABLE `TT`
ADD CONSTRAINT `fk_tt_t1` FOREIGN KEY (`IDT1`) REFERENCES `T1`(`ID`) ON DELETE CASCADE,
ADD CONSTRAINT `fk_tt_t2` FOREIGN KEY (`IDT2`) REFERENCES `T2`(`ID`) ON DELETE CASCADE;
-- Data
INSERT INTO `T1` (`Label`) VALUES ('T1V1'),('T1V2'),('T1V3'),('T1V4');
INSERT INTO `T2` (`Label`) VALUES ('T2V1'),('T2V2'),('T2V3'),('T2V4');
INSERT INTO `TT` (`IDT1`,`IDT2`) VALUES
(1,1),(1,2),(1,3),(1,4),
(2,1),(2,2),(2,3),(2,4),
(3,1),(3,2),(3,3),(3,4),
(4,1),(4,2),(4,3),(4,4);
-- Delete
DELETE FROM `T2` WHERE `ID`=4; -- Delete one field, all the associated fields on tt, will be deleted, no change in T1
TRUNCATE `T2`; -- Can't truncate a table with a referenced field
DELETE FROM `T2`; -- This will do the job, delete all fields from T2, and all associations from TT, no change in T1
I think (I'm not certain) that foreign key constraints won't do precisely what you want given your table design. Perhaps the best thing to do is to define a stored procedure that will delete a category the way you want, and then call that procedure whenever you want to delete a category.
CREATE PROCEDURE `DeleteCategory` (IN category_ID INT)
LANGUAGE SQL
NOT DETERMINISTIC
MODIFIES SQL DATA
SQL SECURITY DEFINER
BEGIN
DELETE FROM
`products`
WHERE
`id` IN (
SELECT `products_id`
FROM `categories_products`
WHERE `categories_id` = category_ID
)
;
DELETE FROM `categories`
WHERE `id` = category_ID;
END
You also need to add the following foreign key constraints to the linking table:
ALTER TABLE `categories_products` ADD
CONSTRAINT `Constr_categoriesproducts_categories_fk`
FOREIGN KEY `categories_fk` (`categories_id`) REFERENCES `categories` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `Constr_categoriesproducts_products_fk`
FOREIGN KEY `products_fk` (`products_id`) REFERENCES `products` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
The CONSTRAINT clause can, of course, also appear in the CREATE TABLE statement.
Having created these schema objects, you can delete a category and get the behaviour you want by issuing CALL DeleteCategory(category_ID) (where category_ID is the category to be deleted), and it will behave how you want. But don't issue a normal DELETE FROM query, unless you want more standard behaviour (i.e. delete from the linking table only, and leave the products table alone).

How to enforce foreign key constraint from unrelated tables in Mysql?

this is my DB structure.
this is the script I used to create the tables
use for_stkoverflow;
CREATE TABLE UserGroup (
groupid MEDIUMINT NOT NULL AUTO_INCREMENT,
groupname VARCHAR(100),
PRIMARY KEY (`groupid`)
);
CREATE TABLE User_det (
Usrid MEDIUMINT NOT NULL AUTO_INCREMENT,
usrname VARCHAR(255),
groupid MEDIUMINT,
PRIMARY KEY (`Usrid`),
Foreign Key (groupid)
references UserGroup (groupid)
);
CREATE TABLE Accounts (
acid MEDIUMINT NOT NULL AUTO_INCREMENT,
groupid MEDIUMINT,
acname VARCHAR(255),
PRIMARY KEY (`acid`),
Foreign Key (groupid)
references UserGroup (groupid)
);
create table Ledger (
ledgerid MEDIUMINT NOT NULL AUTO_INCREMENT,
ledgername VARCHAR(255),
acid mediumint,
Usrid mediumint,
PRIMARY KEY (ledgerid),
Foreign Key (acid)
references Accounts (acid),
Foreign Key (Usrid)
references User_det (Usrid)
);
I have the following data entered
UserGroup
----------
- groupid groupname
--------------------
- 1 Group1
- 2 Group2
User_det
--------
- Usrid usrname groupid
-----------------------
- 1 User1 1
- 2 User2 2
Accounts
--------
- acid groupid acname
---------------------
- 1 1 ac1
- 2 2 ac2
Ledger
--------
-ledgerid ledgername acid Usrid
--------------------------------
- 1 ledger1 1 1
- 2 ledger2 2 2
- 3 ledger3 1 2
- 4 ledger4 2 1
SELECT t1.ledgerid, t1.ledgername,t2.acname,t3.usrname
FROM Ledger AS t1
INNER JOIN Accounts AS t2 ON t1.acid = t2.acid
Inner join User_det AS t3 ON t1.Usrid = t3.Usrid;
The current table structure permits insertion of data that violates DB integrity.
The entry ledgerid 3 is invalid
---------------------------------- because acname ac1 belongs to group1 to which User2 is not part of. The entry ledgerid 4 is
invalid
because acname ac2 belongs to group2 to which User1 is not part of.
How can I prevent the insert of such data?
Right now in the application I am doing this check via PHP in the BL layer.
Can I enforce this at the DB level because I do some import from the backed also without using the PHP front end.
Use identifying relationships, similar to this:
Note how UserGroup PK migrates from the top of this "diamond", down both "sides" and merges at the "bottom". Since a row at the bottom contains only one field identifying the top, it cannot be related to multiple rows at the top.
You can still keep your other keys if you need them for other purposes and/or make the keys above alternate (i.e. UNIQUE constraints)...
BTW, use naming more consistently - I'd recommend always using singular and prefixing PK fields with unabbreviated table names...
Side note :I believe you gave too many details in your question, so I apologize if I misunderstood it.
Taking into account you use mysql which doesn't have materialized views that could be used to enforce desired constraint, I see two options.
First, you can mimic materialized view with trigger[s] and a new table with unique constraint (it will work, but it's quite hard to implement in general - you have to make sure all INSERT/UPDATE/DELETE on 3 tables are handled properly by corresponding triggers).
Another way is to denormalize your schema by adding groupId to Ledger , and "extra" unique constraint on Users (userId, groupId) and Accounts (acid,groupId), and changing FKs in Ledger so it refers not to userId in Users, but to userId,groupId and not to acid, but to acid,groupId.
I hope that helps.

How come I can enter values freely with foreign key constraint

I created two tables and did the following:
Table 1: (students)
CREATE TABLE student(s int, n int, d int, PRIMARY KEY(s), FOREIGN KEY(d) REFERENCES dep(d));
Table 2: (dep)
CREATE TABLE dep(d int, n int, PRIMARY KEY(d));
So, if i understand correctly, d is a foreign key of table 1 and it references to the primary key of the department. Therefore, The primary key of dep have to match the d in students. However when I do the following
INSERT INTO dep (1,2);
The statement finished with no error? The students table is empty, how could the data be inserted when its primary key is referenced?
Please help, thanks.
By the way I was able to insert into student freely even dep does not have corresponding value. Do you guys think it's because of mysql vs. oracle?
mysql> select * from student;
+---+------+------+
| s | n | d |
+---+------+------+
| 5 | 5 | 5 |
+---+------+------+
1 row in set (0.00 sec)
mysql> select * from dep;
+---+------+
| d | n |
+---+------+
| 1 | 2 |
+---+------+
1 row in set (0.00 sec)
The student table has the foreign key d which is the primary key of the dep table. The student table is the one dependent on the dep table. The dep table has no such dependence on the student table. The constraint is on the student table to have a value of d that should always be in dep table.
Inserting a record into the student table with an invalid value for d WILL cause the error.
You've got your understanding the wrong way round. What you've done in your sql is ensure that when you enter a Student, the value for d must exist as a value in dep.d
if you said
insert into student values (1, 2, 3)
then this would fail if there was no row in dep with d equal to 3
You can insert into the department table as there is no constraint on this table.
If you will try to add a row in student table with the random department number , which is not present in the department table, then it will give you the constraint error.
Example :If you will try
insert into student values (1, 4, 1034);
And if there is no row in the department table with the value of primary key 1034 , then it will give the foreign key constraint.
What you need to do is insert your data starting from the parent down.
If you need to delete data you actually have to go the other way, delete the items before you delete the parent order record.
As usual, when you insert data into the detail table and master table has no corresponding values, you got an error - 'Cannot add or update a child row: a foreign key constraint fails...'.
But when the FOREIGN_KEY_CHECKS variable is set to 0, MySQL ignores foreign key constraints -
SET FOREIGN_KEY_CHECKS=0;
INSERT INTO student VALUES (5,5,5); -- no errors
SET FOREIGN_KEY_CHECKS=1;

MySQL Foreign Key "ON DELETE CASCADE" across 3 tables

I have 3 tables in my DB (there are more, but there are no connections to these yet)
table "molecule" with column id
table "descriptor" with columns "id" and "molecule_id" and a foreign key referencing "molecule.id"
table "tDepDescriptor" with columns "id" and "descriptor_id" and a foreign key referencing "descriptor.id "
(each table has more columns, but none of these act as foreign keys or anything like that)
All foreign keys have "on delete cascade" specified, all ids are unsigned int(5).
Now, if I try to delete an entry in "molecule" for which there are referencing entries in "descriptor" and "tDepDescriptor" nothing happens as if the foreign keys were set to "on update restrict", no error is given.
If I delete an entry in "descriptor", all referencing entries in "tDepDescriptor" are deleted like they should.
The same happens if I try to delete an entry in "molecule" for which there are referencing entries in "descriptor", but no referencing entries to those "descriptor"-entries in "tDepDescriptor".
So "on delete cascade" works for two tables, but the "cascade" does not seem to be passed on when three tables are involved.
What the tables are supposed to do is:
When I want to delete an entry in "molecule", all referencing entries in "descriptor" are deleted. And therefore all entries in "tDepDescriptor" that have a reference to one of the deleted entries in "descriptor" are also deleted.
mysql server version is 5.1, engine is InnoDB
Is hope someone could follow this complicated explanation and can help me.
//EDIT:
Found the problem.
Seems to be a problem with phpMyAdmin, not with the database. clicking on delete in PMA did not work, but coding the query by hand did, cascading through all three tables. Strange, but at least I know my tables work correctly.
It is enough to have ON DELETE CASCADE option. Have a look at this example:
Create and fill tables:
CREATE TABLE molecule (
id INT(11) NOT NULL,
PRIMARY KEY (id)
)
ENGINE = INNODB;
CREATE TABLE descriptor (
id INT(11) NOT NULL,
molecule_id INT(11) DEFAULT NULL,
PRIMARY KEY (id),
CONSTRAINT FK_descriptor_molecule_id FOREIGN KEY (molecule_id)
REFERENCES molecule(id) ON DELETE CASCADE ON UPDATE RESTRICT
)
ENGINE = INNODB;
CREATE TABLE tdepdescriptor (
id INT(11) NOT NULL,
descriptor_id INT(11) DEFAULT NULL,
PRIMARY KEY (id),
CONSTRAINT FK_tdepdescriptor_descriptor_id FOREIGN KEY (descriptor_id)
REFERENCES descriptor(id) ON DELETE CASCADE ON UPDATE RESTRICT
)
ENGINE = INNODB;
INSERT INTO molecule VALUES
(1),
(2),
(3);
INSERT INTO descriptor VALUES
(1, 1),
(2, 1),
(3, 2);
INSERT INTO tdepdescriptor VALUES
(1, 1),
(2, 2),
(3, 3);
Delete one molecule and all its descriptor and all its tdepdescriptor:
DELETE FROM molecule WHERE id = 1;
SELECT * FROM molecule;
+----+
| id |
+----+
| 2 |
| 3 |
+----+
SELECT * FROM descriptor;
+----+-------------+
| id | molecule_id |
+----+-------------+
| 3 | 2 |
+----+-------------+
SELECT * FROM tdepdescriptor;
+----+---------------+
| id | descriptor_id |
+----+---------------+
| 3 | 3 |
+----+---------------+
Please make sure that you are using the Engine InnoDB in all the tables chained to wach other in foreign keys with on update/delete cascade, you may use:
create table test1 (
#column definitions, including fk with on delete/update cascade
) engine = "InnoDB";
My exprience:
I had the same problem on one of my projects. An already developed database was given to me for adding some more parts. The tables did not have on delete/update cascade on foreign keys. I added them, also I added aother table from "query" tab in phpMyAdmin of cPanel. so I had a relation as:
(priorities) 1-m (packages) 1-m (standards)
All with on delete/update cascade. But when I used to delete "priority" , "standard" was not deleted.
"priorities" and "packages" existed with "InnoDB" engine and when I created "standards" table, I did not specify the ENGINE, so it used "MyISAM" by default, that caused the problem. When I recreated the table with the ENGINE="InnoDB" explicitly mentioned, the problem was solved.