2008/12/13

記録

COBOLでは、ファイルは常にレコードの形式になっていることを想定している。すなわち、それぞれ形式の違う複数の項目、例えば顧客番号とか名前とか、そういった項目が複数個集まってレコードという固定長のデータ形式を作り、それが複数個集まって一つのファイルになるという考え方をする。また、汎用機ではOSのレベルでそういう考え方をしているらしい。

その考え方はリレーショナル型データベースの関係表でも同じで、あらかじめ決められた複数の項目が集まってタプルを作り、そのタプルが複数個集まって関係表を形成するという考え方をする。ただし、DBの場合は数学的バックグラウンドがあることから、COBOLのファイルやExcelの表とは根本的に異なるものと見なされる。

こういった表形式は、人間にとって直感的に理解しやすい。それに、実務で使用される帳票は、多少複雑な部分があるとはいえ、基本的には全て表形式である。こういった形式の帳票が作られるようになったのがいつの頃からなのか、実務における情報のやりとりは全て帳票に依るというルールが制定されたのがいつの頃なのか、俺は詳しいことは知らない。しかし、よほど特殊な業界を除いては、世の中のほとんど全ての企業で表形式の帳票を作って商売を行っている事を考えると、おそらくこれは人間の、世界に対する根本的な認識の仕方に基づくものなのだろう。

だからだと思うが、コンピュータでは大抵のデータは固定長のレコード形式をしていることが多い。少なくとも、「お金になる」業務データはことごとくそういう形式になっていると言っていい。(なお、固定長のレコード形式がコンピュータにとって扱いやすいからそういう形式になっているというのは、多分間違いだろう。固定長のレコード形式を扱いやすいようにコンピュータが作られていると考えるべきである。)

大抵の業務データが固定長のレコード形式をしていると言うことは、トラブル時には大抵、固定長レコード形式のデータを解析してトラブルシュートを行うということを意味している。プログラムが直接ファイルをいじるような場合であれ、DBから抜いてきたデータを解析するような場合であれ、大抵SEが目にするのは固定長レコード形式のファイルである。だから、このファイルのフォーマットを間違えると、トラブル対応時に酷い目に遭うことがある。

ということで、前置きが長くなったが、プログラムで取り扱うファイルを設計する上で考慮するべき事項について、俺なりにまとめておいてみようと思う。

1.固定長のレコード形式にする。

そもそも、可変長はありえない。可変長にしてしまったら、一体どうやってデータを分析しろと言うのか。もちろん、ビューアを作れば見て見れないことも無いはずである。しかし、トラブル時にブチ切れてるお客や動かないマシン、役に立たない上司を前にして解析用のプログラムを作れと言うのか。そもそも、いつ何時でも開発用ソフトが使える状態にあるとは限らない。そうなると、メモ帳(一本指打法を墨守するお客のマシンには、当然の事ながらまともなテキストエディタなんて入っているはずもない)でファイルを開いて、指折り数えて改行を入れていくと言うことをしなければならなくなる。

そんなまどろっこしい事をしている間にも騒ぎは大きくなり、じきに灰皿の灰やコップの水が宙を飛び交うようになる。というか、頭の上に降り注ぐようになる。そんな状況に陥ってしまったら、物理的にクビが切られる前にトンズラするしかない。まぁ、そういう背中にナイフを突きつけられるような状況に陥ることはなかなか無いが、それでも未然に防止できるならそれに越したことはない。

また、各項目が可変長のみならず、ファイル中のレコード形式が一定で無かったりすると、おかしなデータを見つけるのに時間がかかったり、あるいは見つけられなかったりすることがある。おかしなデータというものは、周囲のデータと比べて明らかに入っている値が違うとか、英数字しか入らないところに漢字があるとか、データのあるべき位置が空白になってるとか、連番になっているものが途中で乱れているとか、そういったことがきっかけで見つかることが多い。だから、そういう見分け方をするためには是非ともファイル中のレコード形式は一定でなければならないのだ。そうでなければ見つかるものも見つからなくなる。

2.テキスト形式にする

裸のWindows XPにMS-Officeと大量のセキュリティソフトを入れただけの、インターネットに接続できないPCを思い浮かべてもらいたい。でもって時刻は深夜2時。深夜3時までにマシンから抜いてきた大量のデータを解析して、報告書をまとめてお客に報告しなければならないとする。

そういった状況下で、もし与えられたデータが全部バイナリだったとしたらどうだろうか。

こういう会話がなされることが推定される。

俺 「このデータを私のPCにコピーしてよろしいでしょうか? 私が普段使っているPCであれば、このデータを解析するのに必要なソフトが入っていますので・・・」
客 「はぁ? 本番のデータを開発用のPCに持って行っていい訳がないだろうが。馬鹿野郎。ここでやれ。それとも何か、まさか逃げる訳じゃないだろうな? あぁ?」
俺 「いえ、そういうわけでは無いのですが・・・その・・・このPCには、このデータを見るのに必要なソフトが無いので・・・。では、データを持って行けないのなら、私のPCから必要なソフトを持ってきてもよろしいでしょうか? それであれば・・・」
客 「はぁ? 馬鹿かテメェは? 勝手に変なソフトを入れて良いいいわけねぇだろうが。とにかく、ガタガタ言わずに今すぐ仕事しろ。アホが」

こういう不毛な問答をしている間にも時間は刻一刻と経過していき、一方、俺はどうすることもできずに、ただただ針のムシロに座り続けるしかない。これでは、換えの胃袋が何枚あったっても足りないし、いかに鋼鉄の神経でもたちどころにすり切れてしまう。

だから、とにかくデータはテキスト形式とするべきである。それも、できればShift-JISにしておくべきである。そうすれば、少なくとも全く手も足も出ないという状況は避けられるはずである。固定長のテキストデータであれば、Excelで開いてカラムごとに分割することができ、そうすれば少なくともなにがしかの結果をまとめることができる。しかし、中にバイナリのデータが含まれているとそういうことができなくなる。

しかし、時にはシステム的にバイナリのデータを取り扱わざるを得ない場合もあるだろう。そういった場合は、バイナリの部分だけを別の場所(ファイルを分けるか、別のテーブルに入れるか)した方が良い。DBから抜いてくるのであれば、バイナリの部分は避けてテキストの部分だけを抽出するようにした方が良い。そうでないと酷い目に遭うから。

あと、データ中にはできれば日本語は含まれていない方が良い。どうしても日本語のデータが入らざるを得ないのであれば、Shift-JISにするべきである。EUCは最悪である。言うまでもないことだが、いつ何時でもエンコードを自在に変換できるとは限らないからだ。

また、日本語が含まれている場合「レコードを固定長にする」というのが多義的となり、事態が複雑化する。すなわち、固定長というのを文字数で見て固定とするのか、バイト数で見て固定とするのかが異なってしまうのだ。Excelで固定長のデータをカラムに分ける場合、常にデータはShift-JISと見なされ、かつ、バイト単位で固定であるものとしてデータが区切られることになる。また、メモ帳などのエディタで開く場合も、バイト単位で固定長としておけばカラムがそろって見やすくなる。だから、データは必ずバイト単位で固定長として処理した方が良い。

もっとも、この文字数で固定長とするかバイト数で固定長とするのかはシステム全体の設計に関わる問題であるため、なかなか自由に選べるものではないのだが。例えばシステム内部で文字をUTF-16か何かで取り扱う場合は、当然の事ながら文字数で固定とすることとなり、それ以外に選択肢はなくなる。だからその場合は、メモ帳とExcelだけで戦う道は閉ざされる事となる。

3.レコードの末尾には改行コードを入れておく

今までの議論からも明らかなとおり、レコードの末尾に改行コードが入っていないと見づらい。レコード長がバイト単位で固定になっている場合は、エディタで開いて決まったところで改行を入れればいいのでそれ程大変ではないのだが、それでもデータ量が多い場合にはどうしようもなくなる。あらかじめ出力するデータに改行が入っていれば、いざというときに助かる。

挿入する改行コードはCR+LFにしておくと良い。どうせWindowsのPC上でファイルを開いて見るのだから。

なお、時にUNIXオタクの奴がデータをWindows上で解析することに対してケチを付ける事があるが、それはナンセンスである。大学の研究室での常識とやらをビジネスの現場に持ち込まれても困る。一般に、企業で使用されているコンピュータは、サーバはLinuxや商用UNIXであることが多いが、クライアントPCはことごとくWindowsである。業種によってはMacという可能性もあるが、少なくともクライアントPCがUnix系のOSである可能性は非常に低い。でもって、サーバマシンにはディスプレイやキーボードは接続されておらず、それどころか物理的に遠く離れたところに存在し、まともなディスプレイやキーボードが接続されているマシンは、クライアントのWindowsPCのみである。

そういう状況下で、データをシェルスクリプトで分析するだの、viで編集するだの言わないでもらいたい。よしんば、その方が作業時間が短くて済むのならそれでもいいが、しかし、最終的に分析した結果は体裁の整った表なりグラフなりにまとめて、報告書を書いて、それを印刷してお客の所に持って行かなければならないのだ。最後は結局ワープロソフト(一太郎でも何でも良いが少なくともTexではない)で清書するのだから、最初からPC上で仕事をしろ。というか、大概「Excelなんてwww」と言っている奴に限って、Excelの使い方を知らないものだ。

4.データ中にカンマやダブルクォーテーションを入れない

時に、データを固定長のレコード形式ではなくCSV形式で出力することもある。そうすると、文字数で固定だのバイト数で固定だのといった問題や、改行の問題などを回避できる可能性がある。また、Excel等の表計算ソフトに取り込む際に、桁数をいちいち指定する必要が無くなり、作業効率がよくなる。

だがその時、たまに罠に嵌められる事がある。それは、データ中にカンマやダブルクォーテーションといった、CSVファイルで使用される制御用の文字がデータに含まれている場合だ。そういう値が入っていると、CSVファイルを正しく開くことができなくなる。

システムの仕様上、そういった値も持たなければならないというのなら致し方がないのだが、しかし、あえて深い理由もなくカンマなどの文字を使うというのであれば、少し考え直すべきである。余り痛みを伴わずに別の文字で代替できるのなら、替えてみるという選択肢もあるのではないかと思う。

なお、CSVファイルを普通に表計算ソフトで開くと、数字や日付などの値を勝手に解釈してそれぞれの形式に変換して取り込んでしまうという、非常にお節介きわまりない機能が動いてしまう。一般に、桁がずれてるとか変な文字が入っているとか、そういった問題はExcelに変な加工をされると分からなくなってしまうため、データに余計な解釈を加えずに文字列のまま取り込むようにした方が良い。だから、CSVファイルであっても明示的にデータのインポートを行わなければならない。それを知らないと、トラブルがいつまでも解決しないという罠に嵌められる可能性がある。

5.同種の項目であれば桁数を揃える

たまに、金額を表す項目であるにもかかわらず、ある場所では6桁、別の場所では8桁、消費税は5けたなどと、桁数がバラバラになっている事がある。だが、そういう細かい違いはトラブルの元である。システムそのものを開発するときにもバグの温床となるし、トラブル対応時のテンパッているときなら尚のことである。似たような項目は同じ編集方法とするべきである。

同様に、データの桁数が足りない時に、余ったところに入れるパディングの値も、システム全体で統一するべきである。ある項目ではNULLで埋めて、別の項目では全角空白で埋めるなどということをやっていると、いつかは足下をすくわれることになる。できれば、数字/半角文字列/全角文字列で変えるのもやめた方が良い。左詰で余ったところには半角空白をいれる、ということで統一した方が良い。当然のことながら、バイト数を持たせて可変長にする、等というのは絶対にあり得ない。



以上の対策は、今具体的に俺が困っていることを羅列したものであって、全てを網羅しているなどと主張するものではないし、また、必ずしも正しいとも限らないと思う。だが、変な実装のシステムの保守をやらされて苦しんだ上で理解したことだから、それなりの価値はあるのではないかと思う。とりあえず、今度新規にシステムを構築する場合には、以上のような対策を取り込むようにしてみたいと思う。

0 件のコメント: