2012-11-06 39 views
0

現在我有40多張表格供我的網站使用,我不認爲我在使用MySQL的時候完全正確。我正在製作一個類似於Moodle的網站。它基本上只對按課程分組的學生進行測試。學校網站的MySQL表格

Origonal表

courses - Lists all courses (ID, Name) 
c_$id - Lists all the Tests (ID, Name, etc) for course number $id 
a_$id - Lists all questions for the test number $id (Question, A, B, C, D) 
g_$id - Lists all grades for the course with course number $id. 
c_a  - Lists course ID and assignment ID pairs ex: (1,2) (1,3) (2,2) (2,3) 

表修訂1:

courses - Lists all courses (ID, Name, etc) 
tests  - Lists all tests (ID, Name, etc) 
questions - Lists all questions from all tests (ID, Ques, Ans) 
grades* - Lists all grades (studentID, courseID, testID, grade) 
students* - Lists all students and their courses (StudentID, courseID) 

的等級*表中,它基本上是3主鍵和值。有些事情似乎很奇怪。有沒有更好的辦法?學生桌同樣如此。兩者基本上都是其他表的連接。主鍵快速搜索是不可能的?

Origonal帖子:

什麼是重新創建這個利用的MySQL的力量最有效的方法是什麼?

從現在開始新課程開始時,它會爲該課程創建一個新表(c_$id),然後爲每個作業創建一個表格併爲該課程的一個等級列表g_$id。然後,在創建作業時,會創建一個新的a_$id表格,並將該過程和作業對添加到c_a

我已經從大多數select語句中刪除了「*」,並且在選擇主鍵時添加了「LIMIT 1」,接下來解決了這個OOP問題。

回答

2

在一般情況下,最好在可能的情況下堅持靜態方案(即固定的一組表和列)。因此,不要將連接編碼到表名中,而應使用單獨的列來引用其他表。例如,而不是單獨的c_$id持有每門課程的測試,你將有一個testscourse_id。輸入測試時,您需要填寫course_id值來表示該測試屬於哪個課程。檢索數據時,你可以只使用一套固定的表名的

SELECT … 
FROM courses, tests 
WHERE courses.id = tests.course_id 

一個好處是,你可以在你的PHP代碼中使用prepared statements,使用佔位符(通常?),而不是實際值。當您查詢execute時,您可以pass values,服務器將確保他們正確獲得escaped。這可以防止大多數SQL injection attack問題。此外,使用不同的值重複執行相同的準備好的語句可能會帶來性能上的提升,因爲查詢必須經過分析,分析和優化,但是隻能進行一次。

LIMIT 1添加到只能返回單行的查詢不可能產生任何性能增益:MySQL優化器知道主鍵,因此它也可以說明這一點。由於這些行可能使您的查詢稍微難以閱讀和維護,請考慮再次省略它們。

+0

你對靜態方案的權利,這將減少我創建的這個組織怪物,並允許索引做它做得最好,並提高我的查詢速度。謝謝! 上面的編輯就像你在暗示的一樣嗎? – CoderWalker

+0

@CoderWalker:這取決於你想要建模的東西。原始表格有與課程相關的測試。新模型作爲獨立實體進行測試。在後一種情況下,您可以對多個課程使用相同的測試。這是打算嗎?如果沒有,那麼測試表中的courseID將會很有用,正如我的示例所示。一般來說,您的編輯會提出一些新問題,這些問題在後續文章中可能會得到更好的處理。例如。你可以詢問如何創建跨越多列的主鍵(這是可能的)。具有多個外鍵的表格對於表達n:m關係是很常見的。 – MvG