Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I use an ENUM for primary and foreign keys?

Tags:

sql

enums

mysql

An associate has created a schema that uses an ENUM() column for the primary key on a lookup table. The table turns a product code "FB" into it's name "Foo Bar".

This primary key is then used as a foreign key elsewhere. And at the moment, the FK is also an 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(). Am I correct?

I'd prefer to have the FKs be CHAR(2) to reduce the lookups. I'd also prefer that the PKs were also CHAR(2) to reduce it completely.

The benefit of the ENUM()s is to get constraints on the values. I wish there was something like: CHAR(2) ALLOW('FB', 'AB', 'CD') that we could use for both the PK and FK columns.

What is:

  1. Best Practice
  2. Your preference

This concept is used elsewhere too. What if the ENUM()'s values are longer? ENUM('Ding, dong, dell', 'Baa baa black sheep'). Now the ENUM() is useful from a space point-of-view. Should I only care about this if there are several million rows using the values? In which case, the ENUM() saves storage space.

like image 362
RickMeasham Avatar asked Feb 16 '09 03:02

RickMeasham


3 Answers

ENUM should be used to define a possible range of values for a given field. 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.

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.

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.

IMHO, using an ENUM for the primary key type violates the KISS principle.

like image 176
David Segonds Avatar answered Oct 24 '22 08:10

David Segonds


but when you only trapped with differently 10 or less rows that wont be a problem

e.g's

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

like image 40
Rami Jamleh Avatar answered Oct 24 '22 08:10

Rami Jamleh


We've had more discussion about it and here's what we've come up with:

Use CHAR(2) everywhere. For both the PK and FK. Then use mysql's foreign key constraints to disallow creating an FK to a row that doesn't exist in the lookup table.

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.

I'm still interested in comments and other thoughts.

like image 2
RickMeasham Avatar answered Oct 24 '22 10:10

RickMeasham