外键是否应该在用户可以选择多个选项的结构中使用?如果是这样,怎么会这样?

时间:2011-10-05 14:46:29

标签: mysql database database-design foreign-keys relational-database

在MySQL中,我被建议将“Drugs”的多项选项存储为单独的表user_drug,其中每一行是特定用户选择的选项之一。我还建议创建第3个表drug,该表描述表user_drug中选择的每个选项。这是一个例子:

user
id    name  income
1     Foo   10000
2     Bar   20000
3     Baz   30000

drug
id    name
1     Marijuana
2     Cocaine
3     Heroin

user_drug
user_id drug_id
1       1
1       2
2       1       
2       3
3       3

如您所见,表格user_drug可以包含特定用户选择的多种药物,而表格drug会告诉您每个drug_id所指的药物。

我被告知外键应该将表user_drugdrug绑在一起,但我从未处理过外键,所以我不知道该怎么做。

摆脱药物表并简单地将每种药物的TEXT值存储在user_drug中会不会更容易? 为什么或为什么不呢?

如果添加第3个表drug更好,那么我将如何实现外键结构,以及如何使用这些外键正常检索相应的值?

(我发现仅使用2个表就容易得多,但我听说外键有用,因为它们确保输入正确的值,并且搜索和排序{{{{{{ 1}}比文本值,所以我想确定。)

2 个答案:

答案 0 :(得分:3)

  

摆脱药物表并简单地将每种药物的TEXT值存储在user_drug中会不会更容易?为什么或为什么不呢?

更容易,是的。
但并不是更好。

  1. 您的数据不会被标准化,浪费大量空间来存储表格。
  2. 该领域的索引会占用更多空间,再次浪费空间并减慢速度。
  3. 如果要查询可能值的下拉列表,那么使用单独的表就可以轻松实现(硬:read(慢),只需要字段中的文本)。
  4. 如果您只是将文本字段放在1个表格中,则很难确保拼写错误无法进入,使用单独的链接表可以轻松防止拼写错误。
  5.   

    如果添加第3表药物更好,那么我将如何实现外键结构

    ALTER TABLE user_drug ADD FOREIGN KEY fk_drug(drug_id) REFERENCES drug(id);
    
      

    我如何使用这些外键正常检索各自的值?

    SELECT u.name, d.name as drug
    FROM user u
    INNER JOIN user_drug ud ON (ud.user_id = u.id)
    INNER JOIN drug d ON (d.id = ud.drug_id)
    

    不要忘记将表user_drug的主键声明为

    PRIMARY KEY (user_id, drug_id)
    

    <强>替代地
    你可以使用枚举

    CREATE TABLE example (
      id UNSIGNED INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
      example ENUM('value1','value2','value3'),
      other_fields .....
    

    您没有获得单独表格的所有好处,但如果您只想要一些值(例如yes/nomale/female/unknown),并且您希望确保它仅限于只有这些价值才是一个很好的折衷方案 还有更多自我记录和强大的魔法常数(1 =男性,2 =女性,3 =未知,......但如果我们插入4会发生什么?)

答案 1 :(得分:1)

  

摆脱药物表并简单存储会不会更容易   user_drug中每种药物的TEXT值?为什么或为什么不呢?

通常情况下,您在药物表上还有很多其他专栏 - 例如描述,医疗信息,化学特性等。在这种情况下,您不希望在每个记录中复制所有这些信息。 user_drug表。然而,在这种特殊情况下,你只有一个专栏,所以这个问题并不是什么大问题。

此外,您希望确保user_drug表中引用的药物确实存在。例如,如果您将字段存储为文本,那么您可以使用海洛因及其相关的拼写错误,如haroin或herion。当您稍后尝试选择所有海洛因记录时,这会给您带来问题。使用查找表的外键强制id存在于该表中,因此您可以绝对确保所有对海洛因的引用都是准确的。