1

そのようなクラスがたくさんあります(数百万)

class WordInfo
{
     string Value;
     string SomeOtherFeatures;
     List<Point> Points;
}

そして次のコード

 private Dictionary<string, WordInfo> _dict;

   public void ProcessData(IEnumerable<Tuple<string,int,int> words)
   {
        foreach(var word in words)
        {
             if(_dict.ContainsKey(word.Item1))
             {
                 _dict[word.Item1].Points.Add(new Point(word.Item2,word.Item3));
             }
             else
             {
                 _dict.Add(word.Item1, new WordInfo(....))
             }
        } 
   }


   Main()
   {
       while(true)
       {
           IEnumerable<Tuple<string,int,int> data = GetDataSomewhere();
           ProcessData(data); 
       }
   }

ご覧のとおり、このコードは 24 時間年中無休で機能する必要があります。主な問題は、データベースで _dict (情報を保存する場所) を表す方法がわからないことです。毎秒 1000 ~ 5000 ワードを処理する必要があります。リレーショナル データベースは私の仕事には適していませんよね? NoSQLはどうですか?高速な UPDATE および INSERT 操作が必要です。また、データベースに存在する単語(SELECT)をすばやく確認する必要があります。私は何百万ものレコードを持っているので、それも簡単ではありません。何を提案できますか?ファイルに基づいてカスタム ソリューションを作成できますか?

4

1 に答える 1

2

リレーショナルデータベースは、あまり多くのトランザクションを作成しないことを前提として、1秒あたり1000〜5000語を簡単に挿入/更新できる必要があります。

トランザクションはACIDであり、「D」は永続性を意味します。クライアントがトランザクションがコミットされたという通知を受信すると、トランザクションの効果がすでに永続ストレージにあることが保証されます(したがって、その瞬間に停電が発生した場合でも、トランザクションは「消去」されません)。実際には、これは、DBMSがディスクが物理的な書き込みを完了するのを待つ必要があることを意味します。

すべての挿入/更新を独自のトランザクションでラップする場合は、それらのすべてに対してこの待機を実行する必要もあります。OTOH、 1回のトランザクションで多数の挿入/更新をラップする場合、この価格を支払う必要があるのは、「チャンク」全体につき1回だけです。


また、 B-Treeインデックスの力のおかげで、他の何百万もの行の中に特定の行が存在するかどうかをチェックすることは、データベースが非常に得意なタスクです。


データベース構造に関しては、次のようなものが必要になります。

ここに画像の説明を入力してください

そして、あなたはそれをこのように処理するでしょう(擬似コード):

BEGIN TRANSACTION;

foreach(var word in words)
{
     try {
         INSERT INTO WORD (WORD_VALUE, SOME_OTHER_FEATURES) VALUES (word.Item1, ...);
     }
     catch (PK violation) {
         // Ignore it.
     }

     try {
         INSERT INTO POINT (WORD_VALUE, X, Y) VALUES (word.Item1, word.Item2, word.Item3);
     }
     catch (PK violation) {
         // Ignore it.
     }
} 

COMMIT;

(注:SOME_OTHER_FEATURES最初に挿入された後は更新しないと想定しています。更新すると、上記のロジックはより複雑になります。)

DBMSがそれをサポートしている場合は、これらのテーブルの両方をクラスター化することを検討してください(別名、インデックス編成)。また、DBMSがサポートしている場合は、同じ単語に関連するすべてのポイントに同じ値が含まれているため、POINTのプライマリインデックス(WORD_VALUE)のリーディングエッジを圧縮します。


ところで、上記のモデルは、いわゆる識別関係と自然キーを使用しています。代理キーと非識別関係を使用する代替モデルも可能ですが、必要な処理の種類が複雑になります。

于 2012-06-26T09:48:24.743 に答える