在另一个表中引用MySQL枚举

在另一个表中引用MySQL枚举,mysql,enums,constraints,Mysql,Enums,Constraints,我创建了一个表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 Ex

我创建了一个表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作为具有相同值集的枚举来设置外键?这里最好的做法是什么?

简短回答:枚举存储为一个数字,因此从技术上讲,您可以将它们与
tkSkill
作为一个小字符串连接起来

要将其用作外键,您确实需要将
tkSkill
level
都设置为相同的枚举-但您需要
level
成为
unique
列才能限定为外键,因此需要将
unique
添加到其中(确切地说:对于InnoDB,如果手动创建索引,您可以使用非唯一外键,但非唯一外键通常不是一个好主意)。但是您应该考虑
sklllevel
中的键应该是什么,因为现在看起来您希望
Name
成为键

如果您想更改枚举(这是个坏主意!),例如添加另一个技能级别;或者如果您想“阅读”(直接理解),则应将
tkSkill
定义为(相同)枚举,以确保它们的含义相同当您直接从表
testskill
中选择时的值,而无需加入
sklllevel
;如果您想通过使用值的枚举namoe将值插入tkSkill(例如,“Expert”而不是3,但您可以同时使用这两个值),而无需在
sklllevel
中查找它们

较长的回答:最佳实践是:不要使用枚举。取决于“信念”,枚举可能稍微有用(如果有的话)的情况很少。一种可能是您不想使用引用表跳过连接以显示整数id的textvalue/说明。在您的设置中,您实际上使用的是引用表,但仍然希望使用枚举

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

但是,我再次敦促您不要使用枚举

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)
,并将其用作外键-虽然它会占用更多空间,但如果这是您首先使用枚举的原因,那么表中会有“可读”值

在这里,您可以找到枚举的一些背景: