【问题标题】:Best design for dependent tables in a Work Order Database工单数据库中依赖表的最佳设计
【发布时间】:2016-05-27 13:33:12
【问题描述】:

我正在使用数据库来控制工单,但我在设计数据库时遇到了一些问题。

我有一张桌子:

表工单 - 工单ID - 请求日期 - 请求者 - 图号 - 数量

但我不知道如何以标准化方式创建以下表格:

订单必须只有一种状态:已批准或已拒绝。

  • 已批准订单具有ApprovedBy 字段,属于以下两种情况之一:
    • 已交付:如果订单已交付,则应包含DeliveredDateReceivedByReceivedQuantity。我们需要数量,因为收到的数量可能少于或多于请求的数量。
    • 已取消:如果订单已取消,则应包含CancelDateCanceledByCanceledReason
  • 拒绝订单只有RejectedByRejectedReason 字段。

我希望有人能给我一个想法来处理这个头脑风暴

【问题讨论】:

  • 假设您不需要跟踪 Approved、Rejected 的多个状态,那么您应该将这些字段的 all 放在同一个表中。或者,您可以添加检查约束以确保已批准的记录必须具有 RejectedBy 和 RejectedReason = NULL 等。重要的问题是:您是否需要跟踪状态随时间的多次变化?您将这些放在另一个表中的唯一原因是,如果给定的工作订单随着时间的推移有很多变化需要跟踪。

标签: sql database-design


【解决方案1】:

我会使用如下所示的结构:

表工作订单 - ID - 绘画 - 数量 表状态 - ID - work_order_id(work_orders 的外键) - by(封面由请求、批准、拒绝和取消) - 日期 - 类型(已交付 | 已取消 | 已拒绝 | 已请求) 餐桌招待会 - id(与状态id相同,一对一) - 数量 表取消 - id(与状态id相同,一对一) - 原因 表拒绝 - id(与状态id相同,一对一) - 原因

当您创建订单时,您会在 work_orders 表中添加一个条目,以及请求类型的新状态。

订单送达后,您添加一个新状态和一个具有相同 ID 的接收。您甚至可以使用此系统处理多个部分交付。

当订单被拒绝或取消时,您可以在相应的表格中添加状态和条目。这些表可以合并,但如果你决定为这些类型的状态存储不同的信息,你就会遇到麻烦,所以我可能会从一开始就将它们分开。

要了解订单的当前状态,您只需查询状态表,按日期排序,并获取最后一个条目。您甚至可以通过获取所有相应的状态来显示订单的整个时间线。此外,这种结构允许您交付部分订单,而取消其余部分。

我希望这一切都有意义。随意询问您是否要我详细说明。

【讨论】:

    【解决方案2】:

    您有两个状态值,已批准和已拒绝。已批准进一步细分为两个子状态值,已交付和已取消。让我们首先说我们有三个状态值,Rejected、Delivered 和 Canceled,然后看看我们的设计是如何实现的。

    WorkOrder 表将如问题所示,因此我们需要一个 Status 表,它将状态与工单相关联,包含所有状态值共有的任何数据,并提示我们数据的位置可以找到状态。

    create table Status(
        WOID    int  primary key,
        Value   char( 1 ) check( Value in ('R', 'D', 'C' )),
        By      int   not null, -- who approved, rejected or authorized this status
        AsOf    date  not null, -- and when.
        constraint FK_Status_WorkOrder( WOID)
            references WordOrder( ID ),
        constraint FK_By_Employee( By )
            references Employee( ID )
    );
    

    此时,我们知道将有多个表用于包含状态详细信息(命名为猜测,例如 Rejects、Deliveries、Cancels)。但是我们不能定义一个字段作为其他表的 FK,并且定义三个这样的字段会使运行数据库的设计和数据完整性维护变得复杂。幸运的是,有办法解决它。

    我们所做的是让三个详细表中的 FK 引用状态表。但首先,我们必须通过添加一个额外的约束来准备状态表:

    create table Status(
        ...,
        constraint UQ_Status_By_Type unique( WOID, Value )
    );
    

    如果您注意了,您可能想知道为什么我们要在两个字段上创建唯一索引,其中一个字段本身就是唯一的。原因是定义了三个明细表可以锁定的钩子。

    create table Rejects(
        WOID    int  primary key,
        Value   char( 1 ) check( Value = 'R' ),
        Reason  varchar( 10 ),
        constraint FK_Rejects_Status( WOID, Value )
            references Status( WOID, Value )
    );
    

    其他明细表的定义类似。

    让我们检查一下我们目前所拥有的。状态表的 WOID 字段确保任何工作订单的状态不能超过一个,并且检查约束确保它必须是已拒绝、已交付或已取消之一。如果将 WO 状态定义为,例如,拒绝,则必须在状态表中创建一个值为“R”的条目。因此,只能为该 WO 生成拒绝表中的相应条目(它只能包含值“R”)。 Delivered 表中的条目(其状态值只能为“D”)将被系统拒绝。

    从而保持数据完整性。不幸的是,数据完整性经常在设计结束时被硬塞进去。我认为这应该是主要的设计原则。

    当然,改进是可能的。例如,Status 表的 Value 字段本身可以是查找表的外键,而不是使用检查约束。这样可以方便地在以后添加新的状态值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-09
      • 2016-10-10
      相关资源
      最近更新 更多