I need to update an ETS table from changes made to a mysql table: the mysql table is accessible from within the erlang application.
I'm thinking that maybe I could have a process waiting to update the ETS table, while the mysql table gets updated from some sort of web app.
Any and all input appreciated, please let me know if I can supply any more information.
Thanks.
MySQL has no notification infrastructure, so you can't do it automatically, you have to do it with polling. You can make a table with one row which contains time of last update and then create triggers which update this table when relevant rows change. Then continuously check this table to see if it changed.
If you could switch to PostgreSQL, it has LISTEN/NOTIFY commands. With epgsql driver you can add pid of a process which will receive those notifications.
Related
My client wants to maintain audit at column level. He wants a table which stores all the audits i.e. at column level. I have decided on a table structure. i.e
id,tablename,tablecolumn,primarkey,oldvalue,newvalue,date
But i was wondering how will i check for each column level changes. Do i have to check each one manually like old.columnname <> new.columnname and then add into audit table ?
Is there any other way to do it.
When I was given the same task, I've created several stored procedures for modifying table data and restricted CUD operations on table to force users to use only stored procedures.
SPs were actually performing the action requested (i.e. create, update or delete a row in table) plus adding a line to the audit table for every action.
This might be quite inefficient from DB optimization point of view but I think it gives you the most of auditing as update operation and audit are automatically put in a transaction and update can not be completed without adding an audit entry.
i want to create triggers and i have a requirement to do the following.
When a record in a tables is edited trigger that will automatically log this change to another table called logs and where it use inside my php script
The set up of the log table will be as follows:
date
time
value before
value after
edited table
* i am new for triggers please help me my project
Your google-fu is weak my friend: http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html but you will learn eventually :)
Though if this is not a project dedicated to creating triggers, I would not advice to use them. Since this " that will automatically log this change to another table called " can surely be done in business logic. Then you can control what is done from software and by the user. Maybe in the near future you will need to perform a datafix on your table - then you would have to disable the trigger, perform the fix and enable it again. That seem like a lot of work you don't really want to do.
So if possible - avoid triggers, if not - read the mysql docs on how to create them.
Is it possible to use any sort of logic in MySQL without using any procedures? My web hosting does not let me create any procedures so I'm looking for a workaround.
The type of thing I want to do is only add an item to a table if it doesn't already exist. Or add a column to a table if it's not already there. There are some operations that can be done such as CREATE TABLE IF NOT EXISTS and so on, but some operations I require do not have such luxuries :(
I realised late on that my lovely procs won't work and so I tried writing IF/ELSE logic as top-level queries, but for MySQL, IF ELSE blocks only seem to work inside functions/procs and not at the global scope.
Any workarounds greatfully received - I've already asked the hosting to grant me privileges to create procedures but no reply as yet...
I suppose you don't have access to the INFORMATION_SCHEMA either. You can possibly find solutions but it would be better, in my oninion, to:
Change your hosting provider. Seriously. Pay more - if needed - for a MySQL instance that you can configure to your needs. You only have a crippled DBMS if you are not allowed to create procedures and functions.
Posible workarounds for the specific task: You want to add a column if it doesn't exist.
1) Just ALTER TABLE and add the column. If it already exists, you'll get an error. You can catch that error, in your application.
2) (If you have no access to the INFORMATION_SCHEMA) maintain a version of the schema, for your database.
The best solution that I can think of would be to use an additional language with SQL. For example, you can run a query for a specific record, and based on the response that you get, you can conditionally run an INSERT statement.
For inserting a table if it doesn't exist, try using the SHOW TABLES statement and testing whether or not a name exists in the result set.
MySQL supports INSERT IGNORE. and INSERT ... ON DUPLICATE KEY UPDATE.
The following will insert a new row, but only if there is no existing row with id=10. (This assumes that id is defined as a unique or primary key).
INSERT IGNORE INTO my_table (id, col1, col2) values (10, "abc", "def");
The following will insert a new row, but if there is an existing row with id=10 (again, assuming id is unique or primary), the existing row will be updated to hold the new values, instead of inserting a new row.
INSERT INTO my_table (id, col1, col2) values (10, "abc", "def")
ON DUPLICATE KEY UPDATE col1=VALUES(col1), col2=VALUES(col2)
Also, CREATE TABLE supports the IF NOT EXISTS modifier. So you can do something like:
CREATE TABLE IF NOT EXISTS my_table ...
There are many other similar options and modifiers available in MySQL. Check the docs for more.
Originally I created a big script to create or update the database schema, to make it easier to deploy database changes from my local machine to the server.
My script was doing a lot of "if table 'abc' exists and it doesn't have a FK constraint called 'blah'" then create an FK constraint called 'blah' on table 'abc'... and so on.
I now realise it's not actually necessary to check whether a table has a certain column or constraint etc, because I can just maintain a schema-versioning system, and query the DB schema-version when my app starts, or when I navigate to a certain page.
e.g. let's say I want to add a new column to a table. It works like this:
Add a new migration script to the app code, containing the SQL required to add the column to the existing table
Increment the app's schema-version by 1
On app startup, the app queries the DB for the DB's schema-version
If DB schema-version < app schema-version, execute the SQL migration scripts between the two schema-versions, and then update the DB schema-version to be the same as the app
e.g. if the DB's schema-version is 5 and the app version is 8, the app will apply migration scripts 5-6, 6-7 and 7-8 to the DB. These can just be run without having to check anything on the DB side.
The app is therefore solely responsible for updating the DB schema and there's no need for me to ever have to execute schema change scripts on the local or remote DB.
I think it's a better system than the one I was trying to implement for my question.
How can I use trigger to simply update a table with the last time a table was edited? I know that by using triggers it is "for each row" but if someone's inserting more than one row, it'd be pointlessly inserting or altering the table over and over again. Is there any way to do this without doing it over and over again?
I'd like to be able to just have it do it once for all of the inserts instead of having it done time and time again. If not I guess I can force it, via a wrapper.
edit 1:
Well to explain some more of the design I guess then.
I'm going to be having a table in another database to handle the last_updated data for things like chat, or the players "mailbox", and another one for the development things like tables for quests, skills, items etc. And I want to be able to know when a table was last updated so that I can easily see before I go scan the table to see for new things.
Basically this is what I'd like to do(or something similar), I'm also using PHP so it's likely to be PHP-based approach in the code but the SQL should be kind of standard. I'm not going to do full code but rather semi-runnable.
last_modified=mysql_query("select last_modified from various_stats.table_last_updated where database_name=`database_name` and `table_name`");
if(last_modified>last_checked_time){
data_to_get_updated=mysql_query("select something from various_<something>.table_name where last_modified>last_checked_time");
}
else{
do_nothing;
}
edit 2: I'm using InnoDB, and thus I cannot use the information schema's update_time since it never changes.
will this help you, if im on the right track that is:
SELECT UPDATE_TIME
FROM information_schema.tables
WHERE TABLE_SCHEMA = 'dbname'
AND TABLE_NAME = 'tabname'
The above solution is for myisam, for innodb the norm is to set a sceduled script, this can be set as a cron job or a windows scheduled task, if you dont have that kind of control over your web host, you could possibly set up a small server at your work office and run the cron from there. if you do this every say 20 seconds you could simply record the current top auto incremented ID and use this as a guid, if current ID is higher than the last recorded ID you then update your records to show the last changed time to be now.
as this will only be one call to a server every XX seconds, it wont really hammer the server too much and should just run silently in the background.
If you do go down the scheduled task root, it would be wise to add error capture in your script so that you can be alerted via email if something stops working etc.
I need the sample program in Java for keeping the history of table if user inserted, updated and deleted on that table. Can anybody help in this?
Thanks in advance.
If you are working with Hibernate you can use Envers to solve this problem.
You have two options for this:
Let the database handle this automatically using triggers. I don't know what database you're using but all of them support triggers that you can use for this.
Write code in your program that does something similar when inserting, updating and deleting a user.
Personally, I prefer the first option. It probably requires less maintenance. There may be multiple places where you update a user, all those places need the code to update the other table. Besides, in the database you have more options for specifying required values and integrity constraints.
Well, we normally have our own history tables which (mostly) look like the original table. Since most of our tables already have the creation date, modification date and the respective users, all we need to do is copy the dataset from the live table to the history table with a creation date of now().
We're using Hibernate so this could be done in an interceptor, but there may be other options as well, e.g. some database trigger executing a script, etc.
How is this a Java question?
This should be moved in Database section.
You need to create a history table. Then create database triggers on the original table for "create or replace trigger before insert or update or delete on table for each row ...."
I think this can be achieved by creating a trigger in the sql-server.
you can create the TRIGGER as follows:
Syntax:
CREATE TRIGGER trigger_name
{BEFORE | AFTER } {INSERT | UPDATE |
DELETE } ON table_name FOR EACH ROW
triggered_statement
you'll have to create 2 triggers one for before the operation is performed and another after the operation is performed.
otherwise it can be achieved through code also but it would be a bit tedious for the code to handle in case of batch processes.
You should try using triggers. You can have a separate table (exact replica of your table of which you need to maintain history) .
This table will then be updated by trigger after every insert/update/delete on your main table.
Then you can write your java code to get these changes from the second history table.
I think you can use the redo log of your underlying database to keep track of the operation performed. Is there any particular reason to go for the program?
You could try creating say a List of the objects from the table (Assuming you have objects for the data). Which will allow you to loop through the list and compare to the current data in the table? You will then be able to see if any changes occurred.
You can even create another list with a object that contains an enumerator that gives you the action (DELETE, UPDATE, CREATE) along with the new data.
Haven't done this before, just a idea.
Like #Ashish mentioned, triggers can be used to insert into a seperate table - this is commonly referred as Audit-Trail table or audit log table.
Below are columns generally defined in such audit trail table : 'Action' (insert,update,delete) , tablename (table into which it was inserted/deleted/updated), key (primary key of that table on need basis) , timestamp (the time at which this action was done)
It is better to audit-log after the entire transaction is through. If not, in case of exception being passed back to code-side, seperate call to update audit tables will be needed. Hope this helps.
If you are talking about db tables you may use either triggers in db or add some extra code within your application - probably using aspects. If you are using JPA you may use entity listeners or perform some extra logic adding some aspect to your DAO object and apply specific aspect to all DAOs which perform CRUD on entities that needs to sustain historical data. If your DAO object is stateless bean you may use Interceptor to achive that in other case use java proxy functionality, cglib or other lib that may provide aspect functionality for you. If you are using Spring instead of EJB you may advise your DAOs within application context config file.
Triggers are not suggestable, when I stored my audit data in file else I didn't use the database...my suggestion is create table "AUDIT" and write java code with help of servlets and store the data in file or DB or another DB also ...