2009-03-06 39 views
4

我正在研究PHP/MySQL評級系統。讓用戶能夠評估用戶必須登錄。每個用戶都有一個唯一的「UID」。在網站上會有多個評級實例(每個遊戲都有一個實例),我需要一種有效的方式將UID列表存儲在MySQL行中(每個評級系統實例的評級表中有一行MySQL行)保持已投票人的理貨。存儲用戶ID列表的最佳方法

我在其他系統中看到列表存儲在序列化的PHP數組中。每次用戶投票時,序列化數組必須提取,非序列化,插入新的UID,將數組重新序列化,並且MySQL行是UPDATEd。每次加載頁面時,該列表都必須再次被反序列化並檢查以查看瀏覽該頁面的用戶是否投票,以確保用戶不投票兩次。

這似乎是一種效率低下和繁瑣。 MySQL是否有內置列表功能來幫助這個過程更高效?有沒有更聰明的方法可以解決這個問題?

我考慮過一種可能的選擇,那就是忘記序列化並將UID存儲在MySQL數據庫的TEXT類型字段中。我會在每個UID後面添加一些非數字字符(比如說一個句點[。])。要添加用戶條目,我只需將UID連接到TEXT字段的末尾,然後是句點。當檢查用戶是否已經投票時,我可以只是「選擇*從表中WHERE votes ='%$ UID。%';」。這樣做會更有效率嗎?還是有更好的方法來完成工作?

後續行動後對錶結構... Efficient MySQL table structure for rating system

回答

17

效率低下。你在關係方面的含義是用戶和遊戲之間的多對多關係。用戶可以在許多遊戲上投票。遊戲可以被許多用戶投票。解決方案是有一個連接表:

USERS (uid, name, ...) 
GAMES (gid, name, ...) 
VOTES (id, uid, gid, ...) 

其中uid和gid是外鍵返回到它們各自的表。

如果有人投票,請在VOTES中插入記錄。

拿到票的列表遊戲:

$get = mysql_query("SELECT * FROM votes WHERE gid = $game_id"); 
... 

要獲得用戶的投票名單:

$get = mysql_query("SELECT * FROM votes WHERE uid = $user_id"); 
... 

等。

不要加入數組並將其存儲在單個列中。你是對的,以避免這種情況。

+0

看來你和Mehrdad提出了相同的方法。我這樣做。我唯一關心的是VOTES表的大小。可以想象,該表中可能有<#遊戲x#用戶>投票。這應該讓我的共享主機計劃管理員感到害怕嗎? – 2009-03-06 22:27:35

4

在規範化的數據庫,你應該把它保存在一個路口表:

UserRatings 
------------- 
RatingID int 
UserID int 
UserVote int 

我不知道是什麼您的查詢。取決於應用程序,這可能不具有可接受的性能。但是,無論哪種情況,我都建議你採用規範化的方法,基準,並在適當的時候進行非規範化處理。