This is not asking for an opinion, simply what DBA's who are more professional than me tend to do in this situation.
Assume I have a simple lookup table status_type
such as this, where status_id is an autoinc integer PK and status_value is a varchar.
status_id status_value
--------- ------------
1 Active
2 Lapsed
3 Resigned
4 Deceased
5 Demurred
6 Terminated
7 Pending
8 Redacted
and another table person
has a field the_status INT
as a FK linked to status_type
from which I can deduce the status string pertaining to that person. This is easy to maintain and I can alter the text of the status_value if necessary without altering the person
record and can add new status values as needed.
If, inside a stored procedure, I want to update table person
and change someone's status, say to 'Resigned', is it best practice / more common to say
(a) UPDATE person
SET the_status = 3
WHERE personID = 1234;
or
(a) UPDATE person
SET the_status = (SELECT status_id
FROM status_type
WHERE status_value = 'Resigned'
)
WHERE personID = 1234;
Option (a) assumes that the ID of 3 will always mean the same as 'Resigned', so it won't matter even if I change the string contained in status_value
to 'Left the company' but it needs a magic number hard coded in the stored proc, which I don't really like.
Option (b) does not require me to hard code 'magic numbers' into the stored proc but requires me to know what status_value
string is currently held in table status_type
to indicate someone voluntarily no longer works for us. Consequently the stored proc will need changing if the status_value
in table status_type
is ever edited.
Is either way more widely used than the other?
Best Answer
This is a little close to an opinionated question, but in general, I think you'll find option a to be the mostly widely used one from the perspective of the database layer. For the purpose of this answer, I'm using the term enum as synonymous with lookup table, for all intents and purposes.
Enums are inherently meant to numerically give meaning to a concept with the added benefit of being able to verbalize that meaning with a name / string value. But it should be a rare event that the meaning of a specific instance of an enum changes from the original meaning for that numerical representation (in fact, if it did, it would likely logically break any existing references to that enum's numerical value). With that in mind, they shouldn't exactly be considered the same as magic numbers (despite being rather close), and it is the string value / name that is more flexible to change.
Should you use option b, you'd run into two issues:
There's a performance difference (though likely negligible in this case) by doing a second lookup on the
status_type
table as opposed to yourUPDATE
statement in option a.If the name / string value of your enum were to change (remember this is very well more possible than the underlying meaning of the instance of that enum's numerical value to change) then your stored procedure would now be broken.
I would go with option a all day.