2011-07-26 28 views
1

我是使用mysql的初學者,我正在嘗試學習最佳實踐。我已經建立了如下所示的類似結構。這是很好的數據庫標準化嗎?

表= 'main_content'

+------------+---------------+------------------------------+-----------+ 
| content_id | (deleted) | title      | member_id | 
+------------+---------------+------------------------------+-----------+ 
|   6 |    | This is a very spe?cal t|_st |  1 | 
+------------+---------------+------------------------------+-----------+ 

(包含所有唯一條目主表)(提供總每個難度和連接ID - >實際名稱)表= '困難'

+---------------+-------------------+------------------+ 
| difficulty_id | difficulty_name | difficulty_total | 
+---------------+-------------------+------------------+ 
|    1 | Absolute Beginner |    1 | 
|    2 | Beginner   |    1 | 
|    3 | Intermediate  |    0 | 
|    4 | Advanced   |    0 | 
|    5 | Expert   |    0 | 
+---------------+-------------------+------------------+ 

(此表可確保多個值可以插入針對每個條目。例如, 此特定條目指示有2 d與提交相關ifficulties) 表=「lookup_difficulty」

+------------+---------------+ 
| content_id | difficulty_id | 
+------------+---------------+ 
|   6 |    1 | 
|   6 |    2 | 
+------------+---------------+ 

我加入這一切變成可讀查詢:

SELECT group_concat(difficulty.difficulty_name) as difficulty, member.member_name 
FROM main_content 
INNER JOIN difficulty ON difficulty.difficulty_id 
IN (SELECT difficulty_id FROM main_content, lookup_difficulty WHERE lookup_difficulty.content_id = main_content.content_id) 
INNER JOIN member ON member.member_id = main_content.member_id 

以上工作正常,但我想知道,如果這是很好的做法。我實際上遵循了編排的結構Wikipedia's Database Normalization example

當我使用EXPLAIN運行上述查詢時,它說:'使用where;使用加入緩衝區',並且我正在使用2個依賴子查詢。我沒有看到任何方式不使用子查詢來實現相同的影響,但是再次我是一個noob,所以也許有更好的方法....

+1

爲什麼'main_contant'有FK到困難和查找表?你能解釋一下你正在試圖構建什麼,所以我們可以評估你的設計? – Jacob

+0

在我看來,你可以廢棄lookup_difficulty表,而只是在main_content上使用複合PK on(content_id,difficulty_id) –

+0

對不起,我的意思是刪除該列。我沒有使用difficulty_id ..我將編輯帖子。我試圖將所有表基本上與main_content.content_id關聯。 – Justin

回答

1

如果lookup_difficulty提供了content之間的鏈接和difficulty我建議你從main_content表中取出difficulty_id列。由於您可以對每個content_id進行多次查找,因此需要一些額外的業務邏輯來確定將哪個difficulty_id放入您的main_content表(或main_content表中的多個條目,對於每個difficulty_id,但這不符合規範化實踐)。例如。最大值/最小值/隨機值。無論如何,這沒有多大意義。

除此之外,表看起來不錯。


更新

看到你更新的表:)

正如一個側面說明。使用IN會減慢查詢速度(IN可能導致表掃描)。無論如何,它過去就是這樣,但我確信現在SQL編譯器對它進行了很好的優化。 -

+0

感謝您的幫助!作爲一個便箋,我可以在哪裏找到mysql使用的典型速度?換句話說,你是如何發現「IN」很慢?如果我用'= ANY'替換'IN',我可以達到相同的結果。我不知道哪個更快,「EXPLAIN」不能提供更多的信息。 – Justin

+0

@Justin - 主要來自經驗和閱讀。有專有的軟件可以分析你的MySQL查詢,而不是我知道的任何好的開源/免費軟件(任何人都可以隨意舉例)。 –

+0

我想我總是可以使用探查器。我將使用大量聯接來檢索每個提交的內容,因此我最好確保它在某種程度上進行了優化。 – Justin

2

的DB設計看起來不錯關於您的查詢,您可以用加入像完全重寫一遍:

SELECT group_concat(difficulty.difficulty_name) as difficulty, member.member_name 
     FROM main_content 
     INNER JOIN lookup_difficulty ON main_content.id = lookup_difficulty.content_id 
     INNER JOIN difficulty ON difficulty.id = lookup_difficulty.difficulty_id 
     INNER JOIN member ON member.member_id = main_content.member_id 
+0

優秀! 'ON難度。困難_id'代替'ON困難.id'時正常工作。謝謝!!在使用'EXPLAIN'之後,所有'SELECT_TYPES'都是'SIMPLE'並且沒有子查詢。這正是我所期待的! – Justin

+0

不客氣,我很高興我能幫上忙 –