背景
常時、データ(タイムスタンプのカラムがあるデータ)がインサートされるテーブルがあり、そのテーブルには直近1年以内のデータしか保持できない設計としています。
そのため1年以上前のデータはcsv化され別のストレージに保存される仕組みとしています(テーブル容量削減の意図)
しかし、運用上、1年以上前のデータを参照することがあります。
このとき、そのテーブルにアクセスした際に1年以上前のデータを参照する際にはcsvからデータを取得する運用としたいです、
環境
- PostgreSQL Ver
9.5
現状できていること
file_fdwを使って外部ストレージに保存されたcsvをテーブルとみなしてデータを取得することはできています。
やりたいこと
Where句でタイムスタンプの値が1年以上前を参照した際に、参照するテーブルを動的に変更したいです。
手段としては拡張機能を検討していますが、実現手法のイメージができていません。
全体構造は以下のような形を想定しています
- 直近一年以内のデータを参照するときには、PostgreSQL内のテーブルからデータを参照したいです。
- 一年以上前のデータを参照するときには、外部ストレージのcsvデータを参照したいです。
ただし、問い合わせるクエリ文(青四角部)のFrom句は、直近一年分のデータを参照するときと一年以上前を参照するときで変更できません
これは問い合わせ側の制約になります。
例えば実行日時を2020-11-04 00:00:00とした際に以下のクエリを受け取るとします。
Select * From TABLE Where ‘2019-11-04 00:03:00’ >= _timestamp and _timestamp >= '2019-11-04 00:00:00'
この場合、一年以上前のデータになるため、From句を変更して外部テーブルにアクセスする必要があります。
また、csvは毎分ごとに作成されるものになるため、上記のようなWhere句の場合以下の3つのcsvにアクセスする必要があります。
- アクセスする必要のあるテーブル名
TABLE_2020110403
TABLE_2020110402
TABLE_2020110401
現在想定している手法は、拡張機能でアクセスする必要のあるテーブル名のARRAYを作成し、以下の関数によって各テーブルの結果を結合することです。
DROP FUNCTION IF EXISTS csv(csv_names text[]); CREATE OR REPLACE FUNCTION csv(csv_names text[]) RETURNS TABLE( _timestamp timestamp(3) without time zone, _data text ) AS $$ DECLARE csv_name text; Begin FOREACH csv_name IN ARRAY csv_names LOOP RETURN QUERY EXECUTE format('Select * FROM %I', csv_name); END LOOP; END; $$ LANGUAGE plpgsql;
行き詰っているところ
以下の2の手順における、1の手順で受けたクエリのWhere句に応じて、リストを作成する工程で行き詰っています。
1. クエリを受け取る
Select * From TABLE Where ‘2019-11-04 00:03:00’ >= _timestamp and _timestamp >= '2019-11-04 00:00:00'
2. 一年以上前のデータなので、上記のクエリは実行せずに、以下のリストを作成する
[TABLE_2020110403, TABLE_2020110402, TABLE_2020110401]
3. 2のリストを受け取って、関数(csv)に引数として与えて、処理を実行する
Select * FROM csv(ARRAY[‘TABLE_2020110403’, ‘TABLE_2020110402’, ‘TABLE_2020110401’] Where ‘2019-11-04 00:03:00’ >= _timestamp and _timestamp >= '2019-11-04 00:00:00'
拡張機能であればこの処理が実現できるのかもしれませんが、具体的な手法が思いつきません。
なにかいい手法があればご教授いただけますと幸いです。
設計上の制約
- 受け取るクエリのFrom句は変更できない
- PostgreSQLのVerを変更することはできない
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/30 08:36 編集