这不是征求意见,只是比我更专业的 DBA 在这种情况下倾向于做什么。
假设我有一个status_type
像这样的简单查找表,其中 status_id 是 autoinc 整数 PK,status_value 是 varchar。
status_id status_value
--------- ------------
1 Active
2 Lapsed
3 Resigned
4 Deceased
5 Demurred
6 Terminated
7 Pending
8 Redacted
另一个表person
有一个the_status INT
作为 FK 链接的字段status_type
,我可以从中推断出与该人有关的状态字符串。这很容易维护,如果需要,我可以在不更改person
记录的情况下更改 status_value 的文本,并且可以根据需要添加新的状态值。
如果在存储过程中,我想更新表person
并更改某人的状态,比如“辞职”,这是最佳实践/更常见的说法
(a) UPDATE person
SET the_status = 3
WHERE personID = 1234;
或者
(a) UPDATE person
SET the_status = (SELECT status_id
FROM status_type
WHERE status_value = 'Resigned'
)
WHERE personID = 1234;
选项 (a) 假设 ID 3 将始终与“Resigned”表示相同,因此即使我将包含的字符串更改status_value
为“Left the company”也没关系,但它需要一个硬编码的幻数存储过程,我不太喜欢。
选项 (b) 不需要我将“幻数”硬编码到存储过程中,但需要我知道status_value
表中当前保存的字符串status_type
以表明有人自愿不再为我们工作。因此,如果曾经编辑过status_value
in 表,则存储过程将需要更改。status_type
任何一种方式都比另一种更广泛使用吗?
这有点接近一个固执己见的问题,但总的来说,我认为从数据库层的角度来看,您会发现选项 a是最广泛使用的选项。出于此答案的目的,出于所有意图和目的,我将术语enum用作查找表的同义词。
枚举本质上旨在以数字方式赋予概念以数字含义,并具有额外的好处,即能够使用名称/字符串值来表达该含义。但是,枚举的特定实例的含义从该数字表示的原始含义发生变化应该是一个罕见的事件(事实上,如果发生这种情况,它可能会在逻辑上破坏对该枚举数值的任何现有引用)。考虑到这一点,它们不应该被视为与幻数完全相同(尽管相当接近),而且更改更灵活的是字符串值/名称。
如果您使用选项 b,您会遇到两个问题:
status_type
通过对表进行第二次查找而不是您在选项 aUPDATE
中的语句,存在性能差异(尽管在这种情况下可能可以忽略不计)。如果您的枚举的名称/字符串值要更改(请记住,这比更改该枚举的数值实例的潜在含义更有可能)那么您的存储过程现在将被破坏。
我会选择一整天。