在同一个表上处理多个多对多关系?

时间:2019-02-04 16:48:20

标签: mysql database-design

我是偶然的DBA。我使用的大多数数据模型都可以表示为简单的一对多关系,这里或那里的奇数结点表可以对偶发的多对多关系进行建模。我遇到了一种新情况,我不确定该建模的正确方法。

我的应用程序要求可以用几种不同的方式修改特定的属性,而这些方式需要单独指定。考虑一下D&D的一个例子,其中的怪物可以具有抵抗力,免疫力或脆弱性,不受各种伤害类型的影响(例如“抗酸,火和闪电,易受寒冷影响)

在此示例中,我的第一个想法是为怪物,修改类型和伤害类型以及它们之间的连接表构建单独的表-如下所示。

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)
)

此功能有效,但感觉...很糟糕。 我想我也可以为每种修改类型制作单独的表格...

monster--|
         |-Resistance
dmg_type-|

monster--|
         |-Immunity
dmg_type-|

monster--|
         |-Vulnerability
dmg_type-|

...但是感觉也不对。是否有用于对这种行为进行建模的标准?

很抱歉,如果这是重复的-我正在学习如何描述这种事情的特定行话。

1 个答案:

答案 0 :(得分:0)

@Jeremy在原始帖子评论中的输入很有启发性。在这种情况下,似乎并没有真正解决这种情况的“正确”方法,而答案很大程度上取决于具体情况。在我的特定用例中,我最终为关系的每个维度创建了一个表,并使用一个类似结的表来描述关系本身:

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

在我的特定业务案例中,我们很可能会定期添加或删除修饰符(就像是“添加dmg_mod_types”一样),这使得根据需要添加和删除非常容易。如果这些修饰符及其相关值更加静态,那么将它们分成单独的表,或者确实在“怪物”表中添加一列来代表修饰符可能更有意义。

谢谢您的输入-我将此问题标记为已结束。