Practical NoSQL - Solving a Real Problem with MongoDB and Redis
openmymind.net
openmymind.net
There are several ways you can calculate a rank, and some (e.g. self join) are inherently slow. Maybe the problem is as simple as not having the right clustered index? Or maybe sql dbs can do more optimization if you tell them to use their rank function instead of selecting out a rownum? Postgres 8.4+, sql server 2005+, and Oracle all have rank functions (one of the 'window functions' in the SQL:2003 standard http://en.wikipedia.org/wiki/Window_function_(SQL)#Window_fu... )
In general I agree though. If you relax the consistency requirement slightly you can get away with regenerating the rank table every minute or so. It takes ~500ms on my machine to generate the ranked table for 500k rows on PG9. Unlogged tables in 9.1 would probably make it faster.
1) On get_rank() do a count(*) where score < users_score;
2) Store row_number() over() [...] order by score in a lookup table and refresh every so often. Use this for get_rank() lookups.
The problem I have is that you either have to calculate the rank on read using a linear-time count() or on write which means updating n/2 rows on average with their new position.
edited formatting
I am concerned about the complexity of this approach though and I don't think the concessions we're doing away with are that terrible. How meaningful is it to be rank 5623 vs. rank 5249, or even rank 2519? I don't think people can make much sense of ranks beyond 100, but maybe I'm wrong. I would rather break rankings into smaller groups. Which is more interesting, being ranked 23,528 worldwide, or being the town champion? I think the latter is much more meaningful to a person.
As for complexity. The complexity of learning is a noop as far as I'm concerned. Duplicate data? Not concerned. Managing 2 stores...slightly concerning. Agreed. Maintenance? The entire change is largely encapsulated in a new ~30 line Rank class. Sure, I'd rather not have that extra code.
I hadn't considered rank-groups (thanks for the idea though!). I'll definitely give that more thought. Nonetheless, I think I rather have the raw data available and accessible (in addition to any additional abstraction). I don't like making decision for the developers. Maybe 100 ranks isn't enough for them (I've seen them do some pretty creative stuff with the bit of data we're collecting already).
We don't have very high traffic though--we manage roughly 3000 games/hour at our peak times with our one DB server.
The approach has worked well.