Database-Design

儲存使用的過程欄位

  • March 7, 2018

我正在為生產工作(特別是實驗室測試)創建一個數據庫。

大多數Work是用於生產,因此嚴格按照Procedurefor that執行Product。就其本身而言,這很容易建模。參考Work文獻Procedure包含工作的完成方式:

Example Schema
Work:      Work_id, Procedure_id, {other non-relevant fields}
Procedure: Procedure_id, Product_id, Machine_id, Material_id, RunMinutes

兩個例外(覆蓋和特殊測試)增加了設計的複雜性。

**問題:**鑑於以下兩個例外,我應該如何儲存Procedure每個實際使用的欄位Work


例外 - 覆蓋:

有時所需的設備或組件不可用。在這些情況下,經理可以批准一次性替代同等替代品。例子:

  1. 機器 X 壞了。手動執行Work
  2. 我們用完了材料 Y。改用材料 Z。
  3. 將執行時間保持在 45 分鐘

數據庫必須擷取Work實際執行的方式。

我看到三個可能的選擇:

**選項 1:本地儲存:**引用Work原始Procedure. 每個Work還本地儲存Procedure使用的欄位,包括任何修改。這會創建許多重複項,但您對每個Work.

Example Schema
Work_id | Procedure_id    | Machine | Material | RunMinutes
1       | 1               | By-Hand | Z        | 45  

Procedure_id | Product_id | Machine | Material | RunMinutes
1            | 1          | X       | Y        | 45

選項 2:單次使用程序: 將原件Procedure複製到新的Procedure,標記為非活動,並使用覆蓋進行修改。然後Work引用新的Procedure. 這維護瞭Work.Procedure_id如何Work執行。

Example Schema
Work_id | Procedure_id
1       | 2

Procedure_id | Product_id| Active| Machine | Material | RunMinutes
1            | 1         | Y     | X       | Y        | 45
2            | 1         | N     | By-Hand | Z        | 45

選項 3:儲存為覆蓋:Work指向表的點Procedure和可選地指向ProcedureOverride表的點。對於 中的每個欄位Procedure,如果有覆蓋,則使用它,否則使用該Procedure值。

Example Schema 
Work_id| Procedure_id| Override_id
1      | 1           | 1

Procedure_id| Product_id| Machine | Material | RunMinutes
1           | 1         | X       | Y        | 45

Override_id             | Machine | Material | RunMinutes
1                       | By-Hand | Z        | NULL  

Query: ActualWork
Work_id   |Procedure_id | Machine | Material | RunMinutes
1         |             | By-Hand | Z        | 45  

例外 - 特殊測試:

對於非標準工作(如研發),沒有具體Procedure的 . 同樣,數據庫必須再次擷取Work實際執行的方式。

我看到兩個選項(相當於上面的各個選項)

**選項 1:本地儲存:**每個Work本地儲存使用的所有Procedure欄位。使用者必須為每個欄位輸入值。

**選項 2:單次使用程序:**創建一個新Procedure的,標記為非活動的,並由使用者填充。然後Work引用新的Procedure. 這維護瞭Work.Procedure_id如何Work執行。但是請記住,非標準
 
沒有實際(現實世界)。Procedure``Work

我假設對於給定的工作/程序對,您可能有多個異常,每個異常都可能修改一個或多個不同的過程欄位。

雖然您當然可以將每個修改儲存在自己的行中(“覆蓋”),但任何試圖獲取“目前”設置或歷史視圖的查詢都會變得複雜(特別是因為目前設計 - 如所示 - 沒有’似乎沒有任何方法可以顯示應用更改的順序)。

僅根據提供的資訊,我可能會選擇典型的歷史/審計解決方案:

  • 保持Work和Procedure之間的1-1關係
  • 當需要例外時,您使用新值更新過程
  • 程序上的觸發器會將舊記錄寫入審計/歷史表(例如,Procedure_hist),其中包含相同的列加上一個附加列來指定排序(例如,seq_no、modification_datetime 等)
  • 當您想查看目前的工作/程序配置時,您可以加入工作和程序,例如:
選擇 ...
從工作 w
加入程序 p
在 w.Procedure_id = p.Procedure_id
  • 如果您需要查看歷史/審計視圖,則可以拉入 Procedure_hist 表,可能作為外連接,例如:
選擇 ...
從工作 w
加入程序 p
在 w.Procedure_id = p.Procedure_id
剩下
加入Procedure_hist h
在 w.Procedure_id = h.Procedure_id

這與您的選項 #2 略有不同。是的,這意味著一些數據重複,但它也允許更輕鬆的編碼(更新、檢索),這反過來可能會使以後的維護變得更容易(特別是如果有人在你身後維護系統)。

$$ The K.I.S.S. principle comes to mind. $$


在不了解案例、上游/下游需求等的更多資訊的情況下……我可能想看看使用相同的 Work-Procedure-Procedure_hist 關係維護特殊測試是否有意義。

您可以添加一個標誌來指定工作(或程序?)是標準情況還是特殊情況。


可能影響模型的其他考慮因素……是 Work-Procedure 嚴格的一對一關係,或者可能存在多對一/多對多關係,例如:

  • 不同的工作努力可以(重新)使用一個程序嗎?
  • 可以將單個工作成果分解為多個程序嗎?

所以這在很大程度上似乎是一個關於正確數據規範化的問題。

考慮到數據標準化,我們可以很容易地排除選項 1。數據,就像你建議的那樣,顯然是非標準化和重複的。

選項 3 看起來更像是處理目前模式而不擷取您的域的黑客。如果您需要實施這樣的黑客攻擊,那麼絕對是重新設計的時候了。

這將我們帶到了選項 2。在三個選項中,這似乎是最好的。但是,該模式似乎能夠進一步進行適當的規範化。在不了解該領域的更多資訊的情況下,我會假設 Machine、Material 和 RunTime 之間可能存在某種功能依賴關係。或者它可能涉及產品 ID。當然,如果所有這 4 個值都可以自由改變而不影響其他值,那麼可以忽略此模式優化區域。

如果過程表中不存在功能依賴關係,那麼選項 2 中建議的模式與一個新的“非活動”過程來擷取自定義工作似乎是最佳的整體選擇

引用自:https://dba.stackexchange.com/questions/199077