1

想象一下,我有一个包含 OrderID (PK)、CustomerID、CustomerOrderN 等列的 Orders 表。现在我需要添加“关闭”订单的可能性,并指定关闭订单的原因(例如“报价对客户来说太高”、“不可用”、“客户要求关闭订单”)。

问题 1.在数据库设计中实现这一点的最佳和正确方法是什么?

我认为最好的方法是创建可以为空的已关闭列(如果订单已打开),如果不为空(即如果订单已关闭),则该值指向另一个表 OrderCloseReasons。

问题 2.如果我已经在 Orders 表中有一个已关闭的布尔列怎么办,现在我需要实现指定关闭原因的可能性。我不能重构太多,因为系统已经不是那么小了,所以很难重构数据库方案。在这种情况下,增加指定关闭原因的可能性的最佳方法是什么?

我认为如果我只是将 CloseReasonID 列添加到 Orders 表中,那就不好了。但我不确定。

先感谢您。

4

5 回答 5

4

如果您有一堆想要使用的特定关闭原因,并且如果您需要能够基于特定类型的关闭原因执行查询(例如通过原因 X 获取全部),那么您的建议是一个不错的选择idea - null,或关闭原因 ID。

另一方面,如果您不需要搜索等,您可以简单地关闭一列,另一列描述关闭原因。

于 2009-07-25T20:49:01.393 回答
3

我会推荐一个 StatusCode 列(可能是 int 数据类型)和一个包含 StatusCode (int) 和 StatusCodeDescription (varchar) 的单独表。如果您或您的最终用户稍后想到另一种可能的状态,这将为您提供更大的灵活性。

于 2009-07-25T20:54:44.733 回答
1

就个人而言,我会按照您的建议进行查找表,但将其称为状态。我会将 Orders 表中 Status 表的外键设为 int,而不是 null,默认值为 1。

然后状态表中的记录将是(1)打开,(2)关闭原因一,(3)关闭原因二等。这样您就可以映射到更高层中的枚举,而无需在您的存储过程。也就是说,您所做的只是在您的 SELECT 中包含 StatusID,而不必将 null 视为一件事而将查找值视为另一件事。

于 2009-07-25T21:03:00.723 回答
0

将 null 和 reason 合并到一个可以为 null 的文本列中并不是一个好主意,因为几天后其他程序员甚至您可能都无法轻松阅读它。

有两列,一列是 David 指定的布尔值或状态码,并有单独的列。这使您的设计更具可读性。

但我会提前一步,财务相关软件的最佳实践是内置审计跟踪,因为我当然想知道..

“谁关闭了订单?” “几点关门的?” “重新打开了吗?”

审计跟踪通常由另一个表组成,例如,

OrderAudit -> AuditID -> OrderID -> ChangeMadeBy -> ChangeDateTime -> ChangeColumn -> ChangeValue

这将完全控制谁使用此订单以及何时执行此操作。

于 2009-07-25T21:06:50.903 回答
0

一个附加表,其中包含仅那些已关闭的订单的关闭原因。

它不违反 1NF,因为您没有在数据库模式中引入空值,并且您有最绝对的保证,您的更改不会影响现有的东西(您明确指出这是本例中的主要问题)。

编辑

参见数据库日期:Writings 2000-2006 (Springer-Verlag, 2006) 中的“第一范式的真正含义”。也可能作为独立论文在互联网上找到。

以及来自“数据库系统简介”,第 8 版。:“当且仅当在该 relvar 的每个合法值中,每个元组的每个属性都恰好包含一个值时,一个 relvar 在 1NF 中。” (并且 null 不可能是一个值,因为它不等于它自己)。

于 2009-07-25T21:09:31.477 回答