Question :
I have been coding in C# for a couple of years where I usually try to follow the ‘single responsibility principle’ which states that each class should ideally be responsible for only 1 goal. Now I want to design a small database for my app users. My initial go at this is as follows:
I am not sure how the single responsibility principle applies to the database world. Should I split this table into 3 tables, one which holds only the Facebook ID, and another for all high score related fields (HighScore, AllTimeHighScore, ScoreDate, …) and a 3rd for all medal fields, and maybe a 4th table for just the Expert Mode Score, or keep it as is? I know this is probably overkill, but I would like to know the basic principles regarding what can be grouped in a single table.
Note: I would like to take into consideration future proofing. If in the future I decide I want to add a ‘platinum medal’ field, would that change at all how I would want to design my above table now?
Answer :
There are a couple of ways you could model this database. There is nothing wrong with the way you have it right now. However, you could normalize the table structure something like:
CREATE TABLE Player (
facebookId BIGINT NOT NULL,
XP int NULL,
PRIMARY KEY (facebookId)
)
CREATE TABLE Score (
facebookId BIGINT NOT NULL FOREIGN KEY REFERENCES Player(facebookId),
score INT NOT NULL,
scoreDate2 DATETIME NOT NULL,
PRIMARY KEY (score)
)
CREATE TABLE MedalType (
medalType INT NOT NULL IDENTITY(1,1),
medalName VARHCAR(10) NOT NULL,
PRIMARY KEY (medalType)
)
CREATE TABLE PlayerMedal {
medalId BIGINT NOT NULL IDENTITY(1,1),
facebookId BIGINT NOT NULL FOREIGN KEY REFERENCES Player(facebookId),
medalType INT NOT NULL FOREIGN KEY REFERENCES MedalType(medalType),
PRIMARY KEY (medalId)
}
This type of structure would be a lot more flexible. To add your “platinum” medeal, you would add a row to the MedalType table. You could then query the number of medals of that type that the player has from the PlayerMedal table.
For the All-Time High Score, use the Score table with the MAX() function to get their highest score.
Two things that I didn’t quite model properly here are:
- XP — didn’t know what this was, so wasn’t sure where to place it.
- Using facebookId as the primary key – Wouldn’t do this in case you decide your system isn’t going to be solely based on Facebook. Would use an unique key, with facebookId as another column in the table.