
カスタム集計は、誰も理解できないPostgreSQLのユニークな機能の1つです。 ただし、少なくとも1つの実際に機能する例を作成するとすぐに、クラウドが開き、そのようなベテランの機能がなくても以前はどのように生きていたかに驚くでしょう。 それでは、このような単純なユニットを作成しましょう。 論理(ブール)フィールドの状態、つまり最も一般的な値を返します。
誰が、なぜ変なものが欲しいのでしょうか? さて、昼夜を問わずいくつかのWebサーバーを監視し、1時間ごとの稼働時間を把握したいとします。 サーバーのステータスが30秒ごとにテーブルに入力されるとします
。TRUE-サーバーは実行中、
FALSE-サーバーは横になっています。 その後、ほとんどの時間サーバーが動作していた場合は
TRUEを返し、ほとんどの場合サーバーが立っていた場合は
FALSEを返し
ます 。 監視システム自体が嘘をついているため、データがない場合、
NULLを返し
ます 。
もちろん、これはすべて、
WINDOWメカニズムなど、他のさまざまなメカニズムを使用して実行できます。 ただし、あるリクエストでは、ダウンタイムやサーバー操作など、他の蓄積された統計を処理する必要があると想像してください。 この場合、PostgreSQLはエレガントなメカニズムを提供します。
まず、ブールフィールドに関するデータを蓄積する統計関数が必要です。 通常、このような関数には2つの入力パラメーターがあります。
- 計算された値が保存されるパラメーター(結局、この関数は行ごとに呼び出されます);
- 現在の行の値が入る列の型パラメーター。
サーバーのUPおよびDOWN測定値の数を保存するとします。 これには整数配列を使用できます。
同じ成功で、これは複合型で行うことができます。 翻訳者 。 このような関数は、純粋なSQLでも簡単に記述できます。
CREATE OR REPLACE function mode_bool_state(int[], boolean) RETURNS int[] LANGUAGE sql as $body$ SELECT CASE $2 WHEN TRUE THEN array[ $1[1] + 1, $1[2] ] WHEN FALSE THEN array[ $1[1], $1[2] + 1 ] ELSE $1 END; $body$;
int []関数の結果は、次の行で呼び出されるとき、同じ関数の入力への最初のパラメーターとして提供されることに注意してください。 翻訳者 。決定を下して最終結果を出力するには、別の関数を作成します。
CREATE OR REPLACE FUNCTION mode_bool_final(INT[]) RETURNS boolean LANGUAGE sql as $body$ SELECT CASE WHEN ( $1[1] = 0 AND $1[2] = 0 ) THEN NULL ELSE $1[1] >= $1[2] END; $body$;
ポイントは小さいです-ユニットを宣言します:
CREATE AGGREGATE mode(boolean) ( SFUNC = mode_bool_state, STYPE = INT[], FINALFUNC = mode_bool_final, INITCOND = '{0,0}' );
ここで、
SFUNCと
FINALFUNCは関数の名前、
STYPEは統計を収集するためのデータ型、
INITCONDは初期条件です。
仕組みを見てみましょう!
SELECT server_name, sum(CASE WHEN server_up THEN 0.5 ELSE 0 END) as minutes_up, mode(server_up) as mode FROM servers WHERE montime BETWEEN '2013-04-01' and '2013-04-01 01:00:00';
server_name minutes_upモード
web1 56.5 TRUE
web2 0.0 FALSE
web3 48.0 TRUE
web4 11.5 FALSE
PSトムブラウンによる英語
の記事も、カスタム集計の作成方法を説明しています。 その中で、作者は最後のオプションの
FINALFUNC関数を使用しません。彼の例で
STYPEデータを収集するためのタイプは、集約の基本タイプと同じだからです。