何时在关系型数据库中使用枚举或小表?

44

我在数据库中有几个小实体,我用两列表格表示:id和名称。这些实体的示例包括国家、大陆等。

如果这些实体的名称不重要,我应该创建枚举类型吗?


使用枚举类型相比于自定义类型,您认为有什么好处?最大的缺点是如果ID更改或添加新项,则客户端必须重新编译。 - D Stanley
这是一个很好的观点,但是什么情况下使用枚举而不是小表?我的担忧始于建模数据库时看到到处都是小表,因此想到使用枚举会让图形看起来更简单。 - ehmicky
10
大陆不会经常改变 :) - Mariusz Jamro
国家,然而,确实 - mbx
然而,国家们 - undefined
4个回答

45

很抱歉用问题回答问题,答案取决于情况。您期望这些值多久更改一次?您发布代码的频率是多少?

枚举类型需要进行代码更改。纯数据库表格更易于更改。编码时,枚举类型更方便。

如果您发布频率较低或者经常有新/删除/更改的值,建议使用数据库表格。如果数据集是静态的或者您经常发布代码,请使用枚举类型。


问题:为了性能,枚举类型更好吗? - Just a coder
“频繁”是如何被认为是“频繁”的?更新周期为5年是否被认为是频繁的? - Irfandy Jip
2
嗨@Irfandy,我会说5年在任何标准下都不常见...请注意我上面提到的版本发布。问题是:当值发生变化时,您能否及时发布更新的软件/值以满足您的需求? - Barett

35

当需要限制可能取值的范围时,例如星期几、性别、票务状态(已开/已关闭/已存档)时,使用枚举类型是很好的选择。

  • 可以降低存储空间的消耗,每个元组只需占用1个字节。
  • 能够减少联接时的磁盘访问次数。

但在以下情况下,使用枚举类型则不太适合:

  • 当您无法确定可能的取值时。
  • 当可能的取值会发生变化时,由于更改需要管理员权限来 ALTER 表格,这可能需要将表格离线维护。

3

使用枚举类型可以提高性能,因为字符串比无符号整数包含更多的数据。一般来说,只要您确定不会更改枚举映射,就可以采用这种方法,尤其是从编码人员的角度来看。但是,如果您想在数据库本身中运行原始SQL,则需要引用代码以查找所有整数的含义,这会变得有些棘手。


1
这里的一个重要点是关于直接访问数据库的可能性。当然,你可以编写一个API,但如果不这样做,对枚举引用的查询将只是一个无信息的整数,无法提供有关值的含义或可用值范围的任何信息。 - statler

3
一种备选策略是使用同步枚举。编写代码以将表格同步到枚举相对容易。在这种情况下,您可以获得代码的好处,并且在数据库表中也可以使用数据。
有时将数据存储在表中很重要,例如在具有多种访问数据库方式的情况下。例如,您可能有一个单独的业务报告应用程序直接从数据库提取数据。如果仅运行枚举,则数据库将仅包含没有关于值代表什么或可查询的可接受值范围的解释的整数。
同步代码可能如下所示(此处我正在使用ORM,但原则应清晰)。我的代码仅处理添加案例-其他情况可能需要编辑甚至删除枚举到数据库。为了获得更多控制,您可以在枚举键上放置属性,以记录不同文本作为数据库中的描述。
            foreach (ApprovalCategoryEnum category in Enum.GetValues(typeof(ApprovalCategoryEnum)))
            {
                ApprovalCategory asc = existingCategories.FirstOrDefault(x => x.ApprovalCategoryId == (int)category);
                if (asc == null)
                {
                    ApprovalCategory newCategory = new ApprovalCategory(session);
                    newCategory.ApprovalCategoryId = (int)category;
                    newCategory.Description = category.ToString().Replace("_", " ");
                    newCategory.Save();
                }
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接