如何在关系数据库中表示枚举类型?


12

我正在开发一个关系数据库,该数据库跟踪我正在为公司工作的设备上发生的交易。设备上可能发生不同类型的事务,因此我们的一个主记录表中有一个“ trans_type”字段。我的小组决定将该字段的类型设置为整数,并将其视为枚举类型。我的直觉告诉我,将这个字段设置为字符串是一个更好的主意,以便我们的数据库数据更具可读性和可用性。我的同事们似乎担心这会造成更多的麻烦,而不是值得的。字符串比较的成本太高,而且错别字的可能性太大。

因此,您认为,当处理关系数据库中的字段本质上是枚举值时,将该字段设为整数或字符串是否是更好的设计决策?还是我忽略了其他选择?

注意:我们使用的数据库不支持显式枚举类型。我们正在开发的将与此数据库连接的软件是用C ++编写的。


它是否会拖延其他任何人,只要在create table中将其作为检查的类型定义?类似于:CREATE TABLE hit(ip varchar(40),ip_class ENUM(0,“ IPv4”,1,“ IPv6”)); 它应该允许您用序数或字符串(映射到序数)检查= <和>。
dlamblin

Answers:


26

枚举类型应该是数据库中一个单独的表,该表应具有ID号和字符串名,以及其他可能有用的列。然后,每种类型在此表中都作为一行存在。然后在您的表中记录事务,“ trans_Type”字段应该是该引用表的键的外键。这是数据库规范化的标准做法。

这样,您可以存储一个正式的名称字符串,使用数字比较来提高性能,并具有参照完整性,即每个事务都具有有效的类型。


1
是的,如果您决定将“ O”更改为“ Open”,则只需更改一行。
Daniel Kaplan 2013年

+1。一个简单的int / string表是表示关系数据库中枚举的最佳方法。
mike30 2013年

可能正在寻找Java解决方案的下一个访客发现很有用
Jauhien 2015年

2
这个。值得一提的是-如果开发团队已经在Java / C#枚举或类似名称中定义了整数,则可以编写一个测试来检查代码枚举的定义是否与查找表不同。总是存在这样一种危险,即不按顺序添加元素会导致事情失去同步,并且直到实时数据记录看起来不正确时您才意识到。
朱莉娅·海沃德

4

一种常见的做法是创建一个trans_types表,然后让您的主表使用名为的外键对其进行引用trans_type_id。这样可以确保您的记录仅引用有效的枚举类型。

例:

反型
----------
  ID
  名称

交易
------------
  ID
  转换日期
  细节
  trans_type_id(从FK到trans_type.id)

示例数据:

反型

ID | 名称
----------
1 | 提交
2 | 取消


交易

ID | 转换日期| trans_type_id
---------------------------------
1 | 2012-12-31 | 1个
2 | 2013-01-09 | 2

3

如果这些值以整数形式进入数据库,请以这种方式存储它们。写入数据库时​​,无需花太多的时间转换成字符串。您始终可以使用字符串/文本值(更规范化)与查找表相关联。

这具有在单个位置更新字符串值而不是运行某种更新例程的附加优点。而不是1 =“红色”,它可以等于“真的红色”

与仅需要一个带有字符串值的表(非规范化)相比,这对于报告性能不是理想的选择。该字段上的索引将使性能足够好。

大多数RDBMS将具有足够的功能。尽管您的想法是能够以纯数据格式“读取”表,但连接表并不重要。只是养成使用视图或类似对象的习惯。


2

我不同意提倡使用单独的枚举表方法的其他问题。

但是,我当然赞成不重复已经说过的内容,因此我将简单地(对于(或多或少))关于堆栈溢出的同一问题引用已接受的答案:https : //stackoverflow.com/a/229919 / 114626


+1为链接的答案。对于这个问题,您的链接答案似乎是正确的答案。但是,当然,如果发问者希望枚举类型具有灵活性,则参考表会更好。
哈克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.