数据库规范化:描述特征 - 表的外键或带值的 varchar 字段?

Seb*_*ian 4 normalization database-design application-design

我和我的同事正在讨论数据库中描述性特征的规范化,例如“状态”或“类型”。让我们将讨论的中心表称为“订单”。

在我的常规设计方法中,我会定义另一个表“OrderStatus”来描述订单的状态,然后在“Order”表上创建一个具有关系的外键,即“OrderStatusID”。

这会给我参考完整性。我可以随时加入状态,并且我的可能值始终存在于“OrderStatus”表中。

我的同事不喜欢这种标准化程度,因此他将在“Order”表上定义一个 varchar 字段“OrderStatus”。该字段将直接包含值。

status 的可能值在他的应用程序中定义,更具体地说,在 OrderStatuses 的枚举中定义,因此,除非我可以访问所述应用程序的源代码,否则我无法使用。

我习惯于将数据库的整个上下文作为关系和表存在于数据库中,并且不得不编写“WHERE OrderStatus = 'Sold'”而不是“WHERE OrderStatusID = 3”让我感到烦恼。

怎么想?我正在寻找两种方法的优点和缺点,但我主要关注性能和可读性/可维护性。

gbn*_*gbn 9

您应该使用查找表

  • 并非所有客户端都会在应用程序中使用 ENUM
    您将在某个时候获得报告或 MIS 或 Excel 应用程序连接
  • 否则怎么做“不存在”?
    你会被问到这个
  • 您不会知道客户端枚举更改
  • 与 tinyint 相比,字符串效率低下,尤其是当您需要为 WHERE 子句对其进行索引时
  • 数据和数据库将比客户端应用程序寿命更长

另外,请参阅这些:


one*_*hen 5

您描述的设计选择与规范化没有直接关系。

我同意应该有一个查找表。

我认为一个OrderStatusID值会增加冗余。状态(文本)值大概已经满足了一个好键的许多品质:独特、稳定、狭窄、用户熟悉等VARCHAR。当然,引用完整性可以应用于列!每个使用该键的应用程序都可以根据需要为其分配一个枚举,并负责将枚举值映射到状态(文本)值。这大概会使查找表成为单列,“全键”表(因此将满足 6NF,最高范式;)

[如果 OrderStatusID 是Order表中的一个属性,那么它就不会在 6NF 中,但是,正如我所说,我认为您实际上根本没有在询问规范化。]