0

次のユースケースを持つアプリケーションに取り組んでいます。

  • ユーザーは csv ファイルをアップロードします。このファイルは、アプリケーションの再起動後も保持する必要があります
  • csv ファイル内のデータは、照会/ソートする必要があります。
  • ユーザーは、ファイルのアップロード時に csv ファイルでクエリ可能な列を指定します

現在提案されている解決策は次のとおりです。

  • 小さなファイル (より一般的) の場合は、データを xml に変換し、LOB またはファイル システムに格納します。クエリを実行するには、データ全体をメモリに丸呑みし、XQuery などを使用します
  • 大きなファイルの場合は、データベース (MySQL) に動的テーブルを作成し、クエリ可能な列にインデックスを付けます。

私たちはこのソリューションのプロトタイプを作成し、かなりうまく機能しましたが、XML や JSON などのより複雑なファイル形式をサポートできていません。解決策には、ここでは説明しない厄介な問題がいくつかあります。

NoSQL データベースのスキーマレスな性質を考えると、この問題を解決するために使用できるかもしれません。ただし、NoSQL の実務経験はありません。私の質問は次のとおりです。

  1. NoSQL はこのユースケースに適していますか?
  2. もしそうなら、どの NoSQL データベースですか?
  3. DBにcsvファイルをどのように保存しますか(列ヘッダーがキーを構成し、各行のデータフィールドが値を構成するキーと値のペアのコレクション?)
  4. 階層構造が深い可能性のある XML/JSON ファイルをどのように保存しますか?
  5. クエリ/インデックス作成やその他のパフォーマンスに関する考慮事項はどうですか? それはMySQLのようなものと比べてどうですか?

返信に感謝し、事前に感謝します!

csv ファイルの例:

employee_id,name,address  
1234,XXXX,abcabc  
001001,YYY,xyzxyz  
...  

DDL ステートメント:

CREATE TABLE `employees`(  
  `id` INT(6) NOT NULL AUTO_INCREMENT,  
  `employee_id` VARCHAR(12) NOT NULL,  
  `name` VARCHAR(255),  
  `address` TEXT,  
  PRIMARY KEY (`id`),  
  UNIQUE INDEX `EMPLOYEE_ID` (`employee_id`)  
);  

csv ファイルの各行

INSERT INTO `employees`  
                (`employee_id`,  
                 `name`,  
                 `address`)  
       VALUES (...);  
4

1 に答える 1

2

完全な答えではありませんが、いくつかの点で役立つと思います。

2 番については、少なくともNoSQL の実装を整理するのに役立つこのリンクを提供できます。

番号 3では、SQL データベースを使用します (ただし、NoSQL システムにも適合するはずです)。各列と各行を個別のテーブルとして表し、列と行への外部キーを持つ 3 番目のテーブルを追加します。セル。簡単なフィルタリングで大きなテーブルが得られます。

4番については、「階層データをテーブルで表現する」必要があります

これに対する一般的なアプローチは、次の例のように、属性を持つテーブルと、親を指す同じテーブルへの外部キーを持つことです。

+----+------------+------------+--------+
| id | attribute1 | attribute2 | parent |
+----+------------+------------+--------+
|  0 | potato     | berliner   | NULL   |
| 1  | hello      | jack       | 0      |
| 2  | hello      | frank      | 0      |
| 3  | die        | please     | 1      |
|  4 | no         | thanks     | 1      |
|  5 | okay       | man        | 4      |
|  6 | no         | ideas      | 2      |
|  7 | last       | one        | 2      |
+----+------------+------------+--------+

問題は、たとえば要素 1 からすべての子要素を取得したい場合、すべての項目を個別にクエリしてその子を取得する必要があることです。オブジェクトへのパスを取得し、他の多くのオブジェクトを走査し、追加のデータ クエリを作成する必要があるため、他のいくつかの操作は困難です。

これに対する 1 つの一般的な回避策であり、私が好んで使用している回避策は、変更された事前注文ツリー トラバーサルと呼ばれます。

この手法を使用すると、データ ストレージとアプリケーションの間に追加のレイヤーが必要になり、構造を変更する変更ごとに追加の列を埋める必要があります。left各オブジェクトに 、 、rightおよびの 3 つのプロパティを割り当てますdepth

leftおよびプロパティはright、すべてのツリー リーフを再帰的にトラバースしながら、各オブジェクトを上から数えて埋められます。

leftこれはandのトラバーサル アルゴリズムの漠然とした概算ですright( の部分はdepth簡単に理解できますが、これは追加する数行に過ぎません) :

  1. ツリー ルート (または、多数ある場合は最初のツリー ルート)left 属性を 1 に設定します。
  2. 最初の (または次の) 子に移動します。そのleft属性を最後の数字に 1 を加えた値 (ここでは 2) に設定します。
  3. 子供はいますか?はいの場合、番号 2 に戻ります。いいえの場合right、最後の番号に 1 を加えた値に設定します。
  4. 次の子に移動し、2 と同じことを行います
  5. 子がもういない場合は、親の次の子に移動し、2 と同じことを行います。

得られた結果を説明する図を次に示します。

mptt
(ソース: narod.ru )

オブジェクトのすべての子孫、またはそのすべての祖先を見つけるのが非常に簡単になりました。leftこれは、 と を使用して、1 つのクエリだけで実行できますright

これを使用する際に重要なことは、データとアプリケーションの間のレイヤーを適切に実装しleftrightdepth属性を処理することです。これらのフィールドは、次の場合に調整する必要があります。

  • オブジェクトが削除されました
  • オブジェクトが追加されます
  • parentオブジェクトのフィールドが変更されました

これは、ロックを使用して並列プロセスで実行できます。また、データとアプリケーションの間に直接実装することもできます。

ツリーの詳細については、次のリンクを参照してください。

個人的には、NoSQL を数回実行したときに、django-nonrel と django-mptt で素晴らしい結果が得られました。

于 2012-11-09T01:07:46.203 に答える