简体   繁体   中英

Handling multiple many-to-many relationships on same table?

I'm an accidental DBA. Most of the data model that I work with can be expressed as simple one-to-many relationships, with the odd junction table here or there to model the occasional many-to-many relationship. I've run across a situation that is new to me and I'm unsure of the correct way to model it.

My application dictates that a specific property can be modified in a few different ways that need to be specified discretely. Consider an example from D&D, where a monster can have resistance, immunity, or vulnerability from various damage types (such as "Resists Acid, Fire, and Lightning, Vulnerable to Cold)

In this example, my first thought is to construct separate tables for monsters, modification type and damage type, and a junction table between them all - something like below.

CREATE TABLE monsters (
    id char(32) NOT NULL,
    monster_name varchar(100) NOT NULL,
    PRIMARY KEY (id)
)

CREATE TABLE dmgModTypes (
    id char(32) NOT NULL,
    dmg_modifier varchar(20) NOT NULL,
    PRIMARY KEY (id)
)

CREATE TABLE dmgTypes (
    id char(32) NOT NULL,
    dmg_type varchar(25) NOT NULL,
    PRIMARY KEY (id)
)

CREATE TABLE monster_dmg_mod (
    id char(32) NOT NULL,
    monster_id char(32) NOT NULL,
    dmgModType_id char(32) NOT NULL,
    dmgType_id char(32) NOT NULL,
    PRIMARY KEY (id),
    KEY monster_dmg_mod_monster_id_fk_monsters_id (monster_id),
    KEY monster_dmg_mod_dmgModType_id_fk_dmgModTypes_id (dmgModType_id),
    KEY monster_dmg_mod_dmgType_id_fk_dmgTypes_id (dmgType_id),
    CONSTRAINT monster_dmg_mod_monster_id_fk_monsters_id
        FOREIGN KEY (monster_id)
        REFERENCES monsters (id),
    CONSTRAINT monster_dmg_mod_dmgModType_id_fk_dmgModTypes_id
        FOREIGN KEY (dmgModType_id)
        REFERENCES dmgModTypes (id),
    CONSTRAINT monster_dmg_mod_dmgType_id_fk_dmgTypes_id
        FOREIGN KEY (dmgType_id)
        REFERENCES dmgTypes (id)
)

This functions, but it feels... bad. I figure I could also make separate tables for each of the modification types...

monster--|
         |-Resistance
dmg_type-|

monster--|
         |-Immunity
dmg_type-|

monster--|
         |-Vulnerability
dmg_type-|

... but that doesn't feel quite right either. Is there a standard for modeling this kind of behavior?

Apologies if this is a duplicate - I'm learning the specific jargon of how to describe this sort of thing as I go.

@Jeremy's input in the comments to the original post was very instructive. It would seem that in this case there isn't really a 'right' way to handle this sort of situation, and the answer depends largely on context. In my particular use-case, I ended up creating tables for each dimension of the relationship with a junction-like table to describe the relationship itself:

monster------|
             |
dmg_type-----|--Junction (cols. for monster, dmg_mod_type, dmg_type)
             |
dmg_mod_type-|

In my specific business case, where we may well be adding or removing modifiers periodically ('adding dmg_mod_types', as it were), this makes it very easy to add and remove as needed. If those modifiers and their related values were more static, it might make more sense to break them out into separate tables, or indeed to add a column to the 'monster' table to represent the modifier.

Thank you for the input - I'm marking this question as closed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM