20080223 PostgreSQLを使うだけならWindows版にすれば?

上記の言葉をよく聞くようになりました。

なぜLinux版にするかといえば、「数百倍以上高速」だ からです。

DBデータカルテストレージとしてPostgreSQLを使うならWindows版で充分です、
実際にそういう使い方がほとんどですのでコンピュータも遅い旧世代でよいかもしれません。

ところが数十万レコード以上の数値を複雑に演算しなければならないシステムですと、
多量の関連情報をLAN網を経てWindowsクライアントが操作していたら実現しません。
なにしろLAN網は超低速です。
複雑なSQL記述を駆使して高速な turbolinux11server PostgreSQLサーバに演算処理をさせるのも手法ですが、
難解でありプログラムの保守性可用性が著しく劣ります。(仕事になりません。)

PostgreSQLには自サーバー内に動いている自作プログラムへ通知 する機能を持っています。

この機能を使えば複雑な演算をPostgreSQLサーバで速攻に処理できます。
サーバも負荷に耐えうる良いスペックが必要です。
(おおよそですがselect128列10万行演算でRAM256MB食います。)

よろしければ参考にしてください。

注意:ソースリストはDB名を適切にすれば、末尾の「bd.c」(C言語ソースではない)でコンパイル、
 turbolinux11server で動作しますが紹介用です。趣旨を理解せず、このまま拡張しないように。

ソースリスト
'notify.c----------------------------------------------------------------------------------------------------
/*
 * notify.c : 非同期通知インターフェース
 *
 * Visual Basic 2008 などから発行するノンクエリSQL
 * Dim SQL1 as String = "NOTIFY command1"
 * Dim SQL2 as String = "NOTIFY command2"
 * Dim SQL3 as String = "NOTIFY command3" '停止
*/
#include <stdio.h>
#include <string.h>
#include "postgres.h"
#include "libpq-fe.h"
/************************************************************************************/
void exit_nicely(PGconn *conn)
{
    PQfinish(conn);
    exit(1);
}
void mycommand1(int ii_pidCD);
void mycommand2(int ii_pidCD);
main()
{
    /************************************************************************************/
    char    ic_256[256];    /* 汎用文字列[要素数] */
    /************************************************************************************/

    char    ic_LISTEN[]="LISTEN ";
    char    ic_pidCD[12];

    char    ic_Command1[] = "command1";
    char    ic_Command2[] = "command2";
    char    ic_Command3[] = "command3";

    PGnotify    *notify;
    /************************************************************************************/
    char    ic_SQL[4096];            /* SQL */
    /************************************************************************************/
    char    *pghost;    /* 接続するコンピュータバックエンド */
    char    *pgport;    /* 接続するコンピュータのバックエンドポート */
    char    *pgoptions; /* バックエンドのスタートアップオプション */
    char    *pgtty;        /* バックエンドのデバッグ用 tty */
    char    *dbName;    /* データベース名 */

    PGconn        *conn;    /* コネクション・ファイルハンドル */
    PGresult    *res;    /* 戻り値 */
 
    /* NULL なら環境変数.そこに見つからない場合はデフォルト定数. */
    pghost = NULL;        /* バックエンドが動作しているサーバのホスト名 */
    pgport = NULL;        /* バックエンドのポート番号 */
    pgoptions = NULL;    /* バックエンドのスタートアップオプション */
    pgtty = NULL;        /* バックエンドのデバッグ用 tty */

    dbName = "sampledb";    /* データベース名 */

    conn = PQsetdb(pghost,pgport,pgoptions,pgtty,dbName);
   
     /* バックエンドとの接続が成功したことを確認 */
    if (PQstatus(conn) == CONNECTION_BAD)
    {
        printf("Database '%s' Connection Eror!\n",dbName);
        fprintf(stderr,"%s",PQerrorMessage(conn));
        exit_nicely(conn);
    }
    /************************************************************************************/

     strcpy(ic_SQL,ic_LISTEN);
    strcat(ic_SQL,ic_Command1);
    res = PQexec(conn,ic_SQL);
    if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        fprintf(stderr,"'%s'Into Error!\n",ic_Command1);
        PQclear(res);
        exit_nicely(conn);
    }

    strcpy(ic_SQL,ic_LISTEN);
    strcat(ic_SQL,ic_Command2);
    res = PQexec(conn,ic_SQL);
    if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        fprintf(stderr,"'%s'Into Error!\n",ic_Command2);
        PQclear(res);
        exit_nicely(conn);
    }

    strcpy(ic_SQL,ic_LISTEN);
    strcat(ic_SQL,ic_Command3);
    res = PQexec(conn,ic_SQL);
    if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        fprintf(stderr,"'%s'Into Error!\n",ic_Command3);
        PQclear(res);
    exit_nicely(conn);
    }

    PQclear(res); /* メモリリーク防止のため即に PQclear(PGresult) */
 
    while (1)
    {
            sleep(1); /* チェックループ内のウエイト */
       
            PQconsumeInput(conn); /* バックエンド非同期メッセージ取得 */

        /* 非同期通知メッセージ有無 */
        while ((notify = PQnotifies(conn)) != NULL)
        {
            printf("command3.Name'%s',PID='%d' Get From Backend.",notify->relname,notify->be_pid);
           
            sprintf(ic_256,"%d",notify->be_pid);
            strcpy(ic_pidCD,ic_256);

            if ((strcmp(notify->relname,ic_Command1)==0))
            {
                printf("Call.'%s'\n",ic_Command1);
                mycommand1(notify->be_pid);
            }
            if ((strcmp(notify->relname,ic_Command2)==0))
            {
                printf("Call.'%s'\n",ic_Command2);
                mycommand2(notify->be_pid);
            }
            if ((strcmp(notify->relname,ic_Command3)==0))
            {
                printf("Call.'%s'\n",ic_Command3);
                return;
            }
        free(notify);
        }
    }
    PQfinish(conn); /* コネクション終了 */
}
/************************************************************************************/
void mycommand1(int ii_pidCD)
{
    printf("mycommand1\n");
}
/************************************************************************************/
void mycommand2(int ii_pidCD)
{
    printf("mycommand2\n");
}
'notify.c----------------------------------------------------------------------------------------------------

ビルド用
'bd.c----------------------------------------------------------------------------------------------------
#!/bin/bash
#
# echo This Proguram is Build by one.
#
# chmod u+x bd.c 実行権を与える。

# gcc でコンパイルオプション
# -o で実行プログラム名を命名
# -I で'postgres.h'が存在するインクルードディレクトリを指定
# -lpq は、
# -l__ がダイナミック(共有)ライブラリを示し、
# __pq が`PQexec'など`PQ*'のライブラリを示す。

# 予め postgresql-8.2.5.tar.gz を本家から turbolinux11server 自分のディレクトリにダウンロード
# 解凍 tar xvzf postgresql-8.2.5.tar.gz

gcc notify.c -o notify -I /home/dbman/postgresql-8.2.5/src/include -lpq
'bd.c----------------------------------------------------------------------------------------------------

●その他

プログラム開発用のマシンは turbolinux11server 全パッケージ選択でインストールしてください。
(私は、P3B-F.P2,400MHz,RAM.1GB,HDD20G,3Com.3c905+intel,PRO100、故意に遅いマシンを使うことで、 デバッグトレースしやすくしています。HDDを強化すれば大運用システムでも充分耐えます。)

turbolinux11server でプログラム開発するのは大変ですね。
エディタはしょぼいし、操作はWindowsVistaにはとうてい及ばないし、なんて言ってませんか?

これもよく聞くことですが、そうでもないんですよ。

PostgreSQL関連のプログラムしか turbolinux11server に開発しないからGUIは関係ないので、
turbolinux11server 用のgccソースの開発は、無料の「Visual C++ 2008 Express Edition」でやるんです。
コード記述はこれでなければ仕事する気になれません。VisualシリーズでBASICと共に一元管理できます。

上記ビルド用の「bd.c」も変なファイル名を付けていますが管理しやすくするためです。

プログラムソースを書いたら、FTPで turbolinux11server に送り込み、ターミナルからビルド./bd.cするんです。
( turbolinux11server と WindowsVista の2台を使います。)

ちなみにMakeファイルは作りません、色々拡張していくとMakeファイルの作り込みまで悩まなくてはいけなくなるので、
素直に羅列することでWindowsからの管理を簡単にしています。

なにしろMakeファイルを開発しているのではないのですから。

one.