简体   繁体   English

我应该使用ENUM作为主键和外键吗?

[英]Should I use an ENUM for primary and foreign keys?

An associate has created a schema that uses an ENUM() column for the primary key on a lookup table. 关联者已创建一个模式,该模式在查找表上使用ENUM()列作为主键。 The table turns a product code "FB" into it's name "Foo Bar". 该表将产品代码“FB”转换为其名称“Foo Bar”。

This primary key is then used as a foreign key elsewhere. 然后,该主键在其他地方用作外键。 And at the moment, the FK is also an ENUM() . 目前,FK也是一个ENUM()

I think this is not a good idea. 我认为这不是一个好主意。 This means that to join these two tables, we end up with four lookups. 这意味着要连接这两个表,我们最终会进行四次查找。 The two tables, plus the two ENUM() . 这两个表加上两个ENUM() Am I correct? 我对么?

I'd prefer to have the FKs be CHAR(2) to reduce the lookups. 我更喜欢让FK成为CHAR(2)以减少查找次数。 I'd also prefer that the PKs were also CHAR(2) to reduce it completely. 我也更喜欢PK也是CHAR(2)来完全减少它。

The benefit of the ENUM() s is to get constraints on the values. ENUM()的好处是获得对值的约束。 I wish there was something like: CHAR(2) ALLOW('FB', 'AB', 'CD') that we could use for both the PK and FK columns. 我希望有类似的东西: CHAR(2) ALLOW('FB', 'AB', 'CD')我们可以用于PK和FK列。

What is: 什么是:

  1. Best Practice 最佳实践
  2. Your preference 你的偏好

This concept is used elsewhere too. 这个概念也在别处使用。 What if the ENUM() 's values are longer? 如果ENUM()的值更长怎么办? ENUM('Ding, dong, dell', 'Baa baa black sheep') . ENUM('Ding, dong, dell', 'Baa baa black sheep') Now the ENUM() is useful from a space point-of-view. 现在, ENUM()从空间的角度来看很有用。 Should I only care about this if there are several million rows using the values? 如果有几百万行使用这些值,我应该只关心这个吗? In which case, the ENUM() saves storage space. 在这种情况下, ENUM()可以节省存储空间。

ENUM should be used to define a possible range of values for a given field. ENUM应该用于定义给定字段的可能值范围。 This also implies that you may have multiple rows which have the same value for this perticular field. 这也意味着您可能有多个行,这些行具有相同的值。

I would not recommend using an ENUM for a primary key type of foreign key type. 我不建议将ENUM用于主键类型的外键类型。

Using an ENUM for a primary key means that adding a new key would involve modifying the table since the ENUM has to be modified before you can insert a new key. 使用ENUM作为主键意味着添加新密钥将涉及修改表,因为必须先修改ENUM,然后才能插入新密钥。

I am guessing that your associate is trying to limit who can insert a new row and that number of rows is limited. 我猜你的同事试图限制谁可以插入一个新行,并且该行数是有限的。 I think that this should be achieved through proper permission settings either at the database level or at the application and not through using an ENUM for the primary key. 我认为这应该通过数据库级​​别或应用程序的适当权限设置来实现,而不是通过使用ENUM作为主键。

IMHO, using an ENUM for the primary key type violates the KISS principle . 恕我直言,使用ENUM作为主键类型违反了KISS原则

but when you only trapped with differently 10 or less rows that wont be a problem 但是当你只用不同的10行或更少的行捕获时不会有问题

e.g's e.g的

CREATE TABLE `grade`(
    `grade` ENUM('A','B','C','D','E','F') PRIMARY KEY,
    `description` VARCHAR(50) NOT NULL
) 

This table it is more than diffecult to get a DML 获取DML不仅仅是这个表

We've had more discussion about it and here's what we've come up with: 我们已经对它进行了更多的讨论,这就是我们提出的:

Use CHAR(2) everywhere. 到处使用CHAR(2)。 For both the PK and FK. 对于PK和FK。 Then use mysql's foreign key constraints to disallow creating an FK to a row that doesn't exist in the lookup table. 然后使用mysql的外键约束来禁止在查找表中不存在的行中创建FK。

That way, given the lookup table is L , and two referring tables X and Y , we can join X to Y without any looking up of ENUM() s or table L and can know with certainty that there's a row in L if (when) we need it. 这样一来,给查找表是L ,和两个指表XY ,我们可以加入XY没有任何抬头的ENUM() S或表L ,可以肯定地知道,有一排L ,如果(当) 我们需要。

I'm still interested in comments and other thoughts. 我仍然对评论和其他想法感兴趣。

Having a lookup table and a enum means you are changing values in two places all the time. 拥有查找表和枚举意味着您始终在两个位置更改值。 Funny... We spent to many years using enums causing issues where we need to recompile to add values. 有趣......我们花了很多年时间使用枚举导致我们需要重新编译以添加值的问题。 In recent years, we have moved away from enums in many situations an using the values in our lookup tables. 近年来,在许多情况下,我们已经使用查找表中的值从枚举中移除了。 The biggest value I like about lookup tables is that you add or change values without needing to compile. 我喜欢查找表的最大值是您无需编译即可添加或更改值。 Even with millions of rows I would stick to the lookup tables and just be intelligent in your database design 即使有数百万行,我也会坚持使用查找表,只是在数据库设计中保持智能

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM