I'm facing the normalization dilemma.
Now that OpenID has been declared a failure, I would like to incorporate it into my web site. I'm also gonna throw in FB Connect while I'm at it.
Clearly this means I will have a 1:many relationship between accounts and logins. That is straightforward. However, it also means that not all types of login are the same.
This means I need to decide how to store three sets of similar-in-function but different-in-form information pieces. THAT means that I have to make annoying choices and I'm not sure if there is a winning "best" solution. This is why I come to you
I see three immediate options.
Option 1: Logins table with rows for each type
- ID
- Account ID
- Username
- Password
- Facebook ID
- OpenID URL
- OpenID ID
Option 2: Logins table with generic rows
- ID
- Account ID
- Login Type
- Generic Field 1
- Generic Field 2
Option 3: Logins table for each login type
Password Logins
- ID
- Account ID
- Username
- Password
FB Connect Logins
- ID
- Account ID
- Facebook ID
Open ID Logins
- ID
- Account ID
- OpenID URL
- OpenID ID
Having ad hoc rows for each login type in a general logins table (i.e. Option 1) feels dirty and de-normalized.
Having generic rows in a general logins table (i.e. Option 2) feels dirty and highly obfuscated.
Having a separate table for each login type (i.e. Option 3) feels clean/normalized but maybe inefficient and maybe obfuscated.
How would others accomplish this? Are there other options? What will have the most negative implications in reality?
Keep in mind that I would like to incorporate additional login types (e.g. Twitter / next big thig / whatever) as they come along.
Option 3 is your best, IMHO.
1) Security
More than one table has to get stolen in order for you to lose all of your client security data. Think about limiting your risk and liability.
1a) Also...
is there any need for you to know which facebook login is associated with which openID login? Perhaps, but in any case, it sure would be handy for a data thief if you put it all together like that for them (option 1)
2) Table features -- such as triggers, calculated fields, or what have you will probably (?) be used in a unique way for each provider.
3) If you really have to have everything in one table for some odd / ad hoc purpose, you can still accomplish this with a view.
4) Design optimization.
Chances are, the data is pretty similar, but still... Maybe datatypes wouldn't be a motivator, but partitioning / indexing / etc. would be relevant.
5) Unique requirements.
Who knows what next big thing may require. Think scalability without having to re-define your existing structures (quite so much).
I'm sure there are other relevant thoughts on this...but that's off the top of my head, for what it's worth.