web-dev-qa-db-ja.com

多数の列または行に最適なデータベース

問題1:

567行と16,382列のファイルが1つあり、そのほとんどが浮動小数点数です。 117,493行で3列しかない別のファイルがあります。内容は生物学と遺伝学を扱っています。

ファイル内の数値の意味がわかりません。これは大学のプロジェクトで、ファイルの内容がわからなくても、ファイルを指定してさまざまなことを照会できる必要があります。内容を理解する必要があるため、データを正規化することは想定されていません。パフォーマンスと、どのデータベースを選択するかという理由で評価されます。

ファイル1:(567行、16,382列)

このファイルの列の数に驚かされています。列は主に一連の数値を持つ遺伝情報であり、正規化できません。最初はPostgresqlがFile 1に適していると思っていましたが、それらは行指向のデータベースであるため、恐ろしいでしょう。私はCassandraが列指向のルックアップに適していることを読みましたが、問題はほとんどの列と行にデータが含まれており、値のないいくつかの領域を除いて、ほとんどが構造化されています。 Cassandraを使用する方が良いでしょうか?

ファイル1の操作:

  • 単純なルックアップ
  • 平均を見つける
  • 標準偏差を見つける

平均や標準偏差の計算などの集計関数について、SQLとNoSQLの間の一般的なパフォーマンスを確認できません。これは私のデータベースを選択するもう1つの要因です。 Cassandraは列指向であるため、ここではPostgresqlよりCassandraの方が高速だと思います。

ファイル2:(117,493行、3列)

すべての行と列にはデータが含まれています。 3列しかありませんが117,493行あり、Postgresqlは行指向であり、欠落データがないため、Postgresqlはここで優れていると思います。この場合、より良いNoSQLの代替案はありますか? Key-ValueストアのNoSQLは主に取得に使用されるため、より良いでしょうか?

ファイル2の操作:

  • 単純なルックアップ

問題2:

私が持っている大きなファイルのほとんどは、File 1File 2File 2にPostgresqlを使用し、File 1にCassandraを使用すると、かなりのパフォーマンスの損失がありますか?通常、関連するテーブルをRDMSに格納しますが、File 1の列数は、ハイブリッドアプローチを使用する方が良いという意味ですか?

3
Dobob

PostgreSQL

@Dobobすべてを正規化できます:)それがあまり秘密でない場合、それはどのようなデータですか? (遺伝学者に転向したDBAとして尋ねる。)

これは全般的にtrueです。そして、どのように正規化できるかを検討することから始めるべきです。明らかに、あなたはその考えを嫌い、常に正常化することはできません。たとえば、ラスターは多くの場合、科学機器からの読み取り値のコレクションであり、実際に非正規化することはできません。それらは同時に取得され、同じサンプルを表し、多くの場合1,000のデータポイントを持ちます。 (ただし、PostGISに保存できます)。

問題1の解決策

PostgreSQLは テーブルの16,383列(または、1600 +以上) をサポートしていませんが、 SQL配列 はサポートしています。あなたはおそらくそれを利用することができます、

_CREATE TABLE foo AS
  SELECT
    r AS id,
    array_agg(c) AS genetic_stuff
  FROM generate_series(1,567)
    AS r
  CROSS JOIN LATERAL generate_series(1,16382)
    AS c
  GROUP BY r;
_

これで、最初の基準を満たしているものの、正気ではないテーブルができました。

_          Table "public.foo"
    Column     |   Type    | Modifiers 
---------------+-----------+-----------
 id            | integer   | 
 genetic_stuff | integer[] | 
_

平均を見つけるのは簡単です。

_SELECT id, avg(x)
FROM foo
CROSS JOIN LATERAL unnest(genetic_stuff)
  AS t(x)
GROUP BY id;
_

そして、その全体の操作について_Execution time: 3865.308 ms_!それについて文句を言うことができます。その平均をキャッシュしたい場合は、自由に _MATERIALIZED VIEW_ を使用してください。

標準偏差の場合は 適切な集約関数を使用avg()の代わりに使用します。実行時間はほぼ同じです。

ここでこれをどのようにクエリしているかはわかりませんが、インデックスがない場合(最悪の場合)は非常にシンプルで高速です(seqスキャンであることを考慮してください)、16,000のアイテムを含むアレイのスキャンは、最新のCPU、およびPostgreSQL 9.6では、このseqスキャンは並行して実行することもできます(afaik)。

_SELECT * FROM foo
WHERE genetic_stuff @> ARRAY[5];
_

インデックスを使用できますか?承知しました。 intarray モジュールから、

2つのGistインデックス演算子クラスが提供されています。Gist__int_ops(デフォルトで使用)は、中小規模のデータセットに適していますが、Gist__intbig_opsは、より大きな署名を使用し、大きなデータセットのインデックス作成に適しています。 (つまり、多数の個別の配列値を含む列)。実装では、非可逆圧縮が組み込まれたRDツリーデータ構造が使用されます。

それを試してみましょう...

_CREATE INDEX ON foo
  USING Gist(genetic_stuff Gist__intbig_ops);
VACUUM FULL foo;

                                                          QUERY PLAN                                                           
-------------------------------------------------------------------------------------------------------------------------------
 Index Scan using foo_genetic_stuff_idx on foo  (cost=0.14..8.16 rows=1 width=22) (actual time=0.119..47.846 rows=567 loops=1)
   Index Cond: (genetic_stuff @> '{5}'::integer[])
 Planning time: 0.072 ms
 Execution time: 47.948 ms
(4 rows)
_

インデックススキャン以外に何が必要かわからない。すべての行に_5_の要素が含まれていない場合は、おそらくより有用ですが、それはサンプルデータにすぎません。

とにかくそれを持っています。

問題2の解決策

その恥ずかしがり屋ですが、PG行は太っているので、他のことは少しオーバーヘッドの問題にはなりませんが、多くの行を話しているわけではなく、最終的には、以下の表で基準が5088 kBのみであることは問題になりません私のシステム。自分を心配する価値はほとんどありません。

_CREATE TABLE baz
AS
  SELECT
    x AS id,
    x*2 AS x2,
    x*3 AS x3,
    x*4 AS x4
  FROM generate_series(1,117493)
    AS t(x);
_
3
Evan Carroll