2012-01-17 14 views
1

我需要保留一個列表user_id s已經查看了一段內容來計算唯一的用戶視圖。 user_idINT(10)字段。高效地存儲一堆外鍵(序列化與新表)

我可以用user_id,content_idviewed創建一個表格,並在用戶每次查看內容時添加一行,但這看起來很慢。對於每一塊內容的用戶的意見,我會查詢類似

SELECT COUNT(*) FROM viewed_table WHERE content_id = $content_id;

得到的意見的金額,然後

SELECT COUNT(*) FROM viewed_table WHERE user_id = $user_id AND content_id = $content_id;

,看是否用戶已經查看過這個內容,如果沒有,則插入一行。 (每次用戶查看某個內容時2或3個額外的查詢)。

OR ...

如果我一個viewed字段添加到我的內容表和數組每次我添加了一個user_idunserialize()/serialize()json_encode()是另一個類似的選項,在大型數據集上似乎更快。

哪個選項對於正在發展的網站來說是最快/最具擴展性的?謝謝你的幫助!

回答

2

規則的拇指:序列化關係數據一般來說,外鍵尤其是==公路到地獄。

有一個表格,您可以存儲所有視圖的總和,而只增加/減少它。這應該快於SELECT COUNT(*) FROM viewed_table WHERE content_id = $content_id;

要查看給定用戶是否已查看給定頁SELECT 1 FROM viewed_table WHERE user_id = $user_id AND content_id = $content_id LIMIT 1;。這將返回0或1行,所以你只需要檢查。

0

毫無疑問,第一個選項。

每當您要計算視圖數量或每當有人讀取文章時,序列化/反序列化id列表的成本將比編制良好索引的第二張表上的COUNTing慢幾個數量級。

您可以通過將計數存儲在內存中(類似於Memcached或Redis),或者通過向內容表添加view_count列,並在添加到viewed_table時增加該數字來進一步改進。

1

你可以這樣做:

viewed_table 
---------------------------- 
user_id int(10) 
content_id int(10) 
primary key (user_id, content_id) 

插入一條記錄:

INSERT IGNORE INTO viewed_table (user_id, content_id) VALUES ($user_id, $content_id) 

你affected_rows數會顯示這是一個新行(用戶尚未查看的內容)。沒有選擇需要那個。

如果您希望實施總計表格,那麼這也是您要爲選定的content_id添加總計的點。

viewed_table_totals 
---------------------------- 
content_id int(10) 
view_count int(10) 
primary key (content_id) 

更新該行:

INSERT INTO viewed_table_totals (content_id, view_count) VALUES($content_id, 1) 
    ON DUPLICATE KEY UPDATE view_count = view_count + 1 

既然你想獨特的訪問,你不能避免存儲每個用戶的訪問。