多数の列を格納する良い方法は何ですか?


18

データベースにこのデータを保存する方法を決めるのに問題があります。それを行う最善の方法に関する提案はありますか?私はデータベースについて多くのことを知りません、私は付け加えるかもしれません。

データはそのようにフォーマットされていますが、列の数は4ではなく約240であるため、各日付には240の一意の値が関連付けられています。

Date/Time 200,00 202,50 205,00  
2010.11.12  13:34:00  45,8214 43,8512  41,5369   
2010.11.12  13:35:00  461,9364  454,2612  435,5222 

また、行はDataSiteに関連付けられています。

最初に考えたのは、DataID(pk)、DataSiteID、ParameterID、Date、Valueのようなテーブルを作成し、DataSite、Parameter、Dateのインデックスを作成することでした。ParameterIDは、入力列ヘッダー(200,00 202,50 205,00 ...)を格納する別のテーブルを参照します。

私の第2の考えは、240奇数列すべてのテーブルを作成することでした。私は他にもいくつかの方法を考え出しましたが、それらもかなり不満足です。

私が最初の解決策で抱えている問題(それほど大きな問題ではありませんが、好きではありません)は、DateとDataSiteIDがその入力行の240個の値すべてに対して繰り返されるため、かなり多くの余分なスペース。

(上記のテキスト形式で)年間約40GBのデータが入り、データはDataSite、Parameter、Dateで検索されます。入ってくるデータの量は、おそらく1年程度で4倍になります。

良いアイデアはありますか?ありがとう、ジェームス

編集:これは時系列データであり、列は異なる波長での測定値です。データは比較的狭い波長範囲で分析する必要があります。将来のある時点で追加の波長が追加される可能性もあります。

編集:回答者のおかげで、私はそれを本当に感謝します:)私はおそらく500gb程度のテストデータでいくつかの実験を実行する時間を見つけることができると思います。結論を投稿します;)


2
列の命名から、これはある種の観測時系列データであると推測しています。これが科学データである場合、科学分野にデータを整理する典型的な方法があるかどうか、または少なくとも、データを利用する科学のユースケースは何かを確認したいと思います。
ジョー

それは確かに時系列データです:)もう少し情報で編集された元の投稿。
ジェームズ

回答:


10

どちらの方法でもケースを作成できますが、データが分析に使用され、そのデータから複数の列を同時に表示することが多い場合は、幅の広いテーブルを使用します。データベースの列数と行サイズの制限を確認してください。データ型が正しいことを確認してください。列の多くがNULLの場合、SQL Serverではそのためにテーブルを最適化できます。このタイプのデータの分析にNOSQL(SQLだけではない)ソリューションの使用を検討することもできます。

このデータが分析用に少なくなる場合は、質問に記載されているように正規化することをお勧めします。


6

私はあなたと非常によく似た状況で、1年に30〜50 GBの257のフィールドが入ります。結局、SQL Serverの単純な1つの大きな大きなテーブルを維持することになりました。私のデータはかなり質問されましたが、主に日付に関して、うまく機能しました。

データを論理的な小さなチャック(50個程度のグループ)に分割することもできましたが、この場合は実際にはあまり利点がなかったので、面倒を省きました。

今私が空想を感じていたら、理論上より適切なNoSQLオプションを検討するかもしれませんが、ミッションクリティカルなデータでは新しいことを試すことは常に神経にとって素晴らしいとは限りません。


6

だから、遅かれ早かれ自分の質問に答えるために(プロジェクトは最後まで進みませんでした)、空き時間をどうにかして、500GBのデータでテストテーブルを埋め、テーブルを次のように配置しました。

最初に考えたのは、DataID(pk)、DataSiteID、ParameterID、Date、Valueのようなテーブルを作成し、DataSite、Parameter、Dateのインデックスを作成することでした。ParameterIDは、入力列ヘッダー(200,00 202,50 205,00 ...)を格納する別のテーブルを参照します。

データベースのセットアップは、3GBのRAMを搭載した古いデュアルコアマシンへの標準のPostgreSQLインストールでした。DataSite DateとParameterIDによってデータを選択し、1時間の期間、1日間の期間のデータを平均し、新しいデータのチャンクを挿入するだけで、さまざまなクエリを実行しました。メモリから、すべてのクエリの実行に1秒もかかりませんでした。それは確かに私が予想したよりもはるかに速く、非常に使いやすいものでした。私が考えていなかったことの1つは、この方法でインデックス付けされたテーブルでは、インデックスファイルもほぼ500 GBであったため、240カラム幅のテーブルがあれば、ディスクスペースを確実に節約できることです。


しかし、スペースを節約しながら、インデックス作成速度に最も確実に影響を与えていたでしょう。機会があればもう一度やり直して、回転してみてください。
jcolebrand

3

Postgresでは、これをOracleの配列型またはVARRAYでエレガントに解決します。


それはうまくいくでしょう、唯一のキャッチは、データが何も意味しないため、DataSiteの列ヘッダーをどこかに保存する必要があるということです、そしてそれらは変化/変更する可能性がありますブタが前に飛ぶのを見た...)
ジェームズ

その場合、メインデータテーブルには「バージョン」と呼ばれる別の列と、列見出しの配列にバージョンをマッピングする別の列があります(したがって、配列インデックスはデータ配列と一致します)。
ガイウス

3

それがあなたの問題に役立つかどうかはわかりませんが、列については、直接リクエストを行う必要はありません(WHERE条件に決して入れない列)。特定の行は、JSON形式のブログフィールドに結合します。


さらに、そのblobを圧縮します。ネットワークとサーバーに負担をかけないように、クライアントで圧縮を行います。
リックジェームズ

2

おそらく、クエリされたparameter_idの分布に応じて、設計の最終決定を行います。つまり、ほとんど排他的に照会されるparameter_idがいくつかある場合、それらの値をホットテーブルに入れ、残りの値を別のコールドテーブルに入れます

Otoh、クエリの分布が多かれ少なかれ、数日分のサンプルセットをテーブルにロードして、1つのレコードがすべての値を保持して、レコード/ DBブロック間の比率を確認します(または行チェーンの問題さえあります。それに応じて、さらに設計を決定します。

まあ、それを読んだ後、私はおそらく並行して乾燥のための両方のアプローチを行うだろう。


2

私は質問を読み直していました-これが正しい場合、入力として取得する各レコードには、(ParameterIDに基づいて)追跡されている異なる値があります:

ParameterIDは、入力列ヘッダー(200,00 202,50 205,00 ...)を格納する別のテーブルを参照します。

...データの操作方法については十分に知りませんが、別のオプションを使用する傾向があります。各パラメーターIDに個別のテーブルを用意し、必要に応じてビューを表示しますさまざまなパラメーターを日付と場所でより広い(240列)テーブルに結合します。ビューでDataIDにアクセスできるようにすることが重要な場合は、a UNIONではなくaを使用できますJOINが、列はまばらに入力されます。


パラメーターとは、列ヘッダーまたは波長を意味します。私はこの方法でそれを行うことを考えていましたが、240のテーブルを持つことは少し不格好に感じます:)
ジェームズ

@James ... 240テーブルであってはなりません...一意ParameterIDのsだけです。ビューの幅は、測定対象の離散波長の数(および独立変数)になります。... OPeNDAPコミュニティは時系列データを対象としているため、物事をどのように処理するかを確認することをお勧めします。私が扱うデータのほとんどは画像(望遠鏡、コロノグラフ、マグネトグラフ)であるため、それらのデータは私の仕事に合わないため、ストレージの処理方法がわかりません。(それは単にHDF / CDF / NetCDF / ASCIIテーブルかもしれません)。
ジョー

残念ながら、240のような固有のパラメーターがあります:(リンクをお寄せいただきありがとうございます:)
ジェームズ

@James:また、放射照度データですか?もしそうなら、あなたはLISIRDの人々に尋ねたいと思うかもしれません...彼らは実験によってそれを別々のデータのセットに分けていると思います。
ジョー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.