Get the table/primary-key of "cascade-deleted" rows - mysql

When I delete an item which triggers some foreign key cascade-deletes, is there a way to get back the table and primary key of the cascade-deleted rows in MySQL?
If there's no built in way to do this, should I just write a stored procedure to manually handle the cascades and then relay what it deleted?

The only way you can do this is by putting a trigger on the table you're cascading to and having it log what deletes were made. MySQL won't nicely push out which deletes happened to you. So you'll either have to select them first, or log them and select them later.

Related

Duplicates data after joining trigger table with other tables

I want to fetch the BEFORE and AFTER data from TableProduct whenever there is an update. So I created a Before and After trigger queries in which the respected values from the trigger is stored in separate tables titled TableProduct_Before and TableProduct_After.
My challenge is I always get duplicates result whenever I try to INNER JOIN the three tables.
I have tried the DISTINCT and ORDER BY ID command but still the same challenge.
I made enquiry I was told I can't join trigger table values because it doesn't have a foreign key, I tried adding a foreign key but it didn't work saying foreign key already exists in TableProduct.
Please, I will appreciate any help thank you.
You are misunderstanding how triggers work. You can use either a before or after trigger.
The key is using new and old. Inside the body of the trigger, you have both the old and new values. In pseudocode, this looks like:
insert into archive (pk, old_value, new_value)
values (new.pk, old.value, new.value);
Both OLD and NEW data is available in both before and after trigger.
The difference is - BEFORE trigger fixes the attempt to update whereas AFTER fixes successful attempt result. I.e. BEFORE is executed anycase (but its changes may be rollbacked!), rather than AFTER.
See https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=dd19c611c7e2fbef88b2133dcaa61dfa
PS. Recent MySQL versions allows triggers chains - a lot of triggers on the same event fired one-by-one. So check that your saving trigger is the most last in this chain.

Adding a UNIQUE key to a large existing MySQL table which is receiving INSERTs/DELETEs

I have a very large table (dozens of millions of rows) and a UNIQUE index needs to be added to a column on that table. I know for a fact that the table does contain duplicated values on that key, which I need to clean up (by deleting rows/resetting the value of the column to something unique that I can automatically generate). A plus is that the rows which are already duplicated do not get modified anymore.
What would be the right approach to perform a change like this, given that I will be probably using the Percona pt-osc tool and there are continuous deletes/inserts on the table? My plan was:
Add code that ensures no dupe IDs get inserted anymore. Probably I need to add a separate table for this temporarily, since I want the database to enforce this for me and not the application - so insert into the "shadow table" with a unique index in a transaction together with my main table, rollback all inserts that try to insert duplicate values
Backfill the table by zapping all invalid column values which are within the primary key range below $current_pkey_value
Then add the index and use pt-osc to changeover the table
Is there anything I am missing?
Since we use pt-online-schema-change we are using triggers for performing the synchronisation from the existing table to a temp table. The tool actually has a special configuration key for this, --no-check-unique-key-change, which will do exactly what we need - agree to perform the ALTER TABLE and set up triggers in such a way that if a conflict occurs, INSERT .. IGNORE will be applied and the first row having used the now-unique value will win in the insert during synchronisation. For us this is a good tradeoff because all the duplicates we have seen resulted from data races, not from actual conflicts in the value generation process.

How to create a backup of rows deleted due to foregin key reference

I want to save all rows get deleted from db in a different table , So once in a day i will run a php command and deleted all related files from server.
I have created a trigger to save deleted row in to a table and it working fine but table rows get delete due to foreign relationship not get save.
I think triggers are not execute on rows get deleted due to foreign key constrain.
please help
You need to alter the trigger on your master table. It should backup all the child records first and then the master table record. Instead of having multiple triggers for all child tables you can try to achieve it using a single trigger.

mysql with duplicate key

I tried searching online for this...I had a row that I inserted into the database. I removed it. The table has a Unique Key on a particular column. When I try to insert a new row with the same value for the unique key, it fails saying duplicate entry. However, there is no duplicate entry since the row is not there! Is there a way to reset this?
I would like the table to accept values that are unique to what is there right now. I tried to remove the unique key constraint from the table to see if that would work, however, when I added it back, it was having the same issue.
Maybe you perform dirty reading? and the deletion did not commit? try use the read commit option, I think it's called isolation level.

MySQL is handling one SQL query at the time?

If you got 100 000 users, is MySQL executing one SQL query at the time?
Because in my PHP code I check if a certain row exists; if it doesn't it creates one. If it does, it just updates the row counter.
It crossed my mind that perhaps 100 users are checking if the row exists at the same time, and when it doesn't they all create one row each.
If MySQL is handling them sequentially I know that it won't be an issue, then one user will check if it exists, if not, create it. The other user will check if it exists, and since that's the case, it just updates the counter.
But if they all check if it exists at the same time and let's say it doesn't, then they all create one row and the whole table structure will fail.
Would be great if someone could shed some light on this topic.
Use a UNIQUE constraint or, if viable, make the primary key one of your data items and the SQL server will prevent duplicate rows from being created. You can even use the "ON DUPLICATE KEY UPDATE ..." syntax to specify the alternate operation if the row already exists.
From your comments, it sounds like you could use the user_id as your primary key, in which case, you'd be able to use something like this:
INSERT INTO usercounts (user_id,usercount)
VALUES (id-goes-here,1)
ON DUPLICATE KEY UPDATE usercount=usercount+1;
If you put the check and insert into a transaction then you can avoid this problem. This way, the check and create will be run as one one query and there shouldn't be any confusion