儲存使用的過程欄位
我正在為生產工作(特別是實驗室測試)創建一個數據庫。
大多數
Work
是用於生產,因此嚴格按照Procedure
for 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
?例外 - 覆蓋:
有時所需的設備或組件不可用。在這些情況下,經理可以批准一次性替代同等替代品。例子:
- 機器 X 壞了。手動執行
Work
。- 我們用完了材料 Y。改用材料 Z。
- 將執行時間保持在 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 中建議的模式與一個新的“非活動”過程來擷取自定義工作似乎是最佳的整體選擇