realsystems_jpのブログ -2ページ目

PostgreSQLで2つの文字列のminとmaxを求める関数(plv8版)

よく使う機能なのに、標準じゃないので作ってみました。

plpgsqlじゃなくてplv8にしてます。

 

小さい文字列を返す

 

create function strmin(s1 varchar, s2 varchar) returns varchar
as $$
    if (s1 < s2) { return s1; } else {return s2;}
$$

language plv8 volatile;

 

 

大きい文字列を返す

 

create function strmax(s1 varchar, s2 varchar) returns varchar
as $$
    if (s1 > s2) { return s1; } else {return s2;}
$$

language plv8 volatile;

やりたいこと

情報関係では、技術支援、指導、勉強会、セミナー、アプリの開発・販売。

他にも音楽関係と生活関係でやりたいことがある。

仕事に余裕があれば。
なくても時間をつくってやりたい。

どうすればできるだろう?

出羽三山神社 崇敬講社大祭

初めて参列してきました。
出羽三山神社の崇敬講社大祭。

三神合祭殿で月例祭と合わせて約1時間の祭典で、
祝詞の奏上や舞の奉納などが行われました。

100人ちょっとくらいの参列者で、
私はぎりぎりに入ったので正面のところには座れず、
舞は見えませんでした。
ちなみに参列者のほとんどはご高齢の方でした。

途中の祝詞が長くて、低頭を続けるのがちょっと辛かったです。

祭典の後は、崇敬会長の酒井さん(庄内藩主の家系の方)の書とか、
俳句会の方の俳句が記念品として抽選で3名に贈呈されていました。

その後、斎館で直会があったんですが用事があって帰ってきました。
玄関のところで、直会に出られない人用の食事とお祝いのお菓子を戴きました。

帰って開けてみると予想以上に豪華なお弁当。
そもそも箱のサイズが30cm四方くらいあるんですが
きのこご飯、焼きカレイ、ずいき芋の煮物、ゴマ豆腐のあんかけ、きのこの炒り煮、柿・・。

お菓子のほうは大福が10個くらい。

これに御神札までいただけて、大祭にも参列できて、
さらに1年間有効の会員用食事券がついて崇敬会正会員5000円。

お得とかそういう基準で考えることじゃないですが、
はっきりいってお得です!!!

日頃の罪穢れを祓って頂いたので
仕事もがんばれるというものです。

PostgreSQLのplpgsqlで動的SQL処理速度の改善(2倍!)

普通にSELECTするのと、動的SQLをEXECUTEするので
どのくらい処理速度が違うのか。

準備
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT, b TEXT, c TIMESTAMP);

1.普通のSQL
DO $$
DECLARE
    i INTEGER;
BEGIN
    FOR i IN 0..1000000 LOOP
        INSERT INTO t VALUES (i, i::TEXT, now());
    END LOOP;
END;
$$
-- 11秒

2.動的SQL
DO $$
DECLARE
    i INTEGER;
BEGIN
    FOR i IN 0..1000000 LOOP
        EXECUTE 'INSERT INTO t1 VALUES ($1, $2, $3)' USING i, i::TEXT, now();
    END LOOP;
END;
$$
-- 19秒

というわけで、動的SQLのEXECUTEにすると、通常のSQL実行の2倍近い時間がかかりました。

とはいえ、たとえばテーブル名を変えたいとか、動的SQLにしたいケースがあります。

そこで以前から考えていた解決策が、
実行時にSQLを埋め込んだFUNCTIONを丸ごと作ってしまい、
それを呼び出そうというもの・・という拙い文章では伝わらないと思いますので
実際のコードはこちら↓。

DO $$
DECLARE
    tablename TEXT := 't1';
BEGIN
    EXECUTE $Q$
        CREATE FUNCTION temporary_func() RETURNS INTEGER AS $F$
        DECLARE
            i INTEGER;
        BEGIN
            FOR i IN 0..1000000 LOOP
                INSERT INTO $Q$ || tablename || $Q$ values (1,1::TEXT, now());
            END LOOP;
            RETURN 0;
        END;
        $F$ language plpgsql
    $Q$;
    EXECUTE temporary_func();
    DROP FUNCTION temporary_func();
END;
$$
-- 11秒

読んでいただきありがとうございます。

PostgreSQLでシノニムの代用

PostgreSQL(9.4現在)にシノニムが無い。
Oracleにあるのに。

テーブルをスキーマごとに分類したいと思っても
シノニムがないからどうしようかと思ってました。

Oracleなら
ドメインごとのスキーマにテーブルを入れておきます。
schemaDomain1.table11
schemaDomain1.table12
schemaDomain2.table21
アプリ用のスキーマを用意して、そこにシノニムを作ります。
schemaApp1.synonymTable11
schemaApp1.synonymTable12
schemaApp1.synonymTable21
アプリからは、アプリ用のスキーマにあるシノニムにアクセスします。

似たようなことをPostgreSQLでやるには
シノニムの代わりに継承(inherit)を使います。

ドメインごとのスキーマにテーブルを入れるのは同じです。
アプリ用のスキーマを用意するのも同じですが、
そこに入れるのは空の親テーブルです。
schemaApp1.parentTable11
schemaApp1.parentTable12
schemaApp1.parentTable21
ドメインごとのスキーマはこれらを継承します。
ALTER TABLE schemaDomain1.table11 INHERIT schemaApp1.parentTable11;
以下同様・・。

これで、
select * from schemaApp1.parentTable11とすれば
schemaDomain1.table11の内容を取得することができます。

inheritなので
ALTER TABLE schemaDomain1.table12 INHERIT schemaApp1.parentTable11;
とすれば、
select * from schemaApp1.parentTable1
で schemaDomain1.table11とtable12の内容を取得することができます。