问题
There allot of discussion on storing page views for an article or video in a database, but I can't seem to find any information on storing daily page views. For example DeviantArt shows you the past 15 or so days and how many page views each one got in a little graph, as well as the total page view for the profile.
You can see above exactly what I'm trying to achieve, and DeviantArt do it on a huge scale as they get millions of hits.
I am using CodeIgniter on PHP and MySQL
回答1:
You could have a row for each day then increment the count when it is viewed.
INSERT INTO views (day,views) VALUES (CURDATE(),1) ON DUPLICATE KEY UPDATE views=views+1;
And a PHP script...
mysql_query("INSERT INTO views (day,views) VALUES (CURDATE(),1) ON DUPLICATE KEY UPDATE views=views+1;");
This uses a table called 'views' and 2 rows 'day' and 'views'.
See this article for more information.
回答2:
Usually what you do in these cases is have a logging table with 1 record per view. You have a cron run at certain intervals (daily) to summarize the logging data into another summary table. At the most basic level, you would have 1 record per day in the summary table with the total view count. Since the historical data never changes, you don't need to do updates. That gives you at most 365 records per item per year. Not a lot of records, so it scales well.
This scales better than having a single record for each day and updating the count. You could run into contention/locking issues if you are trying to update the same record multiple times. By doing an INSERT DELAYED and using a MyISAM table, your logging table can scale very well.
You can then select from the summary table to get the daily counts, and you could select from the logging table if you want to display the current days count.
If you want to keep your logging table small, when your cron run, you can rename the logging table and create a new, empty one. Then process the renamed logging table.
RENAME TABLE logging TO logging_old;CREATE TABLE logging LIKE logging_old;
If you really need to scale, you can use a replication trick to log views extremely fast. You use a BLACK HOLE table type for logging data, which replicates to another server where the table is MyISAM or InnoDB.
回答3:
I don't use codeIgniter but here's how you can do this in straight php.
Basically, you can either use sessions to record each visit to your site and record their page requests or you can simply record each hit on the page. The first option gives you more information (how many unique hits were made, how many hits are from returning visitors, etc.) but takes more programming to set up and requires user session management. So, for your purposes I'll explain option 2.
SQL:
Table 'pageViews'
Id - Integer, auto Increment, primary key
page - varchar(150)
datetime - datetime
On the page you're monitoring, you would add:
$query2 = "INSERT INTO `pageViews` (page, datetime) VALUES ('".$_SERVER["SCRIPT_NAME"]."', ".date("Y-M-d H:I:s").")";
$result2 = //insert DB connection etc. to apply update to DB
You can then fetch the rows from the db based on the page and the datetime stamp, count the results and display it using html5 canvas. Or, because each hit has a datetime, you can break it down further into hours of the day etc.
I hope this helps.
To modify this for simple daily counters, add an extra column called 'views' that is just an integer. Then on the page put a check to see if there is a row for the current page for today in the db. If so, then get the current views value and increment it and resale to the DB.
For the total views count I would probably create another table with the same columns but not with the date-time column. Then on your page, you increment the views value for the current page in the new table too.
This would be lightening fast. The trade-off is the loss of detail. So, here's the MySQL and PHP for this 3rd option:
MySQL:
Table 'dailyViews'
Id - Integer, auto Increment, primary key
views - integer
page - varchar(150)
datetime - datetime
Table 'totalViews'
Id - Integer, auto Increment, primary key
views - integer
page - varchar(150)
PHP:
// Search the DB for an entry today for this page in dailyViews
$query = "SELECT views FROM `dailyViews` WHERE `page`='".$_SERVER["SCRIPT_NAME"]."' AND `datetime`=".date("Y-M-d H:I:s")."";
$result = //insert your db connection etc to execute the query
if (mysqli_num_rows($result)==1) {
$resultArray = mysqli_fetch_array($result, MYSQLI_ASSOC);
$views = $resultArray['views']+1;
$query2 = "UPDATE `dailyViews` SET `views`=".$views." WHERE `page`='".$_SERVER["SCRIPT_NAME"]."' AND `datetime`=".date("Y-M-d H:I:s")."";
$result2 = //insert DB connection etc. to apply update to DB
} else if (mysqli_num_rows($result)<1) {
$query2 = "INSERT INTO `dailyViews` (views, page, datetime) VALUES (1, '".$_SERVER["SCRIPT_NAME"]."', ".date("Y-M-d H:I:s").")";
$result2 = //insert DB connection etc. to apply update to DB
} else {
// there is more than one entry for this page and date in the DB. An error has ccurred
}
// Then just get the total views for this page and increase it by 1.
来源:https://stackoverflow.com/questions/13659868/most-efficient-way-of-storing-daily-page-views-as-well-as-a-total-count