將表轉換為 2NF 關係
我目前正在學習數據庫規範化並嘗試創建我的第一個關係數據庫。在我遇到以下問題之前一切順利。
在非規範化形式中,我的
justifications
表會像這樣:| justification_id | user_id | question | response | action | category | category_id | submitted_at | -----------------------------------------------------------------------------------------------------
我的研究和思考過程使我得出以下結論:
justification_category
| justification_id | category | category_id |
justification_response
| justification_id | question | response |
justification_action
| justification_id | user_id | action | submitted_at |
正當理由如何運作?
當使用者對某個類別(目前類別為工單、訂單、帳戶)執行操作時,使用者需要說明他們執行該操作的原因。即賬戶刪除
一個操作可以附加多個問題,從而導致多個響應。例如:刪除帳戶會詢問以下問題:您是否遵循了我們的內部步驟?為什麼需要執行此操作?等等。這就是我提出該
justification_response
表的原因,因為它不會儲存任何 NULL 欄位。justification_action 表將記錄執行的操作、user_id(這是操作的送出者)和操作的時間。
問題
我目前有 3 個潛在類別,其中需要對某項操作進行說明,它們是工單、訂單和帳戶。考慮到這一點,使用 3 個單獨的表格來描述每個類別會更好嗎?這種方法會滿足 2NF 嗎?
我覺得我離 2NF 關係還很遠。這是因為我經常將其重新
justification_id
用作 FK 或 PK。我離我有多遠?
感謝您嘗試正確處理並理解原則。我已經這樣做了多年,但有時仍然很難用精確準確的關係理論術語來標記現有結構。
需要注意的是,範式僅描述單個關係(即 SQL 中的“表”),而不是它們之間的關係……因此justification_id的頻繁出現在任何意義上都不會使您的表進一步遠離2NF。事實上,這些都是關於理由的屬性表,所以只有合理的理由才會出現。
justification_id 似乎是每個表中的候選鍵,或者至少是主要屬性……不是嗎?根據定義,候選鍵幾乎不會產生非規範化效果。這是必須分析的其他屬性。
我對類別和類別 ID 感到困惑。“類別”會是(例如)“票”和“category_id”是(例如)“27”……?如果是這樣,您的命名有點違反直覺,並且您正在朝著規範化並沒有真正解決的方向前進,但這可能會在以後給您帶來困難——您將數據域混合在一個屬性中(列)。
我的意思是:“category_id”的值可能是“ticket”表中的 id 或“order”表中的 id 等,具體取決於類別的類型。如果我對這些列的用途是正確的,那麼您不想這樣做,因為(除其他原因外)數據庫不可能正確地對該列施加外鍵約束。根據經驗,一列中的值應該意味著完全相同的東西,而不管其他列中包含什麼。如果有聯結表,“ticket_has_justification”(帶有ticket_id和justification_id),“order_has_justification”(order_id,justification_id)等可能更正確。您仍然可以將所有理由外部連接到他們證明的各種類型的事物,
“questions”列在“question”表中也可能更合適, justification_response 有一個 question_id 列引用它,但是在這裡,規範化並沒有真正解決這個問題——無論它是否作為單詞儲存在這個表中問題,或作為單詞 (question_id) 的替代名詞,“問題”列仍然是一個主要屬性,其中 (justification_id, question) 是候選鍵,響應取決於兩者,所以這個至少是 3NF,儘管在我看來有改進的餘地。
不過,從根本上說,我看不出這些不是2NF ……這取決於“category”和“category_id”的確切含義。