我有一个表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并具有相同的一组值才能设置外键?最佳做法是什么? 最佳答案 简短的答案:枚举存储为数字,因此从技术上讲,您可以将tkSkill作为tinyint加入它们。要将其用作外键,您确实需要同时将tkSkill和level都设为相同的枚举-但是您需要将level用作unique列才能成为外键,因此添加到它(准确地说:对于InnoDB,如果您手动创建索引,则可以使用非唯一的外键,但是非唯一的外键通常是个坏主意)。但是您应该考虑unique中的密钥应该是什么,因为现在看起来好像您希望sklllevel作为密钥。并且除了将其作为键之外,您还应该将Name定义为(相同)枚举,以确保如果您想更改枚举(这是一个坏主意!),例如增加另一个技能水平;或者,当您直接从表tkSkill中选择而不需要加入testskill时,如果要“读取”(直接理解)该值;并且如果您想使用它们的枚举值将值插入tkSkill中(例如,使用“专家”代替3,但您可以同时使用两者),而无需在sklllevel中查找它们。更长的答案:最佳实践是:不要使用枚举。根据“信仰”,只有少数情况可能没有枚举(如果有的话)枚举可能会稍微有用的情况。一种可能是您不想使用引用表来跳过联接以显示整数ID的文本值/描述。在您的设置中,您实际上正在使用参考表,但仍想使用枚举。最接近使用枚举的最佳实践的方法是将sklllevel定义为tkSkill中的枚举,并且根本没有testskill-表(参考表)。但是,我再次敦促您不要使用枚举。您可以将表定义为CREATE TABLE `sklllevel` ( `Id` tinyint(4) primary key, `Name` varchar(20) NOT NULL,) ENGINE=InnoDB DEFAULT CHARSET=utf8;然后将该ID用作sklllevel的外键。甚至CREATE TABLE `sklllevel` ( `Name` varchar(20) primary key) ENGINE=InnoDB DEFAULT CHARSET=utf8;然后将tkSkill定义为tkSkill并将其用作外键-虽然它将使用更多空间,但是如果您是第一个使用枚举的原因,则表中将具有“可读”值地点。在这里您可以找到枚举的一些背景:8 Reasons Why MySQL's ENUM Data Type Is Evil关于mysql - 在另一个表中引用MySQL ENUM,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49958222/ 10-09 01:17