At one point, I think it would be healthy to experiment with a different approach.
Just store accounts and characters in a key/value store, currenlty my favorite storage is Riak.
Give new accounts and character a unique id to use as keys, uuid is a good option (https://en.wikipedia.org/wiki/Universally_unique_identifier). Then store all information bound to the account or character as the value in the structured way. My favourite format is JSON.
You can link accounts to characters by having a list of characters uuids in the account data.
Then, instead of making queries to the database, just load up the JSON into the memory of your server, make alterations in memory and occation dump JSON to the database.
It would look something like this:
{
"account": {
"uid": "123e4567-e89b-12d3-a456-426655440000",
"phash": "JDUkTW5mc1E0aU4kWk1UcHBLTjE2eS90SXNVWXMvb2JIbGhkUC5PczgweVhoVHVycEJNVWJBNQ==",
"email_encrypted": "UkNyOXFaajYvanBkaVJHNXVmZnV6THpHR0pSMDVUU2U=",
"email_hash": "17300987ba9482d229e6bc9f3463b4efbdf2564d",
"character_uids": ["522e4867-f89e-13d6-b672-422615122561", "612f2357-d21c-23e4-c152-122665727512"],
"subscription": "bronze"
}
}
Note that texts that contains weird characters is in most cases best to base64 encode, otherwise jsons parsers might not parse correctly. In this example I would recommend passwords to be hashed with SHA-256 or even SHA-512 and encode to base64 encode before storing in the db (I use bcrypt to generate password hashes).
You probably don't want to store people's emails in clear text in your db, so encrypt using a well known method like AES. But now we have the problem that emails probably need to be unique (one email limited to one account), so we can hash it the email and put a secondary index on it (email_hash). This means we could quickly find if an email is already in use in our system.
{
"character": {
"uid": "522e4867-f89e-13d6-b672-422615122561",
"name": "foobar",
"skills": [{
"combat": [{
"1h_sword": 32,
"2h_sword": 12,
"mace": 82,
"shield": 54
}],
"cooking": [{
"pizza": 99,
"soups": 23,
"grilling": 23
}],
"survival": [{
"acrobatics": 56,
"swimming": 23,
"skinning": 52,
"traps": 13
}]
}]
}
}