14

私はイントラネット アプリケーションとなるものを書いていますが、その機能の 1 つはコンテンツの投票にほぼ類似しています。SO、Amazon、および他の多くのサイトと同じです。

投票可能な各コンテンツに一意の ID があり、各ユーザー (認証されている) に一意の ID があると仮定すると、最も簡単な方法は「投票」テーブルを持つことです...

ContentID int
UserID int
VoteValue int

しかし、これは投票ごとに 1 つの行を作成します。何百万ものコンテンツと何万ものユーザーがいると、そのテーブルは非常に巨大になります。これが最善の方法ですか?つまり、int が 4 バイトの場合、各行は 12 バイトになります。100 万のコンテンツが 100 票を獲得した場合、ストレージは 400 MB 以上になりますよね? どうやら...たくさんのようです:)。VoteValue が tinyint (おそらくこれで問題ありません) で 1 バイトしかない場合でも、テーブルにはまだ数百メガバイトあります。私はおいおいを意味します。

よりスマートな方法はありますか?この「投票」テーブルを別のデータベースに保存して (潜在的なデータ整合性の問題を無視して)、ストレージとパフォーマンスの観点から「メイン」データから分割する必要がありますか?

(今日の世界では 400MB は大した量ではないことは理解していますが、投票を保存するだけでもかなりの量に思えますよね?)

4

5 に答える 5

11

そうですね、でも全体像を見る必要があります。100 万個のコンテンツで:

(コンテンツのサイズ) >> (投票のサイズ) : ここで、「>>」は「はるかに大きい」を意味します。

100 万個のコンテンツがある場合、それは 1 テラバイトのデータになる可能性があり、投票は 400 MB になります。大したことですよね?

また、スケーラビリティが心配な場合は、次のブログをチェックしてください。

http://highscalability.com/

于 2008-12-05T01:19:04.587 に答える
7

個人的には、適切なインデックスが配置されている限り、正しい方法で作業を進めています。使用状況によっては、パフォーマンスのために、二次カウント情報を保存して投票テーブルにヒットしないようにすることもできますが、全体として、誰が何かに投票したかを追跡する必要がある場合は、リストした方法でそれを行う必要があります。

別のデータベースに移動する必要はありません.SQL Serverに本当に関心がある場合は、それを保持するために別のファイルグループを作成できます....しかし、ほとんどの場合、必要ありません.

于 2008-12-05T01:15:27.700 に答える
4

ユーザーが特定のアイテムに投票したかどうかを追跡する必要があり、投票の値が異なる場合 (たとえば、星 1 つから星 5 つまで)、これは可能な限りコンパクトです。

適切なアクセス速度を得るには、データにインデックスを付ける必要があることを忘れないでください (おそらく 2 つのインデックス - 1 つは先頭の列として ContentID を使用し、もう 1 つは先頭の列として userID を使用)。

テーブルを他のテーブルとは別に保存しない理由があるかどうかを判断する必要があります。これが何を意味するかは、使用する DBMS によって異なります。Informix では、テーブルは同じデータベースにありますが、異なるDB 領域に格納され、インデックスが他の 2 つの異なる DB 領域に格納される場合があります。

于 2008-12-05T01:19:52.433 に答える
4

投票の乱用を簡単に検出できるように、テーブル内のコンテンツの作成者の ID も必要になるでしょう。(はい、これはおそらく冗長な情報です。別の方法として、定期的に要約テーブルを作成して、誰が誰に投票しているかを確認します。)

価値のあるものとして、perlmonks の投票テーブルは次のようになります。

 `vote_id` int(11) NOT NULL default '0',
 `voter_user` int(11) NOT NULL default '0',
 `voted_user` int(11) default NULL,
 `weight` int(11) NOT NULL default '0',
 `votetime` datetime NOT NULL default '0000-00-00 00:00:00',
 `ip` varchar(16) default NULL,
 PRIMARY KEY  (`vote_id`,`voter_user`),
 KEY `voter_user_idx` (`voter_user`,`votetime`),
 KEY `voted_user_idx` (`voted_user`,`votetime`)

(vote_id はコンテンツ ID、ip は IP アドレスです。)

于 2008-12-05T03:25:46.767 に答える
0

これらの投票がどのように使用されるかを理解し、最初にデータ モデルに固有のクエリを設計する必要があると思います。これは必ずしも SQL モデルではありません。SQL の世界から来ている場合は、公式の MongoDB チュートリアルを通過することで、最初に頭をすっきりさせることができます。

たとえば、単一の問題ページの投票のみを保存および表示する必要がある場合は、投票を問題の単一の文字列フィールドに保存すると便利な場合があります。これは次のようになりますid1:id2:id3:。すべての ID が同じ長さであると仮定すると、興味深いプロパティがいくつかあります。

  1. 問題に対するすべての投票を数えます。

    len(issue.votes)/len(id)

  2. 問題に投票したことを確認

    myid in issue.votes

  3. 投票したすべての問題を検索:

    select issue.id from issues where issue.votes contains(myid)

  4. 最も投票された課題を見つける

    select issue.id from issues order by len(issue.votes) desc limit 10

このアーキテクチャにより、これらの特定のケースでの読み取り時のコストのかかる計算を回避できますがissue.votes、投票時の更新は、テーブルに行を追加するよりもコストがかかる可能性があります。この場合、ID ごとに 4 バイト + セパレーターを含む 100 票は 500 バイトの文字列です。提案されたバリアントでは、100 票は 800 バイトです。

免責事項: 私はこのようなものを実装したことはありません。これは単なるアイデアです。

于 2013-06-26T08:41:18.270 に答える