MySQL storage : best way to archive data - php

I'm quiet new in the SQL field. Thus I have a way of working question.
Every week, I will send data from an Excel spreadsheet on my MySQL DB through a pHp code. This is already working. Thus I have a table which I can update.
Actually I'm sending price of a specific underlying on my DB. What is the best way to archive my data as following.
On my DB, I have the below structure :
tabe t_index
Label = VARCHAR(255)
Price = float
Date = date()
Let's say I sent my data on my db last week, thus I stored :
Stock A
102.85
2013-03-18
Today, I want to send new price for the same Stock A which is 103.54, but I would like to archive and keep the 102.85 price to be able to make some return or whatever between the two prices.
How should I proceed ?
I hope my question is not too messy...
Thank you for your help

One way of doing this is, create a UPDATE trigger which inserts old value in another table. So when you update an existing entry, old data will be copied/archived to another table.
CREATE TABLE t_index_archive (
Label VARCHAR(255),
Price float,
Date datetime);
Now create a trigger on your existing table
DROP TRIGGER IF EXISTS archive_t_index;
DELIMITER $$
CREATE DEFINER = CURRENT_USER TRIGGER archive_t_index BEFORE UPDATE ON t_index
FOR EACH ROW BEGIN
INSERT INTO t_index_archive VALUES (OLD.Label, OLD.Price, OLD.Date);
END;
$$
DELIMITER ;

You can add another column named like is_active ENUM type with value active,inactive
By default is_active's value will be 'active'
and when you enter new entry in database just update old entry's is_active with 'inactive' and then add new entry
Fetch new data using query using where clause WHERE is_active='active'

Related

copy column to other column in same table [duplicate]

Given the following table:
id | value
--------------
1 6
2 70
Is there a way to add a column that is automatically calculated based on another column in the same table? Like a VIEW, but part of the same table. As an example, calculated would be half of value. Calculated should be automatically updated when value changes, just like a VIEW would be.
The result would be:
id | value | calculated
-----------------------
1 6 3
2 70 35
Generated Column is one of the good approach for MySql version which is 5.7.6 and above.
There are two kinds of Generated Columns:
Virtual (default) - column will be calculated on the fly when a
record is read from a table
Stored - column will be calculated when a
new record is written/updated in the table
Both types can have NOT NULL restrictions, but only a stored Generated Column can be a part of an index.
For current case, we are going to use stored generated column. To implement I have considered that both of the values required for calculation are present in table
CREATE TABLE order_details (price DOUBLE, quantity INT, amount DOUBLE AS (price * quantity));
INSERT INTO order_details (price, quantity) VALUES(100,1),(300,4),(60,8);
amount will automatically pop up in table and you can access it directly, also please note that whenever you will update any of the columns, amount will also get updated.
If it is a selection, you can do it as:
SELECT id, value, (value/2) AS calculated FROM mytable
Else, you can also first alter the table to add the missing column and then do an UPDATE query to compute the values for the new column as:
UPDATE mytable SET calculated = value/2;
If it must be automatic, and your MySQL version allows it, you can try with triggers
MySQL 5.7 supports computed columns. They call it "Generated Columns" and the syntax is a little weird, but it supports the same options I see in other databases.
https://dev.mysql.com/doc/refman/5.7/en/create-table.html#create-table-generated-columns
#krtek's answer is in the right direction, but has a couple of issues.
The bad news is that using UPDATE in a trigger on the same table won't work. The good news is that it's not necessary; there is a NEW object that you can operate on before the table is even touched.
The trigger becomes:
CREATE TRIGGER halfcolumn_update BEFORE UPDATE ON my_table
FOR EACH ROW BEGIN
SET NEW.calculated = NEW.value/2;
END;
Note also that the BEGIN...END; syntax has to be parsed with a different delimiter in effect. The whole shebang becomes:
DELIMITER |
CREATE TRIGGER halfcolumn_insert BEFORE INSERT ON my_table
FOR EACH ROW BEGIN
SET NEW.calculated = NEW.value/2;
END;
|
CREATE TRIGGER halfcolumn_update BEFORE UPDATE ON my_table
FOR EACH ROW BEGIN
SET NEW.calculated = NEW.value/2;
END;
|
DELIMITER ;
You can use generated columns from MYSQL 5.7.
Example Usage:
ALTER TABLE tbl_test
ADD COLUMN calc_val INT
GENERATED ALWAYS AS (((`column1` - 1) * 16) + `column2`) STORED;
VIRTUAL / STORED
Virtual: calculated on the fly when a record is read from a table (default)
Stored: calculated when a new record is inserted/updated within the
table
If you want to add a column to your table which is automatically updated to half of some other column, you can do that with a trigger.
But I think the already proposed answer are a better way to do this.
Dry coded trigger :
CREATE TRIGGER halfcolumn_insert AFTER INSERT ON table
FOR EACH ROW BEGIN
UPDATE table SET calculated = value / 2 WHERE id = NEW.id;
END;
CREATE TRIGGER halfcolumn_update AFTER UPDATE ON table
FOR EACH ROW BEGIN
UPDATE table SET calculated = value / 2 WHERE id = NEW.id;
END;
I don't think you can make only one trigger, since the event we must respond to are different.
I hope this still helps someone as many people might get to this article. If you need a computed column, why not just expose your desired columns in a view ? Don't just save data or overload the performance with triggers... simply expose the data you need already formatted/calculated in a view.
Hope this helps...

How to insert data dynamically in MySQL

I need to record the date each event happens. I have this table.
Click here to view the table
NULL spaces are available to save a new date.
The X represents the date that the event occurred.
The problem is I do not know how to update the date each event occurs
I need to know the best option if you use INSERT or UPDATE querys.
Thank you for your help
If you just want to update a column in a table with the current time:
UPDATE `yourtable` SET `yourcolumn` = NOW() WHERE `ID` = yourid
Assuming your columns are DATETIME() columns.
As an aside, it's best to have event-related information in another relationship table. This way you can link multiple events for each row in your main table. This provides a more accurate data-trail for accounting purposes (or in other words, you can see each and every update without overwriting anything).
If you are seeking to have a 'last_modified' column on your table to help you keep track of changes made on your records, you should do this:
ALTER TABLE my_table
ADD last_modified TIMESTAMP
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP;
Basically what it does is to add a 'last_modified' column, Set it to be a timestamp and make it to be updated with the current timestamp when there is an update on the record.

can i get primary key value and extension after inserting in database using triggers in MySQL

Well, let me explain this as simple as possible, basically i have a table doc_info, which stores information regarding uploaded files; like file name, date created, uploaded by etc;
what i want is to create an INSERT trigger on this table, which will get two things, the primary key ID of this newly inserted row and the extension of the uploaded filename which will be in the document name; and concatenate them and update that same row, with this concatenated value
Example,
If someone uploads "document.docx", then ID will be auto generated as x and document name will be document.docx, thus the value to store will be "x.docx" using update on that same row.
I am new to this MySQL, and have little knowledge if operations like this can be performed with MySQL.
To implement such action within db you should create two triggers: after insert and on update. They should be like this one
delimiter |
CREATE TRIGGER changeProperty AFTER INSERT ON doc_info
FOR EACH ROW
BEGIN
UPDATE doc_info SET doc_info.someProperty = CONCAT(doc_info.id, doc_info.extension) WHERE doc_info.id = NEW.id;
END;
|
You can calculate extension on you file name by following expression: SUBSTRING_INDEX(doc_id.fileName, '.', -1);

How to get DATETIME of the row inserted into Table

I need to display number of users created from last login to current login in my ELGG application, but there is no field in the ElggUser to record the date & time of users created (ElggUser Table Structure).
So is there any way to get DATETIME of rows already inserted into Table?
Thank You
Database schema of Elgg does contain this information. ElggUser extends ElggEntity that has attributes time_created, time_updated, last_action containing Unix timestamps representation of entity creation/modification/last action by this entity or on related content.
These attributes are stored in {DB_PREFIX}entities table and are availible as properties of all ElggEntity subclasses.
You have to add a field for recording date and time. For instance my table name is my_table and for date time using created_date then create a trigger as:
DELIMITER ;;
CREATE TRIGGER `my_table_bi` BEFORE INSERT ON `my_table` FOR EACH ROW
BEGIN
SET NEW.created_date = NOW();
END;;
DELIMITER ;
Every time for added record the trigger will hit recording the date and time of entry
Don't know, if you can alter your table, but you could add a created column like this:
ALTER TABLE yourTable ADD COLUMN created timestamp DEFAULT CURRENT_TIMESTAMP;
The column created would then always have the time when a row gets inserted without further ado.

mySQL INSERT while making sure a specific column has one "YES" value and the rest "NO"

I have a table: event_list with two columns: name as var(80) and default as ENUM('y','n').
The idea is that there can only be one event set as default at a time. So if there are 100 events in the table 99 of them must have a default value of 'n' and one must have a default value of 'y'.
When a customer is adding a new event to the system there is a option "Make This Event Default". What I want to do is insert the event into the table. If the default column for that insert is added as 'y' I need a easy way of changing all the rest of the default rows to 'n'.
Is there a way for mySQL to handle this or will I have to manually change all the other data fields to 'n' if the user makes a new default?
I would suggest altering your current table to include an ID (unique, autoincrement) field, and removing the enum field, and then adding a new table that stores the ID of default event. Then you only need to edit one line.
You can manage it using a trigger.
Else, you'll have to update all your records to set there status to 'n' prior to do your insert.
edit : SenorAmor answer looks better
how about creating STORED PROCEDURE?
DELIMITER $$
CREATE PROCEDURE SetCurrentEvent(IN oEventName varchar(50))
BEGIN
UPDATE `event_list` SET `default` = 'N';
UPDATE `event_list` SET `default` = 'Y' WHERE `name` = oEventName;
END$$
DELIMITER ;
So by creating this, you can simply use:
CALL SetCurrentEvent('qwwrty');

Categories