代码之家  ›  专栏  ›  技术社区  ›  nightcoder

如何对数据库中的打开/关闭状态建模?

  •  1
  • nightcoder  · 技术社区  · 17 年前

    假设我有一个orders表,其中包含orderid(pk)、customerid、customerdern等列。现在,我需要添加一种可能性来“关闭”订单,并指定订单关闭的原因(例如“提供的价格对于客户来说太高”、“不可用”、“客户要求关闭订单”)。

    问题1。 在数据库设计中,最好和正确的方法是什么?

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

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

    我认为,如果我只是将closeReasonID列添加到orders表中,那将是不好的。但我不确定。

    提前谢谢。

    5 回复  |  直到 17 年前
        1
  •  4
  •   Jani Hartikainen    17 年前

    如果您有一堆想要使用的特定结束原因,并且如果您需要能够基于特定类型的结束原因执行查询(例如,通过原因x获取全部),那么您建议的是一个好主意-空或结束原因ID。

    另一方面,如果不需要搜索等,只需关闭一个列,另一个列描述关闭的原因。

        2
  •  3
  •   David    17 年前

    我建议使用statuscode列(可能是int数据类型)和包含statuscode(int)和statuscodedescription(varchar)的单独表。如果您或您的最终用户稍后考虑其他可能的状态,这将给您更多的灵活性。

        3
  •  1
  •   Mark Bostleman    17 年前

    就我个人而言,我会按照您的建议做查阅表格,但称之为状态。我将使orders表中状态表的外键为int,而不是NULL,默认值为1。

    然后状态表中的记录将是(1)打开,(2)关闭原因1,(3)关闭原因2等。这样,您就可以映射到更高层中的枚举,而无需在存储过程中执行任何特殊操作。也就是说,您所要做的就是在您的选择中包含statusID,而不是把处理空值当作一件事来处理,把查找值当作另一件事来处理。

        4
  •  0
  •   Akash Kava    17 年前

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

    有两列,一列是由david指定的布尔值或状态码,出于某种原因将列分开。这使您的设计更易于阅读。

    但我将向前迈出一步,财务相关软件的最佳实践是内置审计跟踪,因为我当然想知道……

    “谁关闭了订单?” “什么时候关门?” “它是重新打开的吗?”

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

    订单审计 & AuditID -有序 ->更改人 ->更改日期时间 ->更改列 ->更改值

    这将完全控制谁用这个命令做了什么,什么时候做了什么。

        5
  •  0
  •   Erwin Smout    17 年前

    一个额外的表,用于保存仅关闭这些订单的关闭原因。

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

    编辑

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

    从“数据库系统简介”,8ed.:“如果且仅当在每个relvar的合法值中,每个元组仅包含每个属性的一个值时,relvar就处于1nf中。”(而且,空值不可能是一个值,因为它不等于自身)。