问题
I have a typical LAMP based site + Zend Framework where I have a base table and a summary table. Summary table is used to display data in reports.
Base table -
ID | Status
1 | 1
2 | 1
3 | 2
4 | 2
5 | 1
6 | 1
Summary table -
Status | Count
1 | 4
2 | 2
The base table will be changed(insert,update,delete) at an average of 20 times per day.
Currently, I am using triggers to call a stored procedure which will update the summary table based on the base table.
This is the stored procedure.
CREATE PROCEDURE UpdateSummary()
BEGIN
UPDATE summary a
INNER JOIN
(SELECT status, count(*) c from base group by status) b
ON a.status = b.status
SET a.count = b.c;
END
And I have 3 triggers (one for each - Insert, Delete and Update). I have shown the insert sample alone below. Other are similar to this.
CREATE TRIGGER S_T_TRIGGER_I
AFTER INSERT ON base
FOR EACH ROW
CALL UpdateSummary();
I want the summary table to be updated to the latest values always. Using triggers and stored procedure like this is the best way or is there a elegant way to do this?
回答1:
Why don't you use a view like :
CREATE VIEW Summary AS
SELECT status, count(*)
FROM Base
GROUP BY status;
Each time you need, just do :
SELECT *
FROM Summary
And you'll get your result in real time (each call re-computed).
Views can be used the same way like table is used in Zend Framework. Just that you need to specify a primary key explicitly as explained here
回答2:
Well you are re-querying the DB over and over for data that you already know.
Why not just update the summary with only the changes.
DELIMITER $$
CREATE TRIGGER ai_base_each AFTER INSERT ON base FOR EACH ROW
BEGIN
INSERT INTO summary (status, count) VALUES (NEW.status,1)
ON DUPLICATE KEY UPDATE
SET count = count + 1;
END $$
CREATE TRIGGER ad_base_each AFTER DELETE ON base FOR EACH ROW
BEGIN
UPDATE summary s
SET s.count = s.count - 1
WHERE s.status = OLD.status;
END $$
CREATE TRIGGER au_base_each AFTER UPDATE ON base FOR EACH ROW
BEGIN
UPDATE summary s
SET s.count = s.count - 1
WHERE s.status = OLD.status;
INSERT INTO summary (status, count) VALUES (NEW.status,1)
ON DUPLICATE KEY UPDATE
SET count = count + 1;
END $$
DELIMITER ;
This will be much much faster and more to the point much more elegant.
来源:https://stackoverflow.com/questions/7570874/updating-the-summary-table-based-on-triggers-and-stored-procedures