tags:

views:

73

answers:

1

I use a 1 column memory table to keep track of views on various items in my DB. Each view = INSERT query into the memory table. Every 10 mins, I wanna count() the rows for each item, and commit changes to DB.

The question is.... if I run the query that will get the list of all items, such as

SELECT COUNT(*) AS period_views, `item_id` FROM `-views` GROUP BY `item_id` ORDER BY `item_id`

and then run an update query for each row to add the amount of views in that period, and then truncate the table. This operation might take a few seconds.... and in those few seconds, there is going to be other INSERTS into that table, that didnt make it into the original count. Will they be truncated too once that command executes? or will the table be locked until the entire operation completes, and the the new INSERTs added?

A: 

MySQL does not lock the table automatically, and it is possible that you will lose some records in between getting the count and performing the truncate. So two solutions jump out at me:

1) Use table locks to prevent the memory table being updated - depending on the nature of your application, this means that all of your clients might freeze for a few seconds while you are updating, this might be OK.

2) Add a second column to keep track of which records you are currently updating ...

ALTER TABLE `-views` ADD work_in_progress TINYINT NOT NULL DEFAULT 0;

And then when you want to work on the those records

UPDATE `-views` SET work_in_progress = 1;
SELECT COUNT(*) AS period_views, `item_id` FROM `-views` WHERE work_in_progress GROUP BY `item_id` ORDER BY `item_id`;
# [ perform updates as necessary ]
DELETE FROM `-views` WHERE work_in_progress;

This implementation will guarantee that you don't delete any -views which were added while you were updating.

And FWIW, -views is an awful name for a table!

too much php