在另一个表中引用mysql enum

omvjsjqw  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(501)

我创建了一个表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');

我想引用skilllevel.level testSkill.tkSkill 在另一个创建为的表中:

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作为枚举使用相同的值集来设置外键?这里最好的做法是什么?

wxclj1h5

wxclj1h51#

简而言之:枚举存储为一个数字,因此从技术上讲,您可以将它们与 tkSkill 作为一个小玩意。
要将其用作外键,您确实需要同时具有这两个属性 tkSkill 以及 level 是同一个枚举-但你需要 level 成为一个 unique 列限定为外键,因此添加 unique 更确切地说:对于innodb,如果手动创建索引,可以使用非唯一外键,但非唯一外键通常是个坏主意。但是你应该想想你的钥匙在哪里 sklllevel 应该是的,因为现在看来你想 Name 成为关键。
并且独立于它作为你应该定义的关键 tkSkill 作为(相同)枚举,以确保它们的含义相同,如果您在某一点上想更改枚举(这是一个坏主意!)再增加一个技能等级;或者,当您直接从表中选择时,如果您想“读取”(直接理解)值 testskill 不需要加入 sklllevel ; 如果您想通过使用枚举namoe(例如“expert”而不是3,但是您可以同时使用这两个)将值插入到tkskill中,而无需在中查找它们 sklllevel .
长话短说:最佳实践是:不要使用枚举。根据“信念”的不同,枚举可能稍微有用(如果有的话)的情况并不存在,甚至只有少数情况。一种可能是您不想使用引用表跳过连接来显示integer-id的textvalue/description。在您的设置中,您实际上使用的是引用表,但仍然希望使用枚举。
使用枚举最接近最佳实践的方法是定义 tkSkill 作为中的枚举 testskill 而且没有 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) 并将其用作外键—虽然它会占用更多的空间,但如果这是您首先使用枚举的原因,那么表中会有“可读”的值。
在这里您可以找到一些枚举的背景知识:mysql的枚举数据类型是邪恶的8个原因

相关问题