4

I have 3 tables that I am trying to properly create relationships between:

  • game phase
  • game event (a step in a 'game phase')
  • action window (a radically different kind of step in a 'game phase')

A 'game phase' can have one or more 'game event(s)', and a 'game event' can happen in one or more 'game phase(s)'. (Many-to-many)

A 'game phase' can have one or more 'action window(s)', and an 'action window' can happen in one or more 'game phase(s)'. (Many-to-many)

A 'game event' is not related to an 'action window'.

However, I hesitate to create 2 separate junction tables because both 'game events' and 'action windows' share the same order of occurrence (aka sequence) numbering system per 'game phase'. I'm not sure how I would maintain that.

What is the most proper way to lay out these tables while still being able to easily track the order of occurence?

Somnath Muluk
  • 55,015
  • 38
  • 216
  • 226
Glyph
  • 526
  • 5
  • 20
  • 1
    So "game events" and "action windows" *are* related by order of occurrence? My gut suggests going with a single intersection table having sequence number as the primary key. Can you post some (partial) table definitions? – Darwin von Corax Nov 29 '15 at 21:03
  • The sequence number will have to be editable. Games have rule changes so I wouldn't want to set it in stone by making it the primary key. It would work as another column. I am still hesitant to make any junction table with 3+ foreign keys. It'd have to have a constraint that only allows either "game events" id or "action windows" to be filled out. – Glyph Nov 30 '15 at 00:01
  • For any given `game phase`, is the number of `events` and `actions` always the same? In other words, is it possible, that some phase has 5 events and 6 actions? If yes, what will be the sequence numbers for them? If yes, I'd create two separate junction tables, if no, I'd create one junction table. – Vladimir Baranov Nov 30 '15 at 03:29
  • Game event and action window both being steps, are these two tables very different from each other or quite similar? Could you show us your table definitions? – Thorsten Kettner Nov 30 '15 at 09:48
  • @VladimirBaranov Yes it is possible for one phase to have 5 events & 6 actions. The sequence numbers would be 1 through 11 in any order needed. – Glyph Nov 30 '15 at 22:40
  • 1
    @Glyph, so you need 11 rows somewhere to store sequence numbers from 1 through 11. It may make sense to have an extra separate table for sequence numbers after all. – Vladimir Baranov Dec 01 '15 at 00:52

2 Answers2

2

Make one table junction like:

game_phase_steps

+----+-----------+-------+----------+---------+
| id | phase_id  | rank  |   type   | step_id |
+----+-----------+-------+----------+---------+
|  1 |         1 |    1  | event    |       2 |
|  2 |         1 |    2  | action   |       1 |
+----+-----------+-------+----------+---------+
  • id - primary key for game_phase_steps
  • phase_id - foreign key for game phase
  • rank - unique order of occurrence of step in game phase
  • type - game phase can have event or action
  • step_id - event_id for foreign reference of game event or action_id for foreign reference of action window

Don't know how your game_event and action_window are structured. But if you need all data in single query, them you probably need to perform two left joins, one onto game_event and one onto action_window, and return the fields you want from the appropriate join table something like this:

game_phase_steps g
LEFT JOIN game_event e
    ON game_phase_steps.type = "event" 
        AND game_phase_steps.step_id = e.id
LEFT JOIN action_window a
    ON game_phase_steps.type = "action" 
        AND game_phase_steps.step_id = a.id

and if your tables are structured differently then you might need select statement like this:

SELECT CASE WHEN g.type = "event" THEN e.some_field ELSE a.some_field END
Community
  • 1
  • 1
Somnath Muluk
  • 55,015
  • 38
  • 216
  • 226
  • Thank you for the well thought out answer. Is it possible for one foreign-key column (step_id in your example) to point to 2 primary keys like that? I'm using PostgreSQL. This might be something I can google but I thought I'd ask. – Glyph Nov 30 '15 at 23:02
  • You don't need to tie foreign key by structure. You can tie that logically. Id type is `event` then step_id would be primary key of game_event table. You can see [this reference](http://stackoverflow.com/questions/441001/possible-to-do-a-mysql-foreign-key-to-one-of-two-possible-tables) If you want to make tight structure. Then you can make 2 different tables for references with foreign keys. And make one more table referencing those 2 tables for order (i.e. rank). – Somnath Muluk Dec 01 '15 at 05:30
2

I suggest a design that represents sequences of 'game events' and 'action windows', related each other by belonging to a same sequence in the same sequence step.

That is to say, introducing "gaming sequence" and "gaming sequence detail" entities, the junction table is avoided "by design", representing the shared sequencing fact of 'game event(s)' and 'action window(s)' by mean of having the same sequence step in a "gaming sequence" (avoidance due to the consideration that "A 'game event' is not related to an 'action window'").

SCHEMA

+--------------+ 1      1,n +-------------------+ 1,n
|  game_phase  +------------+  game_phase_play  +----+
|              |            |                   |    |
+--------------+            +-------------------+    |
                                                     |
                                                     | 1
+--------------------------+ 1,n         1 +---------+---------+
|  gaming_sequence_detail  +---------------+  gaming_sequence  |
|                          |               |                   |
++--------+----------------+               +-----+-------------+
 | 1,n    |                                      |
 |        +---+  seq_step                        +---+ seq_steps_number
 |
 |
 |                                      +--------------+
 |                                +-----+  game_event  |
 | 1,n +----------------+         |     |              |
 +-----+  gaming_value  | <-------+     +--------------+
       |                |         |     +-----------------+
       +----------------+         +-----+  action_window  |
                                        |                 |
                                        +-----------------+

PREFIXES

gph_                    === game_phase_
gseq_                   === gaming_sequence_
gv_                     === gaming_value_

TABLES

game_phase              ( id , description, ... )
game_phase_play         ( id , gph_id, gseq_id, date, description, ... )
gaming_sequence         ( id, seq_steps_number, ... )
gaming_value            ( id , type, ... )
gaming_sequence_detail  ( gseq_id, gv_id, seq_step, ... )

I've also introduced a generalization entity for 'game event(s)' and 'action window(s)' named "gaming value", useful for being contained in a "gaming sequence". This generalization could represent a kind of gaming immutable value (of 2 different types in our case, but extensible) and so the chosen naming (had been switching from "gaming objectified" and "gaming observable").

'gaming value(s)' of the two types are "stepped together" in the gaming sequence by means of equality of the (gseq_id, seq_step) pair in gaming_sequence_detail (one could argue that this kind of "pairing" is a relationship; this kind of solution acts more like representing sibilings in a sequence step, permitting also to extend to more than 2 types of 'gaming values').

'game event(s)' and 'action window(s)' in a gaming sequence detail could be independently modified and also could appear "unpaired".

A constraint in gaming_sequence_detail is that for every seq_step value could exist one game_event and one action_window and so the maximum cardinality of seq_step for a single gseq_id is 2.

If it's the case, the same gaming_value could also appear more than once in the same sequence. Moreover this design could also represent shared sequences between different 'game phase play(s)'.

rfb
  • 1,107
  • 1
  • 7
  • 14
  • Hi, thanks for the response. Could you explain what gaming_observable is? – Glyph Dec 01 '15 at 01:00
  • Hy @Glyph. I have got difficulties for naming this entity, due maybe to my poor english. Anyway i switched from "gaming objectified" but could more appropriately be named "gaming value". It's some kind of gaming value type isolated in different immutable values. – rfb Dec 01 '15 at 08:00
  • I've updated with new naming and explanation. Thanks for the voting :) – rfb Dec 01 '15 at 18:00