I would say two things.
First my answer to your question. Secondly what I think you should do instead.
1. Answer:
SQL, its easy to develop and test + production for some time.
A table for Players, with INT or some other uniq value, not strings. (I know you said its a sample, but go for "long word" ints that ought to give you enough unique ID's
Same goes for Game. Now the thing to keep the highscores together would be to have a relation between the two.
Score (Table relation):
[Player ID][Game_ID][Score]
Where score is a numeric value... I dont know the max score of each of your games, so you figure out what type is enough.
Now, this should be quite easy to implement for a start. Get that to work. But dont make every call directly to the database.
Make a 3-TIER architecture. Make a datalayer and a businesslayer and then the "game" layer.
So every game calls the businesslayer with its own "game ID" like:
PlayerSaveScore(int gameID, int playerID, int score)
The Businesslayer then checks that the "parameters" are of the correct size and are valid ID's, perhaps validates that this player actual has been in a session the past 5 minutes etc.
After validation, then the Businesslayer calles the datalayer for "update table" where the datalayer first looks if the record exists. IF not, then it inserts it.
Tier design
Once you are "online" (in air) and the games becomes popular, then you can start to "upgrade", but you are still able to get going now with a "furture scaleable solution". Just remember that EVERY game MUST call to the business object/layer, not directly - NEVER!
I've been in the same "thought ooh so many times" but I kept getting into one simple loop called preparation, but that has almost never gotten me into a realistic solution thats up and running fast.
So get 100000 players first! then start worrying when it grows beyond.
2. Part to... how to scale... suggestion:
So here is my reason for all the trouble of building the "businesslayer/webservices"...
And best of all, your speed problems can be solved nicely now.
You can implement "cache" quite simple.
You make an extra table, if you only have 15 games, you dont need a table pr. game, but you decide. That one ONLY keeps the TOP 100 of each game. each time you post a new record from a player, you make a select on this "top 100" and checks if the posted value comes into the list. if it does, then handle that by updating the top 100 table and for extra speed purpose.
Build the extract of Top 100 as a static datalist, eg. XML or similar static data. Depending on your platform, you pick the right "static format" for you.
You could even improve speed further. Just keep the smallest value needed to get on top 100 of each game. That would be a record pr. game.
Then match the player score against the game's "lowest score in top 100"... if its above, then you have some "caching/indexing" to do and THEN you call the "giant sort" :o)
Get the point? I know its a very long answer, but I wanted to post you a "complete" solution.
Hope you will mark this as your answer :o)