単純なユーザー集約

カスタム集計は、誰も理解できない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}' );
      
      







ここで、 SFUNCFINALFUNCは関数の名前、 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データを収集するためのタイプは、集約の基本タイプと同じだからです。



All Articles