2013-03-10 74 views
3

我有一個博客程序(類似Twitter),我目前正在製作一個最近訪問的框,其中包含最近訪問過您的頁面的9個人。什麼是存儲和顯示最近訪問他人頁面的人最有效的數據庫方式?

每個人都使用不同的用戶名註冊。

什麼我目前得到的是這樣的數據庫:

----------------------------- 
| id | username | who_visit | 
----------------------------- 

例如,如果9個用戶foo1foo9訪問foo10的頁面,該數據庫將與行填充

------------------------------------------------------------------------ 
| id | username |      who_visit      | 
------------------------------------------------------------------------ 
| 1 | foo10 | foo1, foo2, foo3, foo4, foo5, foo6, foo7, foo8, foo9 | 
------------------------------------------------------------------------ 

然後當foo11訪問foo10的頁面,我會從字符串的結尾去掉foo9,並添加foo11前面。

但現在的主要問題是,如果foo1訪問foo10的頁面,然後foo2參觀foo10的頁面,然後foo1再次訪問foo10的頁面?然後,我將不得不搜索9個用戶,刪除任何重複項,將其放在前面,然後繼續執行。但問題是,那麼它只會顯示8行。

唯一的解決這個問題,我能想到的是使數據庫這樣的:

----------------------------- 
| id | username | who_visit | 
----------------------------- 

而不是在一排填充它們,我想補充一個新的行爲每一位光臨:

----------------------------- 
| id | username | who_visit | 
----------------------------- 
| 1 | foo10 | foo1 | 
----------------------------- 
| 2 | foo10 | foo2 | 
----------------------------- 
| 3 | foo10 | foo3 | 
----------------------------- 
| 4 | foo10 | foo4 | 
----------------------------- 
| 5 | foo10 | foo5 | 
----------------------------- 
| 6 | foo10 | foo6 | 
----------------------------- 
| 7 | foo10 | foo7 | 
----------------------------- 
| 8 | foo10 | foo8 | 
----------------------------- 
| 9 | foo10 | foo9 | 
----------------------------- 

但是這樣會佔用大量不必要的空間。

有沒有一種方法我錯過了,它可以有效地解決這個問題,而不需要爲數據庫中的一個用戶添加> 50000行?

更新:對於那些具有相同問題的人,如下面在註釋中所述的PM 77-1,可以在插入新行時刪除最早的重複行。這樣,你不會得到'數據膨脹'。

+1

如何分割的邏輯:如果訪問者已經在列表上,則代替他/她最早 – 2013-03-10 00:29:51

+0

@ PM77-1哎,爲什麼我沒有想到這一點。 – think123 2013-03-10 00:30:44

+0

我將它擴展爲答案。 – 2013-03-10 00:37:08

回答

3

你的第二種方法是最好的。當我第一次開始在我的應用程序中實現數據庫時,我嘗試了第一種方法當你想擴展或改變這些數據集的處理方式時,會產生問題。

如果索引正確,您應該沒有問題通過快速排序這些數據。

您仍想從whovisit表中刪除最舊的行。這會阻止你的5萬個條目。理論上,每個用戶的whovisit表中只保留9條記錄。因此您的實際表的大小將是9 * NUMBER_OF_USERS

表中的一個用戶

id | username 
-----|----------- 
1 | foo1 
2 | foo2 

表中的兩個whovisit

id | user(id) | visited(userId) | Date/time stamp 
-----|-----------------------------|---------------- 
1 | 1  | 2    | 9999-12-31 23:59:59 

當您插入新的被訪問查詢的用戶ID,並得到一個行數。如果少於9個,則罰款(如果超過9個),則刪除最長的一個,爲用戶留下共9行。

0

我會建議使用兩個表:

users

id | name 
1 | foo1 
2 | foo2 
3 | foo3 
4 | foo4 
    ... 
10 | foo10 

visits

host_userid | visitor_userid 
    10  |  1 
    10  |  2 
    10  |  3 
    10  |  4 

visits表還可能有一個日期列或者一個主鍵,如果需要的話。僅存儲兩個整數將導致非常小的行大小。

+0

但仍有許多行使用。 – think123 2013-03-10 00:33:56

+0

@ think123:是的,但所需的存儲空間量並不直接取決於行數,而是取決於'number_of_rows * row_size'。在你的第一個例子中,你有更少的行,但行大小更大。 – Hazzit 2013-03-10 00:36:05

2

看來這將有助於添加每次訪問的日期/時間戳。

如果你這樣做,邏輯可能是這樣的:

  • 用戶已經在名單上 - 更新與當前日期最早的時間/時間戳/時間
  • 用戶還沒有在名單上 - 找到總體最早的訪問,並與該用戶的信息更新記錄
+0

我同意。謝謝! – think123 2013-03-10 00:57:25

+0

使用時間戳+1 – 2013-03-10 01:39:09

0

你的想法被稱爲正常化,實際上是一個好主意。

用戶

----------------- 
| id | name  | 
----------------- 
| 1 | foo1  | 
----------------- 
| 2 | foo2  | 
----------------- 
| 3 | foo3  | 
----------------- 

訪問

----------------------------- 
| id | user_id | visit_id | 
----------------------------- 
| 1 | 1  | 2  | 
----------------------------- 
| 2 | 2  | 3  | 
----------------------------- 

現在你可以輕鬆快速地存儲和檢索的訪問數據。如果你把它放在一個字段中(就像你的第一個例子),你最終會陷入程序員的地獄。

您可以在表訪問中包含時間戳並刪除x天以前的條目。

0

改爲使用關係表...在用戶表中創建多個ID不建議出於顯而易見的原因...

例如:

Users

[UserID] [UserName]

Visits

[Source_User_ID] [Visitor_User_ID] [Visit_Count]

然後你的SQL語句BEC青梅多用簡單:

SELECT TOP 9 [Visitor_User_ID] WHERE [Source_User_ID]=### ORDER BY [Visit_Count] DESC 
相關問題