How to best check if a SQL table contents have not changed? - mysql

Assuming I have the following table named "contacts":
id|name|age
1|John|5
2|Amy|2
3|Eric|6
Is there some easy way to check whether or not this table changes much like how a sha/md5 hash works when getting the checksum for a file on your computer?
So for example, if a new row was added to this table, or if a value was changed within the table, the "hash" or some generated value shows that the table has changed.
If there is no direct mechanism, what is the best way to do this (could be some arbirary hash mechanism, as long as the method puts emphasis on performance and minimizing latency)? Could it be applied to multiple tables?

There is no direct mechanism to get that information through SQL.
You could consider adding an additional LastModified column to each row. To know the last time the table was modified, select the maximum value for that column.
You could achieve a similar outcome by using a trigger on the table for INSERT, UPDATE and DELETE, which updates a separate table with the last modified timestamp.

If you want to know if something has changed, you need something to compare. For example a date. You can add a table with two columns, the tablename and the timestamp, and program a trigger for the events on the table you are interested to control, so this trigger will update the timestamp column of this control table.

If the table isn't too big, you could take a copy of the entire table. When you want to check for changes, you can then query the old vs. new data.
drop table backup_table_name;
CREATE TABLE backup_table_name LIKE table_name;
INSERT INTO backup_table_name SELECT * FROM `table_name`;

Related

restoring data in a specific table

One of our tables has been maligned
/*edit as per commented request
On doing an update to a specific column I accidentally neglected to specify for which row I wish to make this change and set the offending value for every row in the table.
*/end edit
but we have a very recent backup, however not so recent that other tables won't lose data if we do a total database restore.
I'm wondering what the procedure is (assuming there is one) of copying the contents of a given table from one database to another.
The largest problem is that I can't just drop the offending table and replace it as it has rows that are indexed by id into other tables. This won't be a problem if we just take the values from the identical rows in the back-up and bring them over (since the row ids wouldn't change).
It's unclear what exactly has gone wrong with your data. But I'm thinking maybe just a column or two has got messed up. As you said, you just want to copy over the data from the old table, based on the id column.
Assuming you've imported the backup database as "olddb" and the current one is named "newdb":
UPDATE newdb.yourtable newtable, olddb.yourtable oldtable
SET newtable.somecolumn = oldtable.somecolumn
WHERE newtable.id = oldtable.id
Use mysqldatadump for that particular table, and then feed that into the other database.
You can edit the dump file prior to redaing it in to the target table.
See: https://dba.stackexchange.com/questions/9306/how-do-you-mysqldump-specific-tables

How to create SQL table with limited entries?

I have a table that is used to store the latest actions the user did (like a ctrl+z for the program), but I want to limit this table to about 200 entries, and after that, every new entry would delete the oldest in the table.
Is there any option to make the table behave this way on SQL or do I need to add some code to the program to do it?
I've seen this kind of idea before, but I've rarely seen a case where it was a good idea.
Your table would need these columns in addition to columns for the normal data.
A column of type integer to hold the row number.
A column of type timestamp (standard SQL timestamp) to hold the time of the last update.
The normal approach to limit this table to 200 rows would be to add a check constraint to the column of row numbers. For example, CHECK (row_num between 1 and 200). MySQL doesn't enforce check constraints, so instead you'll need to use a foreign key reference to a table of row numbers (1 to 200).
All insert statements will need to determine whether the table is full, examine the time of the last update, and either a) insert a new row with a new row number, or b) delete the oldest row or overwrite it.
My advice? Renegotiate this requirement.
Assuming that "200" is not a hard limit, in other words if the number of entries occasionally went over that by a small amount it would be OK...
Don't do the pruning on line, do it as an off line process, run as often as needed to keep the totals per user from not getting "too high".
For example, one such solution would be to fire the SQL that does that query every hour using crontab.

Create columns that autoincrement with name in a MySQL Database

I know that this might seem like a strange question, but let me try and explain it. I have a database table called 'plan' and in it the first column is called 'username' and the columns after it are called 'question1', 'question2' and so on. I now need to add a hundred or so more columns named like this, but it would be nice to have a sql statement that would automatically do that for me.
I know this wasn't set up in the best way, but if you have a solution, please let me know :)
There isn't any SQL command or feature that would do this automatically; sure you can generate the alter table statements and add the columns programmatically; however, your design would be terribly flawed.
Instead of adding columns, you should create a table containing the question, the user_id (or username, whatever is the PK) to hold the records. If you need to identify a question by number (or ID), simply add another column called question_id.
Write the query in sql to excel. Seperate the incrementing number. Drag down until excel row 100. Hard to explain but i guess you ll figure it out. You'll have 100 incrementing add column sql statements. copy paste run it on a query tool.

How to get the date of record updating in MySQL

I have a table that one of this record has been changed.
Is there any MySQL function to get the date of this updating?
No. There is no way to get that modification date unless you explicitly stored it somewhere else (through a trigger or application side technique).
Well it depends on how you are using the data value.
but mostly it is a good practice to have both created_at and updated_at as attributes for your table.
OR if you want to keep each update date info for a record then store them in different table. before each update in main table insert existing row in tracking table from main table.

Updating MySQL fields only when other information in the row changes

I have a problem where I would like a field to work in a similar way to the timestamp type field, where it only gets updated on an update if there are other changes to the record.
I am using php to update a mysql database with myisam tables.
Take the following example table which has one row with the following fields;-
UNIQUEID : 1
TITLE : Example
AMENDAT : (timestamp)
AMENDBY : Andy
I have some code which handles maintenance on the table. The update to the table uses (for example) the following statement ;-
update example set TITLE="New Title",AMENDBY="Andy" where UNIQUEID=1 ;
This statement works fine and updates the row including the AMENDAT timestamp field.
If a different user makes the same change;-
update example set TITLE="New Title",AMENDBY="Bob" where UNIQUEID=1 ;
Again, everything works as expected.
But, it is possible that the update statement may be called when no changes have been made to any of the columns in the statement (this is possible in the real world because I have a large number of fields in the table which are all updated at once and I do not wish to code a check on the before and after values of the fields - I just let the update take the strain);-
update example set TITLE="Example",AMENDBY="Andy" where UNIQUEID=1 ;
In this case, MySQL decides that nothing need be done, so it does not update the AMENDAT timestamp (all good so far).
But if another user does the same thing;-
update example set TITLE="Example",AMENDBY="Bob" where UNIQUEID=1 ;
Then the row is updated due to the change in the AMENDBY field. So even though the actual data has not changed, the amendment details have (which is not good for my amendment tracking).
My current work around for this problem is to use the following statement for updates;-
update example set TITLE="XYZ",AMENDBY="XYZ",AMENDAT=NULL where UNIQUEID=123 ;
This forces an update every time, so the amendment details will reflect the last user to save the record whether or not they made any changes. Obviously this is not ideal.
Is there any way of making the AMENDBY field update only when there are changes to other fields on the record, much like the default functioning of a timestamp type field?
I realise this problem is easily solved by making two separate calls to MySQL, one to do the update and check from the return (number of records updated) whether to make a second call to update the amendment details, but this is a messy and not very elegant solution.
Bear in mind that I have a large number of tables which are set up in the same way, each has an arbitrary number of fields, so I don't want a solution which requires an enormous call to MySQL which includes an if statement for every field which may or may not be updated.
I think that what you are trying to do can be achieved with a TRIGGER with timing AFTER on the UPDATE event. Triggers can be tricky though, use them with extra caution. Also bear in mind, that if the trigger statement fails for some reason the actual UPDATE/INSERT/DELETE fails too.