Designing SQL database for an item with multiple names

时间:2019-03-18 03:09:15

标签: mysql database database-design

I am creating a table for dietary_supplement where a supplement can have many ingredients.

I am having trouble designing the table for the ingredients. The issue is that an ingredient can have many names or an acronym.

For example, vitaminB1 has other names like Thiamine and thiamin. An acronym BHA can stand for both Butylated hydroxyanisole and beta hydroxy acid(this is actually an ingredient for skincare products but I am using it anyways because it makes a good example).

I am also concerned about the spacing and "-". For example, someone can spell vitaminA without spacing and someone can write vitamin A. Also, beta hydroxy acid can also be written as β-hydroxy acid(with "-") or β hydroxy acid(without "-").

What I have in mind are 2 options)

1) put all the names for one ingredient in a column using semi-colon to distinguish between names. eg) beta hydroxy acid;BHA;β-hydroxy acid;β hydroxy acid -this would be easy but I am not sure if this is the smart way to design the database when I have to perform search actions etc.

2) create a table for all the names and relate it with a table for ingredients. -This is the option that I am leaned towards, but I wonder if there are better ways to do this. And do I have to create separate rows for the same items with difference in spacing and "-"?

3 个答案:

答案 0 :(得分:0)

为配料和补品创建表格,并创建一列与配料表和补品相同的列,如果要选择,只需将其加入

答案 1 :(得分:0)

可能是这样的:

CREATE TABLE Ingredient (
      Id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
    , ImagePath VARCHAR(63)
    , Description TEXT
    -- other ingredient's non-name dependent properties
);

CREATE TABLE IngredientName (
      Id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
    , IngredientId INTEGER UNSIGNED NOT NULL
    , IsMain TINYINT(1) UNSIGNED NOT NULL DEFAULT 0
    , Name VARCHAR(63) NOT NULL
    , KEY IX_IngredientName_IngredientId_IsMain (IngredientId, IsMain)
    , UNIQUE KEY IX_IngredientName_IngredientId_Name (IngredientId, Name)
    , CONSTRAINT FK_IngredientName_IngredientId FOREIGN KEY (`IngredientId`) REFERENCES `Ingredient` (`Id`) ON DELETE CASCADE ON UPDATE CASCADE
);

或者您可以添加Ingredient.Name作为主名称,然后删除IngredientName.IsMain。

对于空格,应该在应用程序中使用一些名称规范化,例如删除连续的空格,大写,规范化逗号,破折号周围的空格等。当然,可以根据需要在触发器中对数据库应用此类规范化。

还有其他可能性。

您应该考虑首先使用DB的用户案例。 这个非常重要。没有“最好的通用数据库设计”。 如果您需要一些特殊的搜索案例,则可能需要特殊的数据库设计或至少索引。

P.S。我相信在一个字段中将不同的名称作为分隔的值不是一个好主意

答案 2 :(得分:0)

创建一个从“名称”到“ canonical_name”(或ID)的映射表。它会有像

这样的行
Thiamine   vitaminB1
thiamin    vitaminB1
vitaminB1  vitaminB1
B1         vitaminB1

通过使用以_ci结尾的排序规则,您无需担心大小写。

在提取补充数据时,首先查找name以获取canonical_name,然后在其他任何表中使用后者。

在该2列表中,有

PRIMARY KEY(canonical_name),
INDEX(name, canonical_name)

以便您可以选择任一方向。