2010-12-09 150 views
2

我創建一個系統來存儲用戶統計數據如下:MySQL的搜索查詢

 
Table Stats 
=========== 
id name 
----------- 
1  height 
2  weight 
3  eye_colour 
4  etc... 
 
Table Stat_Options 
================== 
id stat_id name 
1  1   170cm 
2  1   172cm 
3  1   174cm 
4  2   60kg 
5  2   65kg 

我存儲在用戶表中stat_options的ID如下:

 
Table User_Stats 
================ 
id user_id height weight eye_colour etc... 
--------------------------------------------------------- 
1  10   3   5   7 

存儲Id的原因是stat_option的'name'可以隨時更改,用戶記錄也不需要更改。

但看着這個我認爲它可能會出現問題,尤其是在搜索時。例如,如果我想搜索兩個特定高度之間的所有用戶?想到的一個解決方案是在Stat_Options表中插入一個'value'字段,但我仍然不確定這是否可行。有什麼建議麼?

+0

`SELECT ... FROM STAT_OPTIONS WHERE stat_id = 1 AND name BETWEEN x AND y` - 這有什麼困難?如果您需要根據名稱值獲取stat_id,則加入STATS表... – 2010-12-09 22:12:05

回答

1

這種類型的設計的問題是,你是混合您的Stat_Options表中的定性值(高度,重量)和定性值(eye_colour)。如果你絕對想要這樣做,請將定量和定性值分解爲2列。

Table Stat_Options 
================================== 
id stat_id name value unit 
=== ======= ===== ===== ===== 
    1  1 170cm 170  cm 
    2  1 172cm 172  cm 
    3  1 174cm 174  cm 
    4  2 60kg  60  kg 
    5  2 65kg  65  kg 
    6  3 black NULL black 

然後其他建議,JOIN表來獲取值BETWEEN x AND y

0

從你的榜樣,你可以得到x和y之間的高度的所有用戶通過查詢:

Select user_id from User_Stats where User_Status.height between x and y 
+0

除他/他似乎用包含的單位存儲高度外。我同意,這張桌子至少應該有一個價值,也許是一個單位領域。從那裏,爲了過濾而加入一個聯合是微不足道的。 – 2010-12-09 22:13:58

1

恕我直言,你應該使用一個查找表像你Stat_Options僅爲情況下,該屬性具有有限值的數量,如眼睛的顏色。嘗試使用類似這樣的表來表示(理論上)具有無限數量值(如高度和重量)的屬性,正如您已經猜到的那樣,會導致嚴重的頭痛。我會將這些值直接存儲在您的User_Stats表中。

+0

理想情況下,我想避免直接在我的用戶表中存儲值,我寧願只引用一個ID並從鏈接表中檢索該選擇的名稱。這樣,我可以隨時更新選擇的名稱,而無需使用新名稱更新所有用戶記錄。 – GSTAR 2010-12-09 22:25:52

+0

好的,但在你身高的例子中,你是否想要在'Stat_Options`中將名字從170cm修改爲190cm。你會突然改變每個分配了該ID的用戶的高度,這顯然不是你想要的。 – 2010-12-09 22:34:49

+0

這是真的,但我更關心的是,如果我決定在單位之間進行交換。根據網站的反饋,我可能會決定以英寸而不是CM存儲高度。所以我想有靈活性,我可以在不影響任何用戶數據的情況下交換單位.. – GSTAR 2010-12-09 22:54:36

0
SELECT user_id FROM User_Stats WHERE height BETWEEN 170 AND 172; 

我想那一個。

但對於你的表的結構,我可以建議如下:

  1. 沒有必要的統計數據表,因爲它可以包含在User_Stats表內沒問題。這樣你會更好地規範表的使用。

  2. 如果並且只有如果身高和體重的值可以大於你在那裏的3(例如180,183,192,200,110 ...)那麼我建議與第1點相同。刪除表幷包含在User_Stats表內,因爲此值可能會發生變化,因此不需要爲此創建新表。通過這種方式,您可以更快,更輕鬆地在單個表中比較所需的任何內容。

+0

不,因爲身高是一個外鍵..在這種情況下從來不是一個整數。 – bAN 2010-12-09 22:18:33

0

這不是一個好主意,做這樣的..使用Stat_option綁定下拉列表供爲例,如果你有一些從來不經常改變的值..

你爲什麼不只需在User-stats表中添加一個整數字段的高度?

但如果你真的想你可以這樣做:

SELECT * FROM USER_STATS 
INNER JOIN STAT_OPTION 
ON USER_STATS.height in (
SELECT ID FROM Stat_Options 
WHERE NAME BETWEEN 170 AND 175) 

或類似的東西,我不常用的MySQL ..