2

私はブログプログラム(Twitterのようなもの)を持っています、そして私は現在あなたのページを最近訪問した9人を含む最近訪問されたボックスを作っています。

全員が異なるユーザー名で登録されています。

私が現在持っているのは、次のようなデータベースです。

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

たとえば、9人のユーザーがのページにアクセスfoo1した場合、データベースには次の行が入力されます。foo9foo10

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

そして、のページにfoo11アクセスすると、文字列の最後からfoo10削除して、先頭foo9に追加します。foo11

しかし、現在の主な問題は、のページにアクセスし、次にページにアクセスし、次にページに再度アクセスした場合はどうなるfoo1でしょうか。次に、9人のユーザーを検索し、重複を削除し、これを前に配置して、実行を続行する必要があります。しかし、問題は、8行しか表示されないことです。foo10foo2foo10foo1foo10

私が考えることができたこの問題の唯一の解決策は、次のようなデータベースを作成することでした。

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

そして、それらを1行に入力する代わりに、訪問ごとに新しい行を追加します。

-----------------------------
| 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   |
-----------------------------

しかし、これには大量の不要なスペースが必要になります。

データベース内の1人のユーザーに50000を超える行を追加することなく、この問題を効率的に解決できる、見逃した方法はありますか?

更新:同じ問題を抱えている人のために、PM 77-1がコメントで以下に述べているように、新しい行が挿入されたときに最も古い重複行を削除することができます。このように、「data-bloat」を取得することはありません。

4

5 に答える 5

2

2番目の方法が最適です。私が最初にアプリにデータベースを実装し始めたとき、私はあなたの最初の方法を試しました。そのデータセットの処理方法に関して物事を拡張または変更したい場合、問題が発生します。

適切にインデックスが作成されていれば、このデータをすばやく並べ替えることができます。

それでも、whovisitテーブルから最も古い行を削除する必要があります。これにより、5万件のエントリが防止されます。理論的には、各ユーザーのwhovisitテーブルに保持するレコードは9つだけです。したがって、実際のテーブルサイズは9*Number_of_usersになります。

テーブル1ユーザー

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

表2whovisit

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

新しくアクセスしたクエリを挿入すると、ユーザーIDと行数が取得されます。罰金が9未満の場合、9を超える場合は、最も古いものを削除して、ユーザーに合計9行を残します。

于 2013-03-10T00:27:22.187 に答える
2

各訪問の日付/タイムスタンプを追加すると役立つようです。

その場合、ロジックは次のようになります。

  • すでにリストにあるユーザー-最も早い時間/スタンプを現在の日付/時刻で更新します
  • ユーザーはまだリストに含まれていません-全体的に最も早い訪問を見つけて、このユーザーの情報でレコードを更新します
于 2013-03-10T00:35:18.570 に答える
0

2つのテーブルを使用することをお勧めします。

テーブル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テーブルに日付列または主キーが含まれる場合もあります。2つの整数だけを格納すると、行サイズが非常に小さくなります。

于 2013-03-10T00:33:31.863 に答える
0

あなたのアイデアは正規化と呼ばれ、実際には良いアイデアです。

テーブルユーザー

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

テーブル訪問

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

これで、訪問データを簡単かつ迅速に保存および取得できます。これを1つのフィールドに入れると(最初の例のように)、プログラマーの地獄に行き着きます。

テーブル訪問にタイムスタンプを含めて、x日より古いエントリを削除することができます。

于 2013-03-10T00:35:48.423 に答える
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
于 2013-03-10T00:36:09.040 に答える