關於數據庫模型設計/性能的建議
我目前正在使用 Ruby on Rails 和 PostgreSQL(或 MySQL)建構一個“線上考試”類型的 Web 應用程序,一旦投入生產,它將成為更大應用程序的一部分。由於我最近剛剛進入 RD 設計領域,因此我很感激對以下設計的一些回饋。
應用規格
- 有1000多個不同的問題。每個問題可以有 2-5 個不同的選項,只有 1 個選項是正確的。
- 一次向使用者提出 10 個問題。
- 如果使用者正確回答了 2 次問題,則該問題將不會再次顯示給他(讓我們稱這些問題現在已完成)。
- 如果使用者錯誤地回答了一個問題,那麼他需要正確回答該問題 2 次以上。
- 當沒有更多問題要顯示時,使用者通過了考試。
我目前的數據庫架構是:
user -user_id -name etc question -question_id -text -correct_id (or option_id, stores the correct option id) option -option_id -text -question_id user_answer -user_id -question_id -is_correct
因此,為了創建“10 題測試”,我們可以:
- 創建查詢 user_answer 表的每個已完成問題的列表
- 創建一個可能的問題列表(所有問題 - 已完成的問題)
- 最後為使用者提供最後一個列表中的 10 個隨機問題。
是否有更好的方法來表示數據庫內的“需要回答問題的剩餘時間”?請隨意提出甚至完全不同的設計。
我擔心的是,對於每個單個使用者,會有超過 2x1000 個 user_answer 行。這很快就變成了一個巨大的數字,所以我想一定有更好的方法。
在這種情況下使用 json 數組可以嗎?但據我了解,添加更多問題等很快就會變得很麻煩。
當您在 DBA 站點時,我們很可能會為您提供數據庫解決方案 :-)
據我所知,你被困在你的兩個選項中——每個使用者回答的一行或一個大列表。就數據庫設計而言,最好的選擇是為每個使用者回答一行,並使列盡可能窄。
我對此的解決方案是將“user_answer”表中的欄位“is_correct”更改為“answer_status”並使其成為tinyint。如果使用者回答錯誤,則設置為 0。如果使用者回答正確,則增加 1。為了顯示未正確回答的問題,您將掃描“answer_status”< 2 的所有問題。現在該列將代表:
- 0 = 問題尚未回答或回答錯誤
- 1 = 問題回答正確一次
- 2 = 問題回答正確
當使用者開始他們的考試時,您將為該使用者的問題表中的每個問題輸入一個條目,預設 answer_status = 0。
如果您的“question_id”列和“user_id”列都是整數,則每行將儲存 9 個字節 - 這意味著如果您為該表使用 100MB,您將儲存約 1.19 億行。如果每個使用者有 10,000 行,您將儲存大約 12,000 個使用者的數據。您很可能希望將此表聚集在“user_id”上。
此外,您可以通過在“user_exam”表中設置標誌來清理“user_answer”表。您可能需要此表來將問題封裝到考試中並列出使用者註冊的考試。該表可以具有“狀態”欄位,當使用者通過考試時可以將其設置為“已完成”。隨後,“user_answer”表中的所有行都可以為該考試刪除,對於該使用者,一旦他們完成了所有答案(可能會獲得一些統計數據,如所用時間長度)。當重建表聚集索引時,這將回收數據庫中的空間。