2013-12-19 57 views
0

我正在创建一个MySQL数据库,并且遇到了一个需要多态关联的实例......很明显,SQL不支持这个,所以我决定为每个外键创建一个列;发现下面:试图避免多态关联

CREATE TABLE mixers (
mixers_id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, 
name VARCHAR(255) NOT NULL, 
0_booze_id INT(11), 
0_gen_booze_id INT(11), 
0_gen_soda_id INT(11), 
0_soda_id INT(11), 
1_booze_id INT(11), 
1_gen_booze_id INT(11), 
1_gen_soda_id INT(11), 
1_soda_id INT(11), 
2_booze_id INT(11), 
2_gen_booze_id INT(11), 
2_gen_soda_id INT(11), 
2_soda_id INT(11), 
3_booze_id INT(11), 
3_gen_booze_id INT(11), 
3_gen_soda_id INT(11), 
3_soda_id INT(11), 
4_booze_id INT(11), 
4_gen_booze_id INT(11), 
4_gen_soda_id INT(11), 
4_soda_id INT(11), 
5_booze_id INT(11), 
5_gen_booze_id INT(11), 
5_gen_soda_id INT(11), 
5_soda_id INT(11), 
6_booze_id INT(11), 
6_gen_booze_id INT(11), 
6_gen_soda_id INT(11), 
6_soda_id INT(11), 
7_booze_id INT(11), 
7_gen_booze_id INT(11), 
7_gen_soda_id INT(11), 
7_soda_id INT(11), 
8_booze_id INT(11), 
8_gen_booze_id INT(11), 
8_gen_soda_id INT(11), 
8_soda_id INT(11), 
9_booze_id INT(11), 
9_gen_booze_id INT(11), 
9_gen_soda_id INT(11), 
9_soda_id INT(11), 
FOREIGN KEY (0_booze_id) REFERENCES booze(booze_id), 
FOREIGN KEY (1_booze_id) REFERENCES booze(booze_id), 
FOREIGN KEY (2_booze_id) REFERENCES booze(booze_id), 
FOREIGN KEY (3_booze_id) REFERENCES booze(booze_id), 
FOREIGN KEY (4_booze_id) REFERENCES booze(booze_id), 
FOREIGN KEY (5_booze_id) REFERENCES booze(booze_id), 
FOREIGN KEY (6_booze_id) REFERENCES booze(booze_id), 
FOREIGN KEY (7_booze_id) REFERENCES booze(booze_id), 
FOREIGN KEY (8_booze_id) REFERENCES booze(booze_id), 
FOREIGN KEY (9_booze_id) REFERENCES booze(booze_id), 
FOREIGN KEY (0_gen_booze_id) REFERENCES gen_booze(gen_booze_id), 
FOREIGN KEY (1_gen_booze_id) REFERENCES gen_booze(gen_booze_id), 
FOREIGN KEY (2_gen_booze_id) REFERENCES gen_booze(gen_booze_id), 
FOREIGN KEY (3_gen_booze_id) REFERENCES gen_booze(gen_booze_id), 
FOREIGN KEY (4_gen_booze_id) REFERENCES gen_booze(gen_booze_id), 
FOREIGN KEY (5_gen_booze_id) REFERENCES gen_booze(gen_booze_id), 
FOREIGN KEY (6_gen_booze_id) REFERENCES gen_booze(gen_booze_id), 
FOREIGN KEY (7_gen_booze_id) REFERENCES gen_booze(gen_booze_id), 
FOREIGN KEY (8_gen_booze_id) REFERENCES gen_booze(gen_booze_id), 
FOREIGN KEY (9_gen_booze_id) REFERENCES gen_booze(gen_booze_id), 
FOREIGN KEY (0_gen_soda_id) REFERENCES gen_soda(gen_soda_id), 
FOREIGN KEY (1_gen_soda_id) REFERENCES gen_soda(gen_soda_id), 
FOREIGN KEY (2_gen_soda_id) REFERENCES gen_soda(gen_soda_id), 
FOREIGN KEY (3_gen_soda_id) REFERENCES gen_soda(gen_soda_id), 
FOREIGN KEY (4_gen_soda_id) REFERENCES gen_soda(gen_soda_id), 
FOREIGN KEY (5_gen_soda_id) REFERENCES gen_soda(gen_soda_id), 
FOREIGN KEY (6_gen_soda_id) REFERENCES gen_soda(gen_soda_id), 
FOREIGN KEY (7_gen_soda_id) REFERENCES gen_soda(gen_soda_id), 
FOREIGN KEY (8_gen_soda_id) REFERENCES gen_soda(gen_soda_id), 
FOREIGN KEY (9_gen_soda_id) REFERENCES gen_soda(gen_soda_id), 
FOREIGN KEY (0_soda_id) REFERENCES soda(soda_id), 
FOREIGN KEY (1_soda_id) REFERENCES soda(soda_id), 
FOREIGN KEY (2_soda_id) REFERENCES soda(soda_id), 
FOREIGN KEY (3_soda_id) REFERENCES soda(soda_id), 
FOREIGN KEY (4_soda_id) REFERENCES soda(soda_id), 
FOREIGN KEY (5_soda_id) REFERENCES soda(soda_id), 
FOREIGN KEY (6_soda_id) REFERENCES soda(soda_id), 
FOREIGN KEY (7_soda_id) REFERENCES soda(soda_id), 
FOREIGN KEY (8_soda_id) REFERENCES soda(soda_id), 
FOREIGN KEY (9_soda_id) REFERENCES soda(soda_id) 
)ENGINE=InnoDB; 

我想这样做,是设置表,以便为每个组的成分 -

0_booze_id INT(11), 
0_gen_booze_id INT(11), 
0_gen_soda_id INT(11), 
0_soda_id INT(11) 
  • 只能使用一列(三列必须为空)或者所有四个组必须为空。

是否有可能创建类似这样的? 如果不是,那么更好的解决方案是什么?

编辑 澄清 - 我正在做一个自动饮料搅拌机器人。我试图创建一个数据库,允许在没有特定成分的情况下使用通用成分。

例如,如果配方需要“杰克”和“可乐”,并且我有可用的成分“杰克”和“可乐”,那么我会想要使用这些特定的成分。然而,可以说我有一些可口可乐,我想用可乐代替。我希望专门为“杰克”和“可乐”调用的食谱能够用“可乐”代替“普通可乐”。

我的目的是创建两个通用表格,一个用于汽水,另一个用于豪饮“gen_soda”“gen_booze”。这些表格将包含诸如“可乐”,“威士忌”,“伏特加”等项目。表格汽水和酒会含有特定的成分名称,如“可乐”或“杰克丹尼尔斯”;这些项目将被引用回它们的泛型类型。

我最初发布的搅拌机表包含了机器人知道如何制作的所有各种混合饮料。应该提供的唯一混合饮料是具有特定成分的饮料。这就是我遇到术语多态关联的原因。

+2

嗯,规范化任何人? – Strawberry

+2

你的表格看起来非常不规范。你能用简单的语言描述你想要的数据吗(避免像“多态关联”这样的术语)?这通常有助于构建数据模型。 –

+0

我试图在我的编辑中描述我的最终目标。如果你需要更多的细节,请让我知道,我可以尝试澄清我自己多一点。 – kubiej21

回答

2
CREATE TABLE mixers (
    mixer_id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    mixer_name VARCHAR(255) NOT NULL, 
) 

CREATE TABLE ingredients (
    ingredient_id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, 
    ingredient_name VARCHAR(255) NOT NULL, 
) 

CREATE TABLE mixer_ingredients 
    mixer_id INT(11) NOT NULL, 
    ingredient_id INT(11) NOT NULL, 
    PRIMARY KEY (mixer_id, ingredient_id), 
    FOREIGN KEY (mixer_id) REFERENCES mixers(mixer_id), 
    FOREIGN KEY (ingredient_id) REFERENCES ingredients(ingredient_id), 
) 
+0

我花了一段时间了解这里发生了什么,但现在我已经考虑了这几天,现在这一切都有意义。谢谢您的帮助! – kubiej21

0

我明白你想要做什么,但认为这是错误的做法。您的数据模型需要更好地适合您的问题。

首先,开始与成分表,与像列:

  • ingredientId
  • ingredientName
  • ingredientType

然后MixedDrink表:

  • MixedDrinkId
  • MixedDrinkName

然后,在MixedDrinkIngredient表:

  • MixedDrinkIngredientId
  • MixedDrinkId
  • IngredientId

所以,这个处理的混合饮料没有换人。你如何表达他们?

好了,在这一点上,你需要做出一些决定。替代通用为成分?或者是一些MixedDrinks而不是其他的替代物?根据这些问题的答案,取决于您需要的规则,替代信息可能会在MixedDrinkIngredients,Ingredients或两者中出现。

顺便说一下,酒精和苏打之间的区别嵌入type信息Ingredients。这是一种简化,您可能实际上需要一个层次结构,并在层次结构中的特定位置进行替换。例如,你可能愿意用百事可乐替代可口可乐,而不是姜汁啤酒。

+0

我很感激帮助,但我现在有点困惑。为了回答你的问题,我的意图是能够用可口可乐或法伊可乐等其他特定成分代替可口可乐,或用普通可口可乐类型代替可口可乐(如果特定成分未添加到数据库)。所以,我想我失去了替代信息应该进入哪个表。查看您对MixedDrinkIngredient的建议,当只有一个IngredientID列时,如何包含多个成分? – kubiej21