4

ソーシャル ネットワーク サイトの場合、各エンティティ (およびそのような数百万のエンティティ) の頻繁に変更されるリストを保存する必要があります。

  • 頻繁に追加される
  • よく読む
  • 時々減る
  • リストは主キーによってキー付けされます

私はすでに他の種類のデータを RDBMS に格納しています。これらのリストを、次のように多対多の関係として RDBMS に格納できることを私は知っています: Create a table listItemswith two column listId& listItem& to generate any specific list, just do a SELECTquery for all records WHERE listId = x. しかし、高いスケーラビリティが懸念される場合、この方法でリストを RDBMS に格納することはあまり理想的ではありません。代わりに、検索パフォーマンスが最大になるように、準備されたリストを自然な方法で保存したいと考えています。ユーザーがログインしてページを表示するたびに、ユーザーのためにそのようなリストを約100件取得する必要があるためです。

では、どうすればこれを解決できますか? このデータにはどのような種類のデータベースを使用する必要がありますか?おそらく、Cassandra のような、主キーによってキー付けされた列の変数を追加できるデータベースですか?

4

7 に答える 7

5

私は同じ方法を使用しました。つまり、すべてのレコードに 2 列の行を格納し、それを書式設定された html を含む txt ファイルに変換し、それを json に変更し、最後に mongodb に変更しました。

ただし、頻繁に操作する場合は、cassandra、hbase、および accumulo cloudata や hypertable などの googles ビッグ テーブルの実装をお勧めします。

Cloudata はあなたにぴったりかもしれません。

于 2013-08-27T05:56:59.287 に答える
3

あなたが指摘したように、ソリューションはパフォーマンスが高く、スケーラブルでなければなりません: LIST データ構造と O(1) 挿入および O(N) フェッチ (N - フェッチする要素、最後にフェッチしていることを考慮して) で Redis を使用することをお勧めしますリストからのもの)、ハッシュアルゴリズムで水平方向にスケーリングします。保存するデータの量と使用可能なマシンの数はわかりませんが、メモリ アクセス速度に勝るものはないため、パフォーマンスに関しては間違いなく最良の選択です。

データの量が膨大で、すべてを RAM に保持できない場合は、Cassandra がその役割を果たします。前述の Zanson のようにパーティション戦略を使用すると、時間順にリストを保存するのに適しています。

もう1つの考え:読み取りパフォーマンスは最大でなければならないと言いました。ユーザーがログインすると、このユーザーの何百ものリストを取得する必要があります。ユーザーごとに 1 つのリストを用意してみませんか? そうすれば、より多くの書き込みが発生しますが、1 つのリストから最新のエントリのみを取得する必要があるため、読み取りは最適化されます。それがあなたの仕事に合っているかどうかはわかりませんが、ただの考えです。:)

于 2013-09-02T11:14:02.933 に答える
2

Cassandra は、セット/マップ/リストの保存をネイティブでサポートしています。クエリが常にすべてを引き下げる場合は、この種のことを処理する非常に簡単な方法です。

http://www.datastax.com/dev/blog/cql3_collections http://cassandra.apache.org/doc/cql3/CQL.html#collections

リストがユーザーに関連付けられている場合、ユーザーの行/パーティションに異なる列を作成すると、複数のリストのクエリが高速になります。これは、それらがすべて特定のユーザーの同じパーティションにあるためです。

于 2013-08-27T16:21:15.893 に答える
2

Google leveldb ネットワーク ラッパーであるSSDB ( https://github.com/ideawu/ssdb ) をお勧めします。SSDB は、リスト、マップ、zset (ソート済みセット) などのコレクション データを格納するように設計されています。次のように使用できます。

ssdb->hset(listId, listItem1);
ssdb->hset(listId, listItem2);
ssdb->hset(listId, listItem3);
...
list = ssdb->hscan(listId, 100);
// now list = [listItem1, listItem2, listItem3, ...]

1 つのマップ内のアイテムの数は、ハードディスクのサイズにのみ制限されます。もう 1 つの解決策は Redis ですが、Redis はすべてのデータをメモリ (たとえば 30GB 以下) に格納するため、おそらくプロジェクトに適合しません。

C++、PHP、Python、Java、Lua、およびその他のクライアントが SSDB でサポートされています。

于 2013-08-27T16:10:05.277 に答える
1

Cassandra は、このようなユース ケースに非常に適しています。返されたデータ セット/クエリに必要な数の列ファミリを作成します。Cassandra は、正規化されていないデータまたは 1:m、m:m 関係などのセットで最適に機能します。

于 2013-08-29T11:25:51.400 に答える
1

リレーショナル データベースを検討したくないことは承知していますが、この単純な状況には、リレーショナル データベースを使用したスケーラブルなソリューションもあると思います。主な利点は、別のデータベース システムを維持する必要がないことです。

スケーラビリティを得るために、すべての NoSQL ソリューションはデータを複数のノードに分散します。これをアプリケーション コードで実行して、データを複数のリレーショナル データベースに分散させることができます。負荷のバランスを維持するために、時々データを移動する必要があるかもしれませんが、N 個のリストごとに新しいデータベースを作成するだけで十分な場合があります。

于 2013-09-02T22:27:54.273 に答える
0

cassandra では、行ごとに最大 20 億列までの幅の広い行を持つことができます...エンティティの累積リストの項目に十分な場合は、エンティティのリスト全体を 1 つの行に格納してから、すべてをまとめて取得できます。Cassandraの「複合列」を使用すると、各リストの要素を順番に並べて保存でき、必要に応じて単一の列(リスト項目)を削除できます。挿入がある場合は、列を挿入するだけです...

このようなもの: (!)

      |list_1_Id : item1Id |list_1_Id : item2Id | list_2_Id : item1Id |...| list_n_Id : item3Id |
entity|     item1Value     |     item2Value     |     item1Value      |...|     item3Value      |

したがって、実際には、リストではなく列 (= 項目) を処理します...そして、作業がはるかに簡単になります。エンティティの行を複数の行に分割することを使用して、リストのサイズに依存します...次のようなもの: (!)

                 |  item1Id   |  item2Id   |  item3Id   |  item4Id   |...
entiId_list_1_Id | item1Value | item2Value | item3Value | item4Value |...
                 |  item1Id   |  item2Id   |  item3Id   |  item4Id   |...
entiId_list_2_Id | item1Value | item2Value | item3Value | item4Value |...
...

itemValue を列名に入れ、列の値を空のままにしてサイズを小さくすることができます...たとえば、次のようにするだけで新しいアイテムを挿入できます。 listId][itemId] = アイテム値; または //列はその値によってソートされます insert into entityList[entityId][listId][itemvalue] = nothing; および削除: entityId='d' および listId='o' および itemId='n' である entityList から削除します。

または、アプリケーションを介して、 Hectorのようなリッチ クライアントを使用してそれを行うことができます...

于 2013-08-27T07:08:14.803 に答える