Database Model - Tournaments for eSports - mysql

I'm quite new to Database Modelling and I'm struggling a bit with my Tournament Module Structure.
The following is what I managed to come up with so far:
Click here
Overview:
(TABLE) Seasons - All tournaments/leagues/ladders fall under it. Plain & simple.
(TABLE) Tournaments:
Related to the 'parent'->seasons via season_id
Tournament Format - allow 1vs1 or team-based participation.
Tournament Type - as the name hints: tournament, league, ladder
The rest in Tournaments is pretty self-explanatory so I'll skip ahead.
(SUB-TABLE)Tournament Entries - 1 Table Row per Every Participating Player, AND Team (If format is Team-based). It's moderated with column is_team (= 0, means Player Entry).
(SUB-TABLE)Tournament Matches - connected to Tournaments via entry_id->tournament_id (Possible?). Columns team A & B are populated based on entry_id->is_team (When 0 assigns entry_id->player_id otherwise entry_id->team_id).
(TABLE) Player Statistics - 1 Table Row per Every Team PLAYED FOR during Tournament => meanning, a Player can:
Transfer teams in the same tournament.
View previous recorded stats during the time he played for them.
I'm struggling with structuring current stage/phase of the tournament, play-offs, groups, single/double elimination, loser bracket and round-robin. In addition, how to track 'Best of' type of matches. How do I track that and create matches (new and based on previous results)?
Also, are my created relations & indexes correct and efficient?
NOTE: don't pay attention to the field types, it will be re-organized.
Thanks in advance!

Related

SQL First Normal Form (1NF) vs Serialisation

Lets say I have a football team table, where player names are tied to positions:
teamId: 1
goalkeeper: 'Marc'
position1: 'John'
position2: 'Erik'
...
But now I also want one attribute that represents the players NOT taking into account positions. I would create a new attribute teamString serialising all players sorted alphabetically (this will ensure that different Teams with same players will have the same teamString attribute):
teamString: Eric-John-Mark[...]
Now I can filter Teams with same players even if they play in different positions.
Will this new attribute teamString be against 1NF principle?
Thanks in advance
Your teamString attribute would be a violation of the 1NF as your teamString property would contain multiple values. And it would reference values existing in non-key attributes of the same entity (maybe a 3NF violation but I'm not sure about it).
The issue here is that you treated specific positions in a team as attributes of the team and not as a relation.
I'd make a relation between team and player:
team (1, n) - (0, n) player
A team may have one to many players.
A player may play for zero to many teams.
As both max cardinalities are to n you'd get a Many To Many relation which implies a join table with foreign keys from both sides (the team id + player id). In this table you can add a column for the position type.
This means you should get rid of the position columns (goalkeeper, position1, ...) in the team table.
The position table could look like:
team_id
player_id
type
1
12
goal_keeper
1
15
position1
2
12
position_2
Then the application could be responsible for checking that a team has only a limited number of players for a specific position. But for modeling you should stick to the 0, 1 & "n" values that you use in cardinalities.

How to SELECT next available award from available awards

I am in process of designing my database.
It's a simple online course, which users can earn points by achieving certain goals. For instance, if a user passes a quiz with score over 90, then 50 'iq' points are awarded to student.
My specific question here is, How would I find out the NEXT available award, and how many points are needed to obtain award.
So here is my idea of the tables (very truncated here for brevity of course):
Users table
id
name
points_balance
Awards table
This table holds all available awards.
id
award_name
points
award_sql
The award_sql column holds a sql statement to run to find out if the user is eligible for this award. For example, I could add a sql statement here to check to see if the user logged in three consecutive days. If true, user eligible for this award.
User_awards
Holds the awards a user already obtained
id
user_id
award_id
date_awarded
So the ideal query would do the following:
Check to see if the user qualifies for the award and doesn't already have it
Based on the list returned above, I need to know which which award is CLOSEST in points.
Schema Is Rough Draft
The table structure above is just my first draft.
I am new to writing SQL
If there is a better way to design my tables, I'd love to hear your suggestion.
Thank you for looking. I have looked into using the MIN function, but that's kinda above my skill set right now.
I would design my Awards tables as below:
Instead of the column "award_sql" in Awards table it would be better to have something like "award_status". This column will have a value "y" or "n" based on the user qualifying for the award.
In this design awards.award_status gets populated or loaded after login_history,quiz_results,referral_table and the remaining dependent tables are loaded. Use the award clause SQL to populate award_status column.

Database Design for Games Attended

I go to a lot of sports games, mostly hockey. I have been tracking the games via an excel sheet and even at one point a simple database table. I am trying to build this a little better and eventually create a web interface. But I also want to be able to run various queries.
I don't care about player goals, ice-time, sog or any of those stats - merely just teams playing, score and date with a section for notes. (eg, Hat trick, 500th game for player)
So what I had was:
(id, home_team, home_score, away_team, away_score, jersey = [home,away,alt], date, notes, timestamp)
I have thought of other ways to normalize it but I don't want to over complicate it and trying to query has been a nightmare.
I had a three table design in mind:
Team
(team_id, city, state, nickname)
League
(league_id, league_name, conference, division)
Venue
(venue_id, venue_name, venue_city, venue_state, venue_zip, venue_address, venue_capacity)
Venue table and even league table seem unnecessary for the most part but I was thinking of different types of queries.
Then I would create some views or a games table that would pull in the necessary fields.
Queries I had in mind to execute:
Games attended that the home team won
How many times my team has played whatever team and overall record
Games won/lost wearing alternate jersey, home jersey, away jersey
Venues visited and record when visiting
Games attended where there has been a significant event. (Hat trick, record)
Overall record of games attended in x year, all time.
Playoff game record, preseason game record, regular season record (I was thinking I could notate game type in notes or create a field for type and do (playoff, preseason, regular)
Any advice would be appreciated, its not that I do not know how to build the database, it is that I do not know how to build it right and without stressing over the entire website I want to build from it.
Eventually I would like to expand it to other sporting events (football, baseball, basketball, etc..) but before getting too far ahead of myself I would like to get the hockey one running.
Thanks in advance

MYSQL Relational Schema Planning

I'm trying to figure out the best way to manage this data storage problem....
I have a table of players, teams, and competitions.
A team may be involved in let's say 3 competitions.
A player belongs to a team, but may only be eligible to play in 2 of the 3 competitions that his or her team plays in. Likewise another player of the same team may be eligible for all 3.
I don't want to add a column to the player table for each competition as I'm then moving away from the relational model. Do I need another table 'competition_eligiblity' - this seems like a lot of work though!
Any suggestions?
Thanks,
Alan.
Yes, you do need a table for competition eligibility.
It really is no more work to put it there. Actually, it will be less work:
Adding a new competition in the future will be a real pain if it involves adding a new column to a table.
If the competition eligibility is stored in columns, performing a query to get information on eligibility becomes a nightmare.
Suppose you wanted to list all the competitions players are eligible for. Here would be your query:
select player, "competition1" from players where competition1_eligible = 1
union all
select player, "competition2" from players where competition2_eligible = 1
union all
select player, "competition3" from players where competition3_eligible = 1
union all
select player, "competition4" from players where competition4_eligible = 1
Sounds like fun, eh? Whereas, if you have an eligibility table, this information will be very simple to get.
Update: storing all the eligibility info in a single value would be even more of a nightmare, because imagine trying to extract that information back out of the string. That is beyond the limits of a sane SQL query.
Creating a new table is really a trivial piece of work, and you only have to do that once. Everything after that will be much easier if you do it that way.

Proper way to model user groups

So I have this application that I'm drawing up and I start to think about my users. Well, My initial thought was to create a table for each group type. I've been thinking this over though and I'm not sure that this is the best way.
Example:
// Users
Users [id, name, email, age, etc]
// User Groups
Player [id, years playing, etc]
Ref [id, certified, etc]
Manufacturer Rep [id, years employed, etc]
So everyone would be making an account, but each user would have a different group. They can also be in multiple different groups. Each group has it's own list of different columns. So what is the best way to do this? Lets say I have 5 groups. Do I need 8 tables + a relational table connecting each one to the user table?
I just want to be sure that this is the best way to organize it before I build it.
Edit:
A player would have columns regarding the gear that they use to play, the teams they've played with, events they've gone to.
A ref would have info regarding the certifications they have and the events they've reffed.
Manufacturer reps would have info regarding their position within the company they rep.
A parent would have information regarding how long they've been involved with the sport, perhaps relations with the users they are parent of.
Just as an example.
Edit 2:
**Player Table
id
user id
started date
stopped date
rank
**Ref Table
id
user id
started date
stopped date
is certified
certified by
verified
**Photographer / Videographer / News Reporter Table
id
user id
started date
stopped date
worked under name
website / channel link
about
verified
**Tournament / Big Game Rep Table
id
user id
started date
stopped date
position
tourney id
verified
**Store / Field / Manufacturer Rep Table
id
user id
started date
stopped date
position
store / field / man. id
verified
This is what I planned out so far. I'm still new to this so I could be doing it completely wrong. And it's only five groups. It was more until I condensed it some.
Although I find it weird having so many entities which are different from each other, but I will ignore this and get to the question.
It depends on the group criteria you need, in the case you described where each group has its own columns and information I guess your design is a good one, especially if you need the information in a readable form in the database. If you need all groups in a single table you will have to save the group relevant information in a kind of object, either a blob, XML string or any other form, but then you will lose the ability to filter on these criteria using the database.
In a relational Database I would do it using the design you described.
The design of your tables greatly depends on the requirements of your software.
E.g. your description of users led me in a wrong direction, I was at first thinking about a "normal" user of a software. Basically name, login-information and stuff like that. This I would never split over different tables as it really makes tasks like login, session handling, ... really complicated.
Another point which surprised me, was that you want to store the equipment in columns of those user's tables. Usually the relationship between a person and his equipment is not 1 to 1 and in most cases the amount of different equipment varies. Thus you usually have a relationship between users and their equipment (1:n). Thus you would design an equipment table and there refer to the owner's user id.
But after you have an idea of which data you have in your application and which relationships exist between your data, the design of the tables and so on is rather straitforward.
The good news is, that your data model and database design will develop over time. Try to start with a basic model, covering the majority of your use cases. Then slowly add more use cases / aspects.
As long as you are in the stage of planning and early implementation phasis, it is rather easy to change your database design.