【问题标题】:Referring MySQL ENUM in another table在另一个表中引用 MySQL ENUM
【发布时间】:2016-05-03 22:32:00
【问题描述】:

我有一个表 SkillLevel 创建为

CREATE TABLE `sklllevel` (
  `Name` varchar(20) NOT NULL,
  `level` enum('No Experience','Beginner','Expert','Advisor') DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

有价值观

INSERT INTO test.sklllevel (name,level) values ('No Experience','No Experience'),('Beginner','Beginner'),('Expert','Expert'),('Advisor','Advisor');

我想在另一个创建为的表中使用testSkill.tkSkill 引用 SkillLevel.Level:

CREATE TABLE `testskill` (
  `pkid` int(11) NOT NULL,
  `name` varchar(45) DEFAULT NULL,
  `tkSkill` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`pkid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我是否需要将 tkSkill 作为 ENUM 并具有相同的值集才能设置外键?这里的最佳做法是什么?

【问题讨论】:

    标签: mysql enums constraints


    【解决方案1】:

    简答:枚举存储为一个数字,所以从技术上讲,您可以将它们与tkSkill 作为一个小整数加入它们。

    要将其用作外键,您确实需要将 tkSkilllevel 设为相同的枚举 - 但您需要将 level 作为 unique 列才有资格作为外键,所以添加 unique 到它(准确地说:对于 InnoDB,如果你手动创建索引,你可以有非唯一的外键,但非唯一的外键通常是个坏主意)。但是您应该考虑一下sklllevel 中的密钥应该是什么,因为现在看起来您希望Name 成为密钥。

    并且独立于将其作为键,您应该将 tkSkill 定义为(相同的)枚举,以确保如果您在某一时刻想要更改枚举(这是一个坏主意!)它们的含义相同,并且例如添加另一个技能级别;或者如果你想“读取”(直接理解)直接从表中选择时的值testskill而不需要加入sklllevel;如果您想通过使用枚举名称(例如“专家”而不是 3,但您可以同时使用两者)将值插入 tkSkill,而无需在 sklllevel 中查找它们。

    更长的答案:最佳做法是:不要使用枚举。根据“信念”,只有少数情况下枚举可能稍微有用(如果有的话)。一种可能是您不想使用引用表来跳过连接以显示整数 ID 的文本值/描述。在您的设置中,您实际上是在使用参考表,但仍想使用枚举。

    使用枚举最接近最佳实践的方法是将tkSkill 定义为testskill 中的枚举,并且根本没有sklllevel-table(参考表)。

    但是,我再次敦促您不要使用枚举。您可以将表定义为

    CREATE TABLE `sklllevel` (
      `Id` tinyint(4) primary key,
      `Name` varchar(20) NOT NULL,
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    然后使用该 id 作为tkSkill 的外键。甚至

    CREATE TABLE `sklllevel` (
      `Name` varchar(20) primary key
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    然后将 tkSkill 定义为 varchar(20) 并将其用作外键 - 虽然它将使用更多空间,但如果这是您使用枚举的原因,您将在表中具有“可读”值首先。

    在这里你可以找到枚举的一些背景:8 Reasons Why MySQL's ENUM Data Type Is Evil

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-11
      • 2023-03-22
      • 1970-01-01
      • 2013-11-02
      • 1970-01-01
      • 1970-01-01
      • 2021-05-01
      相关资源
      最近更新 更多