Steffan Long
Steffan Long

Reputation: 337

Database Design - Confused

The image below is what I have so far.

What I have so far

The Design

The Emitters Table

Emitters have their own properties such as location (in terms of x and y), id, level, and the last time this information was updated. More importantly, emitters can be defended by any clan member. Emitters can only be defended by a member of that clan. One emitter can be defended by many players.

The Players Table

Or rather, clan members. This table contains information about the players specifically. This also has location in terms of x and y and other information about that player. (I'll probably add lastupdated here, too) One player can defend multiple emitters.

The Emitter_Player Join Table

This table contains a single emitter_player combination. (providing one such relationship exists) Let me first ask if this is a proper relationship between emitters and players? I figured it would be many-to-many. Now, I could make this easy on myself and just add defensepoints to this join table (what I really care about is how much "defense" a player has in a specific emitter) Is this also a correct thing to do? However, I'd like to "do it right the first time" and add information about each specific unit a player has defending this emitter.

The Units Table

This table contains information about all of the units in the game. This table has the units id and it's associated defensive and offensive values. This table will very rarely be inserted into, and when it is (new units are added to the game) it will be updated manually.

The Problem

Fixing the design

Emitters do not contain units outside of players. A player must be the owner of every unit in an emitter. So, there is no relationship between emitters and units. Also, while a player likely has units outside of the emitters, I do not care for this example. I only care about the units that are in an emitter. So, I figured that there would be a many-to-many relationship between the Emitter_Player join table and the Units table. My reasoning behind this is that an Emitter_Player combination can easily have many different types of units and one type of unit can be in many different Emitter_Player combinations.

Inserting information

With two join tables, I am now extremely confused on how to insert information into this database.

Querying information

Again, I am extremely lost how to access information from this database.

The Goal

Graphs

I would like to eventually create graphs (from both players and emitters) showing their progress over time. How I will query this I do not know.

Weekly Changes

I would like to be able to inform players whether they have made progress since last week or lost progress. (and in this case, flag them for review)

Conclusion

I tried to make this as detailed as possible, if you need any more information please let me know. I'm hoping to get this finished soon and I'm really at a complete loss of any ideas further.

Upvotes: 2

Views: 182

Answers (1)

Zane Bien
Zane Bien

Reputation: 23125

You're off to a fairly decent start, but I'd recommend a few suggestions:

It seems to me that you can consolidate the emitters_has_players_has_units table into the emitters_has_players table. Simply make the unit_id a third component in the primary key of emitters_has_players:

enter image description here

You'll also notice I added a quantity column to the particular emitter-player-unit associations. This is necessary to keep track of how many of a particular unit a particular player has for a particular emitter.

It's also good practice to keep your column names consistent throughout your database. The way you named your id columns originally was quite long (as it included the full table names as prefixes).


So here are some examples of how you can query the above design:

-- Get all associated emitters of a particular player
SELECT a.*
FROM   emitters a
JOIN
(
    SELECT DISTINCT emitter_id 
    FROM emitters_has_players 
    WHERE player_id = 1
) b ON a.emitter_id = b.emitter_id

-- Get all players associated with a particular emitter
SELECT a.*
FROM   players a
JOIN
(
    SELECT DISTINCT player_id 
    FROM emitters_has_players 
    WHERE emitter_id = 1
) b ON a.player_id = b.player_id

-- Get the count of players for a particular emitter
SELECT COUNT(DISTINCT player_id) AS player_count
FROM   emitters_has_players
WHERE  emitter_id = 1

-- Get all units associated with a particular player-emitter association
SELECT b.*
FROM   emitters_has_players a
JOIN   units b ON a.unit_id = b.unit_id
WHERE  a.emitter_id = 1 AND a.player_id = 1

-- Get the defense points of a particular player-emitter association
SELECT   SUM(b.averagedefense * a.quantity) AS total_def_pts
FROM     emitters_has_players a
JOIN     units b ON a.unit_id = b.unit_id
WHERE    a.emitter_id = 1 AND a.player_id = 1

-- Create a new player-emitter-unit association
INSERT INTO emitters_has_players 
VALUES (1,1,1,1) -- Where the fourth "1" is the quantity of units initially.

-- Player adds on one more of a particular unit for a particular emitter
UPDATE emitters_has_players
SET    qty = qty + 1
WHERE  emitter_id = 1 AND
       player_id  = 1 AND
       unit_id    = 1

Upvotes: 1

Related Questions