views:

42

answers:

2

My website is like stackoverflow, there are many questions. I want to record how many times a question has been visited. I have a column called "view_count" in the question table to save it.

If a user visits a question many times, the view_count should be increased only 1. So I have to record which user has visited which question, and I think it is too much expensive to save this information in the database because the records will be huge. So, I would like to keep the information in memory and only persist the number to the database every 10 minutes.

I have searched about "cache" in Rails, but I haven't found an example. I would like a simple sample of how to do this, thanks for help~

A: 

This article is pretty amazing - if you have the opportunity to use Memcache I think it would help you greatly: http://www.ridingtheclutch.com/2009/01/08/cache-anything-easily-with-rails-and-memcached.html

if you could do something like:

if CACHE.get(key) >= 10:
  send to db
  CACHE.set(key, 0, 1.hour)
else:
  newcount = CACHE.get(key) + 1
  CACHE.set(key, newcount, 1.hour)
end
Auston
@Auston, thanks. I hope I can just use the built-in cache, because what I want is very simple, I don't want to use another product. I looked at the `Rails.cache`, but it is not thread-safe. How do you do **simple caching** with rails and thread-safe?
Freewind
And, I am on windows, it seems the lastest vertion of memcached can't run on windows.
Freewind
A: 

First i would probably suggest that your opinion about using database for this would be too storage costly is invalid. Storage itself is cheap, and i doubt the recordset will get that huge. Plus when properly indexed, this table will be blazing fast to access (and it will be mostly read access with pretty unique constraints). But this is your decision, not mine :)

One idea would be to use cookies - it would be really really easy, although you have a size limit do deal with, which can complicate things a bit.

The thing with memory (and memcache alike) is that it's not persistent. The next time you boot your application environment, the data is reset. So for persistent storage, you still need some kind of a database or persistent queue thing (Redis for example).

Tanel Suurhans
@Tanel Suurhans, thank you. I supposed there are 100,000 questions, and each question has been visited 500 times, that are 50,000,000 records, and it will be more. I'm not sure if it is suitable to use database. I don't have many experience, please give me more advives, thank you
Freewind
I would probably have a visits count field (just as you do now) and then a table to track unique visits per question. The table would contain the IP of the visitor, question id and time. On each visit i would check if an IP with the given question id exists in that table, and if not, increment the visit count. Also lets say that visits should be considered unique if it happens lets say 12 hours before the previous one. Meaning the visits database would be pruned of records where creation time is older than 12 hours.The downside is that IP is not 100% accurate on tracking visits.
Tanel Suurhans
Oh and another solution would be to store a cookie in the visitors browser per question (this kind of might be bad because of the amount of cookies stored by the site) with an expiration of 12 hours (or whatever you like). So on each visit, you check if the cookie for this question exists, and if it doesnt, just increment the visit_count field value. These are the first ideas right from the top of my head :)
Tanel Suurhans
@Tanel, thanks, your idea of "keep 12 hours of one IP" is very helpful, that since the table only stored 12-hour's data, the records won't be too many.
Freewind
And the cookie one, I've thought about that, but there are some limitations: 1. Cookie can't store too many text(4k?) 2. Client will send cookie to server in every request 3. If client disabled cookie, this won't work. So, I will consider the database one. Thanks :)
Freewind