I have a database which can be accessed by multiple users. Is there any way I can set the tables such that whenever somebody enters a new record or modifies a record, his/her username and the date entered is stored into 2 columns in the same table as the record itself. The table would look like this:
Id | Name | Username | Date Entered | Date Modified
1 | Cat | john | 1999-05-05 | 1996-06-06
I am using a GUI which is phpMyAdmin.
Thanks!
You can set a column to not allow null values, either when you create the table using NOT NULL after the data type declaration. Otherwise, you use an ALTER TABLE statements to change a column if they already exist, or you are adding the column to an existing table.
That will stop someone from adding a record, but not update. If you have a separate table of users to reference, you would use a foreign key relationship to make sure that if the user column is populated, it will be done with a valid user.
DEFAULT constraints can be used to set the value of the date fields if a value is not provided.
ALTER TABLE x
ADD USER VARCHAR(45) NOT NULL
ALTER TABLE x
ADD DATE_ENTERED DATE NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
ALTER TABLE x
ADD DATE_ENTERED DATE NOT NULL DEFAULT ON UPDATE CURRENT_TIMESTAMP
First of all, you may want to spend some time thinking about the best way to design an audit mechanism, because adding two columns to every table in your DB is probably not optimal.
Having said that, what you are looking for to do what you described is a trigger. This is a piece of SQL that will execute every time a specified operation is invoked. A rough example for your case:
create trigger audit
after insert on "table_name"
insert (user, time) into "table_name"
I don't remember the precise mysql syntax, but that's a rough example of what you need. Please ask a follow-up question if that isn't clear.
Related
I'd like to record the last user and last time a particular row was either inserted or updated in a MySQL table. What is the best way to go about this? Is there some MySQL metadata I can investigate or do I need to create username and timestamp columns myself and then create triggers to populate them?
You need to create separate columns yourself for timestamp and user name. For timestamps there is no need to use triggers to update its value, just declare the timestamp field to use current timestamp as initial value and update value:
CREATE TABLE t1 (
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
The user is bit more interesting. If you are talking about mysql level user, then yes, use triggers or stored procedure using the USER() function. If you are talking about application level users, then I would supply that username as part of the update statement.
UPDATE table SET username='xxx', ... WHERE ...
You can use a column and set it default system date for insert
For update you must use trigger or etcs.
At least in MySQL 5.5.46, you can track tables. This includes structure and data. There, the DB username and timestamp is recorded.
I am creating a table for users that have been banned from my website. I want to move everything over to the new table, including the TIMESTAMP of when the record was created, but the new table will also have a TIMESTAMP for when they got banned.
When I create a row in table foo, I have a TIMESTAMP that registers when that row was created. I would like to transfer that row to another table (bar) that has a different number of columns, and keep the information from the original TIMESTAMP. How can this be done?
I am fairly new to MySQL, so correct me if I have false assumptions, but it seems that the TIMESTAMP field actually creates a TIMESTAMP when the record is created and that the existing TIMESTAMP value would have to be stored as something else like a VARCHAR in the new table. Am I off base?
EDIT: Solved my own question
I originally had not tried anything because I did not know what to try. In the end, it turns out that simply moving the value from one TIMESTAMP column to another TIMESTAMP column does, in fact, work. The only difference between the two columns is that the original TIMESTAMP has a DEFAULT of CURRENT_TIMESTAMP, whereas the new TIMESTAMP has a DEFAULT of NULL.
I used the following code:
INSERT INTO `bar` (`created`)
SELECT `created` FROM `foo` WHERE `user` = '000'
I am dealing with a legacy application that is using MariaDB to emulate a queue. One of the key things missing is that the original design doesn't insert the time the messages in the queue were inserted meaning that the order the messages are processed is not guaranteed.
So far the messages appear to be processed in order as we're only using a single MariaDB instance but I would like to add a created_on column to ensure this continues.
My question is that I need to backfill the created_on column and i was wondering if MariaDB stored the time a given row was inserted into the database?
I realise that unless it is in the schema it is unlikely but occasionally databases will have non-standard extensions that capture this sort of thing. Oracle for example has similar functionality to this.
MariaDB does not have a hidden timestamp. If the table has an AUTO_INCREMENT, that might suffice since you are asking for order, not specifically time.
My opinion of queuing via MySQL/MariaDB: "Don't queue it, just do it". The effort of queuing and dequeuing can become a burden, especially in end cases.
Yes you can, if you were to create a field make sure when you create the field you have the following:
create table test_created_on_table(
created_on timestamp default now() on update now()
);
If you already have a field just take off the "CURRENT_TIMESTAMP" flag on the created field. Whenever you create a new record in the table, just use "NOW()" for a value.
Or.
On the contrary, remove the 'ON UPDATE CURRENT_TIMESTAMP' flag and send the NOW() for that field. That way actually makes more sense.
This would track when row is inserted or updated.
There's another way of doing it by db trigger:
Adding a ModifiedTime
Adding a modified timestamp to a table is the most straight forward. All your have to do is create the field of type TIMESTAMP, and by default, MySQL will automatically update the field when the row is modified.
There are a couple of things to be aware of:
While you can have multiple TIMESTAMP fields in a row, only one of
these can be automatically updated with the current time on update.
If your UPDATE query contains a value for your ModifiedTime field,
this value will be used.
So, to add your modified timestamp field to an existing table, all you need is:
ALTER TABLE my_table ADD ModifiedTime TIMESTAMP;
Adding a CreatedTime
Adding a CreateTime value is a little more involved.
On the latest versions of MySQL it is apparently possible to create a DateTime field with a default value of CURRENT_TIMESTAMP. This wasn’t an option for me as I was having to support a somewhat older version, besides, even on the newer versions of MySQL it is not possible to have more than one field using CURRENT_TIMESTAMP, which of course we are in order to get ModifiedTime working.
So, in order to get a created timestamp, firstly we must add a DATETIME field to the table.
ALTER TABLE my_table ADD CreatedTime datetime NOT NULL;
Note, that this must be created as NOT NULL in order for the next part to work (this is because setting NOT NULL forces an automatic all zeros default).
Next, we must create a trigger, which will automatically be fired when we insert a value into our table and set the created timestamp.
DELIMITER //
DROP TRIGGER IF EXISTS my_table_insert_trigger//
CREATE TRIGGER my_table_insert_trigger
BEFORE INSERT ON my_table
FOR EACH ROW
BEGIN
IF NEW.CreatedTime = '0000-00-00 00:00:00' THEN
SET NEW.CreatedTime = NOW();
END IF;
END;//
DELIMITER ;
Now, when you insert a value into the table, this trigger will fire and, if you’ve not provided a CreatedTime field in your insert query, it will be set to the current time stamp.
I'd like to see the update date per-row in a table (InnoDB) in mysql.
Is it possible? The only thing I found is the statistics on a table, not row.
SHOW TABLE STATUS
Any suggestions appreciated!
It is not possible, if you want to track the updates or inserts of 'row' in a table, you have to manually create a logic to do so, for example you can use triggers , to maintain the track of all changes and updates of the 'rows' in any other table.
I don't think you can see specific informations like this for a row.
What I usually do is that I create a column creation_date and modification_date in all my tables and then I fill them for each INSERT or UPDATE query with the function NOW()
You can also create your table this way :
CREATE TABLE [name]
[other colmns]
creation_date DATETIME DEFAULT CURRENT_TIMESTAMP
For this, see this topic.
Is there any way to find the time when a user was created? It means to trace the user creation date in mysql.
Please help me out.
Thanks,
Nitesh Kumar
You can add timestamp along with user information when user creation form is submitted otherwise there is no way to track that.
You have to add new field in your database users table say it "created" with type DATETIME
Sample Query is here:
ALTER TABLE `users` ADD `created` DATETIME NOT NULL COMMENT 'user created date' AFTER `name`
Here AFTER name is the last field of table so that it will add new field created at last of users table.
You can add a new TIMESTAMP field to your table, but remember to set CURRENT_TIMESTAMP as default value, so when the record is created, this field gets the timestamp from when the record is created.
I'd say it's impossible to tell afterwards when a record has been created, maybe with some kind of using binary logs, but i don't know much about that.