システム奮闘記:その7

中小企業でPostgreSQL導入の話



(2001年12月21日に掲載)
(2003年11に改定)
(2006年9月16日に改定第2版)
はじめに


  2001年9月の半ば、システム構築の話がでてきた。
  それは、インタネット上で、ある顧客向けのデータ検索システムを
構築する事だった。

  私は

 PostgreSQLが使えるかも!

 と思った。
  PostgreSQLは名前は聞いたことはあるし、2001年9月7日に行なわれた
PostgreSQL関西支部設立記念セミナーで、PostgreSQLが商用のデータベースに、
引けを取らないと聞いていた。

  しかし、実際にはPostgreSQLを触ったことがなかった。
  そこで、どんな物かを知るために、早速、石井達夫さんの
「シーラカンス本」を購入した。

 「シーラカンス本」とは「改訂第3版 PostgreSQL完全攻略ガイド」で
表紙にシーラカンスが泳いでいるので、通称「シーラカンス本」という。


  普段なら、のんびり構えて、暇な時にでもPostgreSQLでも触ろうと思っていた。
  しかし、そんな悠長な事はできなかった。

  数日後、社長が私の所にやってきた。

社長とのやりとり
社長 今度の検索システムやけど、自社ででけるんかいな?
PostgreSQLやPHPなどを勉強しないといけないですから
最低2ヶ月はかかります。
社長 そんなに時間がかかるんやったら、外注や!

  自力で構築したかったのに・・・ (TT)

  近くに部長と次長がいたので

部長と次長の言葉
次長 まずは、業者に見積もりを依頼するように!
部長 もう1社、わしの知り合いに紹介してもらう。

  そこで、渋々、SI業者に見積もりの依頼する事にした。

  外注する方向に決まったが、折角、データベースの導入するのに、
自分でシステム構築できないのは、無念さを感じる。
  しかし、往生際の悪さ(?)は天下一品の私。そこで考えたのが

  見積もりが出るまでに、自社開発しちゃえ!

 自社仕様のシステム構築を外注する場合、業者と打ち合わせをして
ある程度、仕様を決めたりしてから、見積りが出る。
  なので、見積り依頼をしてから出るまで時間がかかるので、
それまでの時間を有効に使える。


  まずは、データベースを載せるマシンの確保だった。
  さすがに、稼働中のサーバーにインストールは恐かった。
  初めて入れるだけに、何か起ってはマズイ。
  幸い社内で余っていた古いマシンが1台あった。

  取られる前に、すぐに確保。性能はPentium133MHz、RAM48Mだった。

  社内初のテストサーバーだった!

  この時、どれくらいの性能でPostgreSQLが動くのか知らなかった。
その上、PostgreSQLの事例集などを見ると、使われているサーバーが
相当、高性能のサーバーなので「この性能で、データベースは動くのかいな」と
心配だったが、物は試しと思い実行した。

Pentium133MHzでも動くPostgreSQL
「ホンマに動くのかいな」と心配しながら、インストールしたPostgreSQL。
でも、まともに動いたので、良かったと思った。

だいぶ後になり、シーラカンス本の著者の石井さんとお話する機会があり
石井さんに「性能が低いパソコンでもPostgreSQLは動くのですね」と言うと
石井さん曰く「Pentium133MHzもあれば、贅沢ですよ」だった。

Pentiumが出る前から、PostgreSQLが開発されているため、
性能が低いパソコンでも動くように設計されているようだ。

  Linuxをインストールした上で、PostgreSQLをインストールした。
本の通りやれば素直にできたので、難しくなかった。

  次に、データベースを扱うために、SQL言語を覚える必要があった。
  SQL言語。実は、1999年に、情報処理2種(現在の基本情報処理技術者)の
試験を受けてみようと思い、試験勉強した時に出会った事がある。
  SELECT文などがあったのは覚えているが、机の上だけのお勉強だけで、
実際に、データベースを使って実践的に覚えていないため、頭に入っていない。
  そのため「SQL文があったなぁ」という程度にしか記憶がなかった。

  もちろん、情報処理2種試験は落ちました (^^;; 

  MS-Accessは触ったことがあるけど、SQL文までは触った事がない。
  そこで、最初からSQL文を覚えることになった。

  SELECT * FROM table ;

 という感じで、コマンドを叩きながら、覚えていた。
  机の上のお勉強と違い、コマンド実行後の出力結果が見れるので、
実体験の伴った学習は覚えやすい。
  それに試験と違い

  例え、忘れても本を見りゃ大丈夫!

  そんな安心感から、忘れても心配しなかったため、リラックスした感じで、
検索、更新などのSQLの簡単な部分を一通り試していった。

 一通り、SQL言語を覚えた所で、次はデータベースにアクセスするための
言語を覚えなくてはならなかった。
  PostgreSQLへのアクセス言語に、PHP言語が主流になっている。
  しかし、無理に新しい言語を覚えるよりも、多少でも知っているC言語の方が
早いと考えた。

多少、C言語を知っていると書いているが・・・
上のように「多少でも知っているC言語」と書いたが、
当時のC言語の知識は、お粗末な状態でポインタすら理解していなかった。

C言語の場合、まだ、if文、for文に、簡単な計算プログラムが書けたが、
PHPの命令文を全く知らない状態だったので、PHPと比較したら、
C言語の方が、まだ知っていたというレベルだった (^^;;

これを世間では「ドングリの背比べ」という。

ちなみにC言語のポインタについては「システム奮闘記:その36」
(C言語:ポインタと構造体入門)をご覧下さい。

  なんとか、シーラカンス本に書いているC言語のソースを見ながら
サンプルプログラムを作成したが

  コンパイルが通らへん (TT)

 そこで、困った時のProject BLUEのMLに質問した。

投稿した内容
 おはようございます。

 困った時のBLUE頼みです。

 社内で、データ検索システムの構築が決まり、
データベースを導入ということで、
PostgreSQLを入れようと思っています。

 PostgreSQLにアクセスするための言語に
ある程度、知っていますC言語でいこうと思いました。
 でも、試しに、簡単なプログラムを作りましたが、
コンパイルが受け付けてくれません (TT)

 なぜ、ダメなのか、もし、よろしければ、
教えていただけませんでしょうか?
 ソースと、症状を下に書きました。

 環境は gcc は egcs-2.91.66
 OSは RedHat6.2  、PostgreSQLのバージョンは 7.1.2 です。

--------------------(ソース)--------------------
#include <stdio.h>
#include <postgres_fe.h>
#include <libpq-fe.h>

int main(void)
{
  char *pghost ="", *pgport ="" , *dbName = "test" ;
  PGconn *con;

  con = PQsetdb(pghost,pgport,NULL,NULL,dbName);
}

---------------------(症状)--------------------

gcc access.c -L/usr/local/pgsql/lib  -I/usr/local/pgsql/include

/tmp/ccuntItK.o: In function `main':
/tmp/ccuntItK.o(.text+0x30): undefined reference to `PQsetdbLogin'
collect2: ld returned 1 exit status


 PQsetdbLogin の関数が見れないみたいです。
 何か、取り込まないといけないヘッダー・ファイルがありますのでしょうか?

 PS  C言語にこだわらず、
    いちからPHPを覚えた方が早いかも (^^;)

  投稿したら、すぐに馬場さんからお返事を頂いた。

馬場さんからのお返事
>gcc access.c -L/usr/local/pgsql/lib  -I/usr/local/pgsql/include
>
>/tmp/ccuntItK.o: In function `main':
>/tmp/ccuntItK.o(.text+0x30): undefined reference to `PQsetdbLogin'
>collect2: ld returned 1 exit status
>
>
> PQsetdbLogin の関数が見れないみたいです。

ええと、ライブラリのパスは指定してあっても、ライブラリの指定が
ありません。いま手元に pgsql が入ったマシンがないので、ライブラリ
の名前がわからないのですが、もしそれが、仮に、libabc.a とか libabc.so
だったとすると、コンパイル時には、

gcc access.c -L/usr/local/pgsql/lib  -I/usr/local/pgsql/include -labc

のように、-labc をつけないといけないのでは。

  続いて、わかとのさんから、お返事を頂いた。

わかとのさんからのお返事
わかとのっす。

>  なぜ、ダメなのか、もし、よろしければ、
> 教えていただけませんでしょうか?
>  ソースと、症状を下に書きました。

 エラー自体は、「最後のリンク時点で解決できないシンボルがある」
というものですね。
 馬場さんも書いてますが、これは PostgreSQL のクライアント向けの
ライブラリが -l 等で指定されてないってことです。

 手元の環境でコンパイルだけチェックしてみましたが、

> gcc access.c -L/usr/local/pgsql/lib  -I/usr/local/pgsql/include

 は、

gcc access.c -L/usr/local/pgsql/lib  -I/usr/local/pgsql/include -lpq 

とかしてやるのが正しいかと。

  「 -lpg 」というオプションを付ける必要がある事がわかった。


  馬場さんと、わかとのさんからのお返事を見て、ふと思った。
  postgreSQLのライブラリが「libpg」なので、「-lpg」をつける。
 
  そういえば、C言語のプログラムで、gccに「-l」オプションをつける話。
  学生時代、大学の研究室でC言語で三角関数などの数値計算をしたため、
math.hのヘッダーファイルと、コンパイル時に「 -lm 」という
オプションが必要だという事は知っていたが、なぜオプションを付けるのかは
全く知らなかった。
  調べてみると、数学の計算式を使う際に取り込むライブラリとしてlibm.aがある。
  1995年にC言語に出会ってから、6年経って、この事実を知った (^^;;  

ライブラリが何か全くわかっていなかった
ライブラリを取り込むのに「-l」オプションが必要な事を知ったのだが、
この時点では、まだライブラリとは何かが全くわかっていなかった。

ライブラリとは、関数を定義したプログラムの部品(モジュール)だ。
printf()関数や、fget()関数など、C言語の本に出てくる関数の場合、
標準ライブラリに、それらの関数の処理を定義している。
標準ライブラリの場合、gccは自動的に取り込むため、ライブラリの取り込みを
意識する必要することなく、コンパイルができる。

ところで、PostgreSQLの接続する関数は、独自に開発された関数であり、
それらをまとめた物として、ライブラリ(libpg.a)がある。
独自に作られた物なので、gccは、そんなライブラリがあるとは知る由もない。
なので、gccに対しては「取り込め」という指示として「-l」オプションを
つける必要がある。
数値計算のライブラリ(libm.a)も同様だ。

しかし、当時は、そんな事を知らなかったため、普通にgccを使えば
勝手にコンパイルをしてくれると思っていたし、「-l」オプションを
つける理由を全く理解していなかった。
これらを理解できたのは2005年になってからだった。

ライブラリの関して詳しくは「システム奮闘記:その53」をご覧ください。
(C言語のライブラリとは何か?)

  話を元に戻して、MLではPHP言語の方が楽だという、ご意見を頂いた。
  マンモス本の著者の堀田さんからは次のような、お返事を頂いた。

堀田さんからのお返事(一部抜粋)
>  PS  C言語にこだわらず、
>     いちからPHPを覚えた方が早いかも (^^;)

絶対早いっす。

  色々な方から、PHP言語を勧められた

まいパパさんからのお返事(一部抜粋)
文法自体はPHPとCでは似たようなところがあるので
充分知識が役立つと思いますよ^^
近藤さんからのお返事(一部抜粋)
C とよく似た関数も多いので習得は容易です。

ただし、PHP と C は、細い文法が違いますし、PHP は厳格な
言語ではないので、そういうもんだと思って勉強した方が
ストレスがなくていいと思います。

for 文の 中の switch から、break n ; continue n ; 
すると妙な値にしないといけないとか、コンストラクタ
があるのにですトラクタがないとか、勝手に型変換して
しまうので、わけがわからない結果になることがごく
たまにあるとか。

でも、やっぱり PHP は、手軽で便利なんで手放せない
ですね。

  単純な私は、あっさりC言語をやめて、PHPにしようと決めた。

  当時、PHPには、2種類のバージョンがあった。PHP3とPHP4だ。
  PHP4は機能が拡張されているが、日本語の処理に不安があると聞いていた。
普通なら迷う所だが、私はあっさり決まった

  どーせ、難しい機能は使わへんから

  無難にPHP3でいこう!

  当時は、PHP3でも、十分活用できた。
  なので「無理したって仕方ないのらー!!」と思った。


 さて、目的のデータ検索システムの構築にとりかかった。

  ライバル社の大手・某I社は、すでにデータ検索システムを公開していた。
  しかも、iモード検索ができる!!
  後発のうちがiモード検索ができないと、評価は下がる。
  そこで、iモードでも検索できるように考慮したシステムを構築する必要があった。
 
  まず、表示文字数。当時、1行に8文字という制限があった。
  その上、文字が多いとパケット通信なので、利用者の料金がかかる。
  文字数を減らす必要があった。

  最大の問題は、文字コードにあった!!
  IEやNetscapeなどのブラウザーの場合は、Shift_JISとEUCの
どちらでも表示可能だが、iモードはShift_JISのみだった。

  すでに、PostgreSQLに格納したテストデータの文字コードはEUCだった。


  この時、HTMLで出力される文字コードをShift_JISにするには、
<meta>タグに以下の事をすれば良いと思ってやってみた。

  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=Shift_JIS">

  しかし、うまくいかず・・・ (--;;

  あくまでもコンテンツの中身はShit_SJISという目印にすぎないのであって
コンテンツの文字の文字コードをShift_JISにするわけではない。
  当り前なのだが、当時はメタタグの事を知らなかったので
「なんで?」と思った。

  それならばと思い、データベースの中身のテストデータの文字コードを
全てShift_JISにして、テストを行ったら、今度も文字化け。
  「うーん、どないしたら、ええねん」と考えた挙げ句

   PHP3の設定ファイルである php3.ini ファイルを触ろうと思った。
   最初の設定の時は、シーラカンス本の通りにしていた。

シーラカンス本の設定
; internationalization
i18n.http_output = EUC-JP
i18n.internal_encoding = EUC-JP
i18n.script_encoding = auto
i18n.http_input = auto
i18n.http_input_default = EUC-JP

  この当時、この設定の意味などわからないが、SJISやEUCの文字を見て
文字コードの設定だというのは、わかった。
  でも、inputが検索などで入力される場合で、outputが出力だという事は
類推できる。autoは全ての文字コードと推測もできる。
  そこで「類推可能な所は、SJISにしちゃえ! 他はautoだ」という感じで変更した。

試行錯誤:その1
; internationalization
i18n.http_output = SJIS
i18n.internal_encoding = SJIS
i18n.script_encoding = auto
i18n.http_input = auto
i18n.http_input_default = SJIS

  しかし、エラーが発生。
  その上、エラーがでなくても、今度はEUCコードが読めなくなる。
  対処療法であって、根本的な解決にはならない。
  考えた末、ふと、autoは全ての文字コード対応だという、
とんでもない発想が思いつき、次のように変更してみた、

試行錯誤:その2
; internationalization
i18n.http_output = auto
i18n.internal_encoding = auto
i18n.script_encoding = auto
i18n.http_input = auto
i18n.http_input_default = auto

  としてみたら、うまくいった  V(^o^)V
  これだと、どんな文字コードのデータを入れようが読める!

  よい子は、メチャクチャええ加減な設定なので、真似しないようにね!
  PHP3の文字コードの設定につきまして「システム奮闘記:その10」の
携帯3社コンテンツ作成物語に書いています (^^)

  PHP3言語の習得。
  最初はシーラカンス本に載っている部分を触ったりしたが、
これではWebアプリは組めない。
  だが、システム構築は外注という方向のため、データベースに必要とは言えない。

  そこで、適当な理由を考えて予算申請した。
  購入はOKというのが出た。購入したのは、マンモス本だった。

 PHP3。習得するのは大変かなぁと思いきや、そうでもなかった。
 C言語を知っていたら、非常に、とっつきやすい言語の上、無理に覚えなくても、
必要な時に、本を見りゃ良いという発想だったので、気が楽だった。

実は、PHP3もたいして習得していなかった (^^;;
この奮闘記を書いた2001年の段階では、PHP3を覚えたと思っていた。
だが、それもC言語でいう if文、for文の程度のレベルだった。

PHP言語はオブジェクト指向言語なのだが、オブジェクトを使うどころか
オブジェクトがある事自体、知らなかった。
しかも、foreach()関数など使えば便利な関数を知らなかった。

その上、PostgreSQLへの接続や検索関係の関数の用法などは
本の丸写しで、キチンと理解しないまま使っていた。

今、考えれば、デタラメかつメチャクチャな事をしていたのだが、
それでも、なんとかPostgreSQLと連動したWebアプリが組めたので、
PHPなら使えるという錯覚を起こしてしまったのだ。

錯覚にすぎなかったのを自覚したのは、2006年になってからだった。

 そして、1週間ぐらい、ちょこちょこ触っていると、システムの大枠が完成した。
  これならいけると思い、部長と次長に報告した。

  ちょっとは評価されると思ったが、ところがどっこい、何を脳天気な事を
言っているのかという口調で「データ入力の問題は、どないなるねん」とか
「どういう形態で運用するのか決まってへんやろ」と言われた (TT)

  とりあえず依頼した外注先には、急遽、自社開発する事になったのを伝えた。

  部長は「SK社には構築する話をしてしまったなぁ」と言った。
  数日後、部長の知り合いが紹介したSK社の人がやってきた。
SK社の営業部長と、営業マンがやってきた。

  部長と私が応対した。
  部長が「実は、菅が、数日で検索システムを構築してしまったんですわ」
と言うと、SK社の人はビックリした。
  S社の人にしてみれば、なんで総務の事務員がデータベースを使った
Web検索システムを構築できるんだという感じだった。
  そのためSK社の人が「御社には、こんな詳しい人がいて頼もしいですね」とか
「これからの時代は、こういう人材が大事ですよ」と、やたら私を持ち上げてくれた。
  SK社の人が帰った後、部長が「えらい菅ちゃんの事、持ち上げ取ったけど、
なんでやろ」と不思議がっていた。

  この頃は、まだ私の技術や知識は全く評価されていなかった。
  単なるパソコン好きの趣味の延長という感覚でしか、捉えていなかった。


  さて、ライバル社の某I社は、さすがは大手。お金をかけている。
  URLから推測した某I社のシステムと、うちのシステムを比較すると

某I社と、うちの会社との比較
比較項目 某I社 うちの会社
サーバーOS WindowsNT Linux
Webサーバー IIS Apache
言語 VisualBasic(?) PHP3
データベース MS-Access
もしくは
SQLServer
PostgreSQL
iモード検索 可能 可能
安定性 時々、障害あり
(話によれば)
安定性抜群のはず(^^;;
構築者 話によれば外注 自力で構築
サーバー機 レンタルサーバー 社長のお古
アクセス言語、データベースは私の推測ですが、OSとサーバーソフトは
Netcraft社のホームページで確認しました。
http://www.netcraft.com/

サーバーですが、nslookupでドメインを調べたら、
某I社の場合、レンタルサーバーのようでした。

  お金をかけて構築した某I社。

 お金をかけずに構築した、うちの会社。

 全く対照的だが、性能的にも機能的にも互角!

  なんと、中小企業が大企業と互角に戦える!
  まさに、オープンソースの威力の凄さの良い例だと思う。

  オープンソースは中小企業のIT化の切り札

  と言っても過言ではない!

  野球で例えたら、9回裏、2死満塁の所で、代打の切り札が出てきて
逆転サヨナラ満塁ホームランを打つ感じがする。


 あとはデータ入力。とにかくデータ量がハンパではない。
  3000件以上はある。しかも、専門知識がないとデータの整理ができない。
  そこで、海外のメーカーに、データの提供を依頼。
  あまり期待していなかったが、なんとデータを提供してくれた。
  しかし、間違いが多かったり、不明の意味の「?」の印が多かった。
  さっそくプリンタに打ち出した。A4用紙で75枚。
  関係部署の人が半泣き状態で、赤ペンでデータを点検・訂正をしていった。


 そして、修正した部分の入力作業。誰でもできるが、手間がかかり面倒な作業。
 そこで外注。業者に頼むのかといえば、そうではなかった。
  うちの会社のOBの方で、パソコンに強い人に依頼だった。
  バイト料を払うとはいえ、業者に依頼するよりも安い

 やるなら徹底的に費用の削減!

  データが3000件以上あり、大変な作業なため、OBさんは死にかけてました。


 ところで、データベースの簡単な使い方を覚えたので、使わないのは勿体ない。
 そこで、Web検索ができたら便利な物を考えてみた。
 最初に思いついたのが商品名の検索だった。
 総務の人間は商品知識がない。商品の数が少なければ問題はないが、
商品の種類はハンパでないため、コードブックを見てもわからない。
  しかし、営業事務もやらないといけない。

 そこで、商品名の一部を入力しただけで、商品名と商品コードが検索できる
システムをと思いついた。
  早速、AS400の中に入っている商品マスターをパソコンに落とし込んだ。
  データを加工してから、PostgreSQLに格納した。
  システム自体は、単純だったので、すぐに構築できた。

  最初は「AS400で、できるようにはならないか」と言っていた次長が、
「いざ使ったら便利やなぁ」と言ってきた。これこそ業務効率化!

 AS400だと難しいことでも、PostgreSQLでは簡単にできるものが多いのだ!!

本当はAS400でも実は可能
初版を書いた時は、AS400でSQL文は使えないとばかり思っていたが、
後で調べると、SQL文をRPG言語に使ったりする事ができるのがわかった。
しかし、うちの会社の場合、SQL開発キットがないため、購入する必要があり
まだ、導入はされていない。

 うちの会社の基幹業務にパソコンシステムが導入される日が来るかもしれない。
その時は間違いなくPostgreSQLを活用だと思う。
 AS400から移植となると、道程は長いけど、面白いと思う。

  頑張り次第で、数百万円のシステムも自力で構築できます。
  オープンソースの偉大さに感謝に尽きます!!


その後のPostgreSQLについて

 PostgreSQLは、無償という手軽に導入できる事から 少しづつ社内での利用が増えていきました。
その後のPostgreSQL導入と、システム奮闘記の記事
その11 PostgreSQLとMS-Accessの連動の話
PostgreSQLとMS-Accessとの連動までの長い道程
その13 PostgreSQLのラージオブジェクトを利用した話。
文書管理システム
その29 ネット販売システムのデータベースにPostgreSQLを活用。
ネット販売システムの大改装
その30 PostgreSQLを利用した月間予定表。
みんなのカレンダー
その60 PostgreSQLのお勉強・その1
PostgreSQL:トランザクション、ロック機能、VACUUMって何?
その63 PostgreSQLのお勉強・その2
PostgreSQLのWALって何? ログ、PITR、障害時のデータ復旧の話


最後に 外注という方向を引っくり返して自社開発する方向にしました。 実は、自社開発した時点では気が付かなかった事ですが、 これが、うちの会社のシステム構築に対する考えが変わる分岐点でした。 その後、PostgreSQLを使って、いくつかの検索システムなどを構築したため 今まで無条件に「外注」という発想が、私が「自力で構築可能」というと、 「自社開発でいこう」という発想に変わりました。 もし、この時、業務命令に従って外注していたら、オープンソースの メリットを享受できなかった上、私は信頼されないままでいたと思います。 もしかすると、システム奮闘記も誕生していなかったと思います。 そう考えると、これは分岐点だったなぁと思ったりします。

次章:セキュリティーてんやわんやを読む
前章:ネット販売システム構築を読む
目次:Linux、オープンソースで「システム奮闘記」に戻る