“多对多”关系

时间:2017-03-29 19:11:53

标签: mysql sql database

我有一个简单的化妆品数据库。每种产品可能由多种成分组成。因此,这是一个简单的多对多关系,目前我有一个这样的数据库:

CREATE TABLE `products` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` TEXT NOT NULL,
  PRIMARY KEY (`id`),
);

CREATE TABLE `ingredients` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `name` TEXT NOT NULL,
  PRIMARY KEY (`id`),
);

CREATE TABLE `ingredient_to_product` (
  `ingredient_id` INT UNSIGNED NOT NULL,
  `product_id` INT UNSIGNED NOT NULL,
  PRIMARY KEY (`ingredient_id`, `product_id`),
  INDEX (`product_id`)
);

然而,一些成分可以有许多不同的名称。例如:“LINALOOL ESSENTIAL OIL”,“LINALYL ALCOHOL”和“3,7-DIMETHYL-1,6-OCTADIEN-3-OL”是指相同的成分。

当我展示一种产品时,我想将产品名称保留在产品标签上。因此,对于一种产品,它将是“LINALYL ALCOHOL”,如果是另一种产品,它可能是其他产品,但指的是相同的成分。

现在我想通过指定其中一个名称或其ID来查询数据库的所有产品名称,但是一个ID如何引用多个名称?我是否必须保留两个表:一个用于一般特定成分,另一个表用于名称(多个名称与一个成分的关系)?还有更好的办法吗?

3 个答案:

答案 0 :(得分:2)

<强> Ingredients

  • ID(int)(pkey)(ai)
  • Name(varchar)

<强> Synonyms

  • ID(int)(pkey)(ai)
  • IngredientID(int)(外键映射到:Ingredients.ID
  • Name(varchar)
  • Flag(可选;样本值:IUPAC NameCommon NameSpanish Name,...)

所以是的,对于您描述的规则,您至少会有一个主要名称,然后使用Ingredients.ID

的同义词表

我还引入了一个Flag字段,以便您可以以编程方式选择何时使用同义词,而不是一直对其进行硬编码。例如,如果您要列出标记为industrial chemical的产品,则会将其编程为提取IUPAC *名称

* IUPAC是指化学品命名的惯例,几乎总是由专业化学家使用,但几乎从未在消费者超市使用:http://www.chem.uiuc.edu/GenChemReferences/nomenclature_rules.html

答案 1 :(得分:0)

我想好消息是一个名字不能用于多种不同的成分,对吗?

所以是的,你可能需要一个“成分名称”表,比如

`name` TEXT NOT NULL,
`ingredient_id` INT UNSIGNED NOT NULL

(我可能只是在这里使用名称作为PK,但是如果你的设计要求总是使用代理人,那么还要添加ingredient_name_id我猜...)

然后ingredient(名称除外)的详细信息仍会出现在成分表中。 (你可以在配料表中保留一个默认名称,但我不会。如果你需要这个概念,我会考虑在配料名称表中添加一个“默认标志”或者其他东西那样的。)

由于您想知道给定产品所使用的每种成分的名称,您可以将当前的“成分与产品外部参照”替换为“成分名称到产品外部参照”。

答案 2 :(得分:0)

为什么不为其他成分名称/化学名称等创建单独的表格,并将其与产品ID连接,以便在需要时单独使用,并避免在您的产品中使用任何NULL值主要表。