Database-Design

插入時觸發訪問表

  • June 6, 2019

我正在使用 Access 2016 並為我的團隊建構一個內部 HR 應用程序。

我有一張Position 桌子,一張Employee桌子,一張Position_Employee桌子和一張Staffing桌子

Position Table
-------------
position_id autonumber
position_number
position_title
group_id FK
level_id FK

Employee Table
-------------
employee_id autonumber
last_name
first_name
dob

Position_Employee Table
------------- 
position_employee_id autonumber
start_date
end_date
is_indeterminate
is_current
position_id FK
employee_id FK



Staffing Table
-------------
staffing_id autonumber
reference_number
hr_confirmation
start_date
end_date
staffing_status_id FK
staffing_type_id FK
position_id FK
employee_id FK
hiring_manager_id FK

我的邏輯是基於職位,因為不止一名員工可以擔任同一個職位。

邏輯如下:

  • AnEmployee可以有一個不確定的職位

  • AnEmployee也可以有一個確定的職位,同時保持其不確定的職位

  • AnEmployee只能有一個確定的職位

  • APosition可以有一個不確定的 Employee

  • APosition也可以有一個確定的 Employee 而有一個不確定的員工

  • APosition也可以有一個確定的員工,而沒有不確定的員工(即空缺)

  • Staffing表是不同人員配備流程的位置,因此可以僱用員工並將其置於確定的、不確定的等位置。

有人告訴我不要使用標誌,因為以後在技術上維護它可能會成為一場噩夢,在我的桌子上Position_Employee,我不應該有is_indeterminateis_current

我想用虛擬碼做的是以下內容:

Trigger on Staffing table
If Insert in Staffing table
   If Staffing.staffing_status_id = 1  * staffing_stadus_id = 1 = Completed *
       Insert New position_employee_id in Position_Employee table
       position_employee.position_id = staffing.position_id
       position_employee.employee_id = staffing.employee_id
       position_employee.start_date = staffing.start_date
       position_employee.end_date = staffing.end_date
   If staffing_type = 1 *staffing_type = 1 = Indeterminate*
       position_employee.is_indeterminate = 'yes'
   If staffing_type <> 1
       position_employee.is_current = 'yes'

我希望以後能夠區分員工的不確定職位,以及員工之前擔任的所有職位,並能夠將員工的不確定職位和目前職位拉到相同但也可以不同的職位。

這個邏輯有意義嗎?如果是,我怎樣才能做到最好?

這種解釋並沒有為這個問題提供完整的答案,但它確實解決了提出一個好的解決方案時的關鍵考慮因素。所以這是一個答案,而不是一個完整的答案。

由於我是不鼓勵“旗幟”的人,因此我將進一步限定我之前的答案。我提到的錯誤標誌用於跟踪相關的數據庫行,否則這些行可以通過適當的規範化表和關係設計來處理。此類錯誤標誌不會告訴您有關要儲存的數據對象的狀態的任何資訊,而只是出於數據庫組織目的。布爾(是/否)標誌可能沒問題,甚至對於記錄您正在儲存的對象的現有有效狀態是必要的。這是確定標誌是否正常的第一個測試。

對於任何類型的標誌,下一個考慮因素是所選擇的數據庫模式是否允許儲存矛盾的狀態。你如何處理這種情況的答案可能很複雜,但是

  1. 您可能能夠更改/增加/重構數據庫模式以避免或消除矛盾的狀態,或者
  2. 準備編寫所有查詢和更新以考慮和處理此類可能的矛盾。如果現實世界的場景本身允許這種矛盾,有時這是必要的。例如,也許您將一名員工分配到兩個職位,認為他們可能可以處理 3 個職位,所以您留下is_indeterminate檢查,但在工作一周後,他們不堪重負,您意識到他們無法處理更多的工作,所以他們的is_indeterminate值未選中。在那種情況下,沒有任何一種自動化方式可以解決這種情況。

另一方面,如果該員工現在獲得了第三個職位,但is_indeterminate複選框沒有正確更新怎麼辦。現在系統有不准確的數據。這可以忍受嗎?工作場所是否會有人執行報告以定期審核和修復不良數據?您的更新常式是否會處理可能的不良數據,例如,員工不會因為說他們需要更多的工作而被少付?等等等等。

根據上面的 #1 建議,可能的更改是用位置計數器列替換基本的布爾標誌列。查詢可以簡單地指示該職位是否分配了正確的員工數量以及標記短缺或人員過剩……但是這次“標記”是在報告中動態確定的,而不是儲存在可能會過時的數據庫中。


關於虛擬碼……我們又開始使用像staffing_stadus_id = 1 == complete. 我承認,有時出於效率或簡單性的原因,這樣的標誌可能很有用……就像最後一張郵票,意思是“一切都完成了,不要再用那個位置打擾我了”。也許沒關係。但是,另一方面,只需將記錄添加到[Position_Employee]表應該足以確定該特定位置是否完整。換句話說,查詢查找所有相關記錄,如果有足夠的員工分配給該職位,則動態確定它是完整的……無需使用特定程式碼更新單獨的列,這些程式碼肯定會變得過時錯誤或人們沒有適當地更新狀態。如果架構/應用程序設計正確,則將職位標記為完成的唯一方法是將員工正確分配到正確的表中……不會意外更新狀態,但忘記實際添加被置於該職位的員工.

但是再一次,可能有必要有一個“狀態標誌”,例如,如果您想維護頭寸歷史,但可能一個頭寸尚未填補,但也被確定為過時。在這種情況下,您確實需要一個可用於將其標記為過時的標誌。

這可能看起來很微妙,甚至是矛盾的,但回到最初的 2 點,考慮為什麼要添加每個標誌,並考慮它是否可以以更自然的、關係數據庫式的方式實現。


另外,為什麼表和employee_idposition_id中都有 FK 列?再一次,這設置了兩個表之間可能不同/過時的可能矛盾的列。一旦為該職位選擇了一名員工,則只需將一條記錄添加到表中。為什麼將employee_id 添加到表中然後將其複製到?[Staffing]``[Position_Employee]``[Position_Employee]``[Staffing]``[Position_Employee]

employee_id如果在表中有其他合法的業務原因[Staffing],則架構需要單獨考慮該要求。例如,也許您想儲存一個潛在的員工以供手動批准,並且在獲得最終批准之前,他們不會進入該職位。那麼一個更好的關係數據庫模式將是另一個表,也許是一個[Staffing_potential]帶有staffing_id列和employee_id列的表。一旦它們被批准,然後從表中移動(複製/插入然後刪除的原子事務)。再一次,人員配備狀態隱含在行存在的表中,而不是與標誌列混淆。[Staffing_potential]``[Position_Employee]


更新

儘管試圖描述這些細節,但總是很難從問題和上下文中判斷每個特定細節的原因。現在很明顯,您的設計和需求已經足夠成熟,不僅可能有很多方法可以完成您的需求,而且對於“我如何才能做到最好?”確實沒有答案。沒有完整的迭代分析。這在這些論壇上是做不到的。事實上,我很久以前就開始使用 Stack Exchange,以前我會以“太寬泛”為由拒絕這個問題。但是最近對“友善和開放”的推動使我提供了更多冗長和具體的答案。我不會收回我發布的建議,但我會用……結束這個答案

特別是出於歷史或檔案的原因,可能確實需要儲存重複數據,甚至有補充的“標誌”欄位。只要有記錄的目的和原因,數據庫規範化規則就不一定是“破壞”的。我經常遇到財務數據,其中記錄不可更改的總交易金額以及組成行至關重要,即使總數可以從明細行中獲得。但關鍵是文件或列名或其他一些功能可以區分欄位的用途,不要被誤認為是非規範化數據。由開發人員來確保這些欄位的用途最終不會因為破壞穩定、規範化設計的原因而被使用。(供參考,

您有意識並意識到您的圖式的各個特徵的目的這一事實是至關重要的。對於處理不確定的就業案件,我沒有任何進一步的建議。

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