存储和显示最近访问过其他人页面的人的数据库效率最高的方法是什么?

时间:2013-03-10 00:23:49

标签: php mysql sql

我有一个博客程序(类似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,可以在插入新行时删除最早的重复行。这样,你就不会得到“数据膨胀”。

5 个答案:

答案 0 :(得分:3)

你的第二种方法是最好的。当我第一次开始在我的应用程序中实现数据库时,我尝试了第一种方当您想要扩展或更改有关如何处理数据集时,它会产生问题。

如果索引正确,您应该可以快速排序这些数据。

您仍想删除whovisit表中最旧的行。这将阻止您的50k条目。理论上,每个用户的whovisit表中只保留9条记录。所以你的实际表格大小是9 * Number_of_users

表一用户

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

表二谁访问

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

当您插入新访问的查询时,用户ID并获取行计数。如果罚款少于9,如果超过9,则删除最旧的一个,为用户留下总共9行。

答案 1 :(得分:2)

添加每次访问的日期/时间戳似乎会有所帮助。

如果你这样做,逻辑可能是这样的:

  • 用户已在列表中 - 使用当前日期/时间更新最早的时间/戳记
  • 用户尚未列入清单 - 找到最早的访问并使用此用户的信息更新记录

答案 2 :(得分: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表也可能有日期列或主键。仅存储两个整数将导致行大小非常​​小。

答案 3 :(得分:0)

您的想法被称为正常化,实际上是一个好主意。

用户

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

访问

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

现在您可以轻松快速地存储和检索访问数据。如果你把它放在一个字段中(就像在你的第一个例子中),你最终会陷入程序员的地狱。

您可以在表格访问中包含时间戳,并删除超过x天的条目。

答案 4 :(得分:0)

使用关系表...不建议在您的Users表中创建多个ID,原因显而易见......

例如:

Users

[UserID] [UserName]

Visits

[Source_User_ID] [Visitor_User_ID] [Visit_Count]

然后,您的SQL语句变得非常简单:

SELECT TOP 9 [Visitor_User_ID] WHERE [Source_User_ID]=### ORDER BY [Visit_Count] DESC