14

私は分析データベースを構築しています(データとビジネス目標をしっかりと理解しており、基本から中程度のデータベーススキルしか持っていません)。

「カレンダーテーブル」の概念を実装する同様のウェアハウスを構築するためのいくつかの参照に出くわしました。これは理にかなっており、簡単に実行できます。ただし、私が目にするほとんどの例は、スコープを「日」に制限するカレンダーテーブルです。私のデータは時間レベルまで分析する必要があります。おそらく数分。

私の質問:時間/分レベルの粒度のカレンダーテーブルの実装は、スペース効率とクエリ/並べ替え速度の観点から価値がありますか?もしそうなら、あなたはテーブルの構造と人口の方法/例をお勧めできますか?

私のプライマリデータテーブルには、常に2,000万行以上のデータが含まれ、分析用の一般的なサブセットは100万から500万の範囲です。ご覧のとおり、これは多くのタイムスタンプフィールドです。

4

3 に答える 3

18

ではPostgreSQL、任意の長さと粒度のカレンダーテーブルをその場で生成できます。

SELECT  CAST('2011-01-01' AS DATE) + (n || ' hour')::INTERVAL
FROM    generate_series(0, 23) n

これは(他のシステムのように)再帰を必要とせず、揮発性の結果セットを生成するための推奨される方法です。

于 2011-04-28T16:34:57.463 に答える
11

カレンダテーブルは、時空間のトレードオフを実装します。より多くのスペースを使用することにより、一部の種類のクエリはインデックスを利用できるため、より短い時間で実行されます。CHECK()制約に注意し、dbmsがサポートしていない制約を処理する管理プロセスがある限り、これらは安全です。

粒度が1分である場合、毎年約50万行を生成する必要があります。最小限のカレンダーテーブルは次のようになります。

2011-01-01 00:00:00
2011-01-01 00:01:00
2011-01-01 00:02:00
2011-01-01 00:03:00
2011-01-01 00:04:00

「バケット」分析を行っている場合は、このようなものを使用したほうがよい場合があります。

bucket_start         bucket_end
--
2011-01-01 00:00:00  2011-01-01 00:01:00
2011-01-01 00:01:00  2011-01-01 00:02:00
2011-01-01 00:02:00  2011-01-01 00:03:00
2011-01-01 00:03:00  2011-01-01 00:04:00
2011-01-01 00:04:00  2011-01-01 00:05:00

SQLのBETWEEN演算子にはエンドポイントが含まれているため、通常は使用を避ける必要があります。これは、エンドポイントが含まれており、bucket_endを「bucket_startプラス1分からこのサーバーが認識できる最小ビットを引いたもの」と表現するのが難しいためです。(危険は、bucket_endよりマイクロ秒大きい値ですが、bucket_startの次の値よりも小さい値です。)

そのテーブルを作成する場合は、おそらくこのようにします。(私はそれを「カレンダー」と呼ぶべきかどうかについてもっと難しいと思いますが。)

create table calendar (
  bucket_start timestamp primary key,
  bucket_end timestamp unique,
  CHECK (bucket_end = bucket_start + interval '1' minute)
  -- You also want a "no gaps" constraint, but I don't think you 
  -- can do that in a CHECK constraint in PostgreSQL. You might
  -- be able to use a trigger that counts the rows, and compares
  -- that count to the number of minutes between min(bucket_start)
  -- and max(bucket_start). Worst case, you can always run a report
  -- that counts the rows and sends you an email.
);

UNIQUE制約は、PostgreSQLに暗黙のインデックスを作成します。

このクエリは、一度に1日分の行(24時間* 60分)を挿入します。

insert into calendar
select coalesce(
                (select max(bucket_start) from calendar), 
                 cast('2011-01-01 00:00:00' as timestamp)
               ) 
             + cast((n || 'minute') as interval) as bucket_start, 
       coalesce(
                (select max(bucket_start) from calendar), 
                 cast('2011-01-01 00:00:00' as timestamp)
               ) 
             + cast((n + 1 || ' minute') as interval) as bucket_end
from generate_series(1, (24*60) ) n;

これを関数でラップして、一度に1年を生成できます。おそらく一度に50万行未満をコミットしようとします。

テスト用に2,000万行、さらに2,000万行の「カレンダー」分を生成するのにそれほど時間はかからないはずです。長い昼食。多分太陽の下で午後。

于 2011-04-28T18:26:34.873 に答える
1

私が構築したデータウェアハウスでは、別々のCALENDARディメンションとTIME_OF_DAYディメンションを使用していました。最初のディメンションには1日の粒度があり、2番目のディメンションには1分の粒度があります。

他の2つのケースでは、15分未満の粒度ではレポートが不要であることを事前に知っていました。その場合、簡単にするために、1日あたり96レコードの単一のCALENDARディメンションを使用していました。

これまでOracleウェアハウスでこのアプローチを使用していましたが、今年の夏にPostgreSQLウェアハウスプロジェクトに参加する可能性があります。

于 2011-05-09T15:33:44.247 に答える