ちょっと硬派なコンピュータフリークのBlogです。

カスタム検索

2009-04-09

バイナリvsテキストに関するオトコの見解

dankogai氏のブログでバイナリデータとテキストデータの違いについて論じられているので、オトコ的にも少しコメントを加えてみたい。

バイナリーとテキストの本当の違い、それは「終わり」にある。
・「終わり」がはじめにわかるのが、バイナリー。
・「終わり」が来るまで「終わらない」のが、テキスト。
本質的な違いは、これだけである。

果たしてそうだろうか。

例えばテキストデータとバイナリデータを用いて、データをファイルに記録する場合を考えよう。バイナリデータは予め構造が決まっているのに対して、テキストデータは任意の順番でデータが並んでいる可能性がある。つまり、テキストデータにはコンテキストが存在するのである。

バイナリデータがどのような構造になっているかは、プログラムだけが知っているという場合が多い。もしくは仕様書に書いてあるとか。バイナリデータそのものはデータの構造について、情報を持っていないのである。典型的なバイナリデータとして思い浮かぶのは、IPパケットのヘッダとかSCSIコマンドとか画像ファイルとか動画ファイルとか。このうち個人的に慣れ親しんでいる(?)のはSCSIコマンドなのでSCSIコマンドを例に挙げてみると、例えばINQUIRYコマンド(SCSIデバイスを認識するためにホスト等が発行するコマンド)は次のようなフォーマットになっている。(The Linux SCSI programming HOWTOより抜粋。)

Table 44: INQUIRY Command
+=====-========-========-========-========-========-========-========-========+
|  Bit|   7    |   6    |   5    |   4    |   3    |   2    |   1    |   0    |
|Byte |        |        |        |        |        |        |        |        |
|=====+=======================================================================|
| 0   |                           Operation Code (12h)                        |
|-----+-----------------------------------------------------------------------|
| 1   | Logical Unit Number      |                  Reserved         |  EVPD  |
|-----+-----------------------------------------------------------------------|
| 2   |                           Page Code                                   |
|-----+-----------------------------------------------------------------------|
| 3   |                           Reserved                                    |
|-----+-----------------------------------------------------------------------|
| 4   |                           Allocation Length                           |
|-----+-----------------------------------------------------------------------|
| 5   |                           Control                                     |
+=============================================================================+

初めの1バイトはOPコードと呼ばれるものであり、操作の種類(この場合はINQUIRY = 0x12)を示すものであり、その次のオクテットでは上位3ビットがLUN、最下位ビットがEVPD、その次のオクテットがPage Code・・・というように、SCSIの仕様で規定されているのである。つまり、どの位置にどんな情報が書かれているかというのが最初から決まっている。もちろん可変長データの場合には、データ長を書いているフィールドがヘッダにあり、それに実際のデータ(ペイロード)が続く。

一方で、テキストデータはそれ自身が構造を持っている場合が多いし、可読文字を用いて記述されている。データの文法は予め定められてはいるが、文法に従えば記述方法は自由である。すなわち、このことは次のような特性を表すのである。
  • 人間が見てデータの意味を理解出来る。
  • データにはコンテキストが存在する。
  • データを読み込んで構文解析するまでプログラムは内容を理解出来ない。
ということである。例えばUNIXの設定ファイルなどを考えて見よう。Linuxの/etc/sysctl.confは、各行ごとに「token = value」という内容が書かれてあり、tokenがどのように並んでいるか、またはどのようなtokenが記述されているかは設定によってマチマチである。sysctl.confを記述する人は、任意の順番で必要なtokenだけを書くということである。さらに、そのtokenがなぜ設定されているかを示すためにコメントを書くことがあるだろう。コメント行はシャープ記号「#」またはセミコロン「;」で始まり、行の終端文字「\n」で終わる。そして、レイアウトを見易くするため、空行や空白文字を活用することだろう。つまり、テキストデータでは文法は規定されているが、どこに何が書いてあるかということが最初から規定されているわけではないのである。

さらに我々が慣れ親しんでいるテキストデータの代表格としては、HTMLなどのマークアップ言語があるだろう。マークアップ言語ではタグが入れ子になるので、同じテキストでもどのタグに囲まれているかということで意味合いが異なる。そして、HTMLで何を表現するかは自由であり、本当にどこに何が書いてあるかということは、HTMLファイルを構文解析するまでは見当も付かないのである。「コンテキスト(文脈)が存在するデータ」の例として、よりわかり易いのではないだろうか。

プログラマにとって最も重要なテキストデータといえば、やはりソースコードである。日々書きまくり、格闘し、愛して止まないソースコードもやはり、コンテキストを持ったテキストデータなのである。ソースコードの構文解析を担当するのはコンパイラ(またはインタプリタ)の仕事である。コンパイラが処理出来るルール=言語仕様に従ってソースコードを書かないとエラーになるが、言語仕様に従っている限り、プログラマは自由にそのプログラムを表現出来るのである。(しかし時にプログラマはコーディングスタイルに関して激論したりするのだが。)

さて、データについて論じるならば、やはりデータベースについても考察しなければならない。

データベースでは、SQL文はテキストデータであり、実際にテーブルに格納されているデータはバイナリデータである。(MySQLのCSVストレージエンジンのような異端的なものは除くが。)SQL文は可読性が高く、柔軟性が高く、利用場面に応じてプログラムが自動生成し易いという特性を持っている。一方で、テーブルに格納されているデータはバイナリデータであり、データベースが高速に扱いやすいようになっている。データがBツリーインデックスなどを用いて構造化されてはいるという見方も出来るが、ツリーを構成する各ページの内部構造にはテキストデータのような自由度はなく、上で挙げた「token = value」の例のように任意の順番でデータが並んでいるということはない。

このように、テキストデータは構造化されたデータであるので、人間にとって加工しやすく、理解し易く、柔軟性に富んでいるが、その分構文解析をしなければいけないので処理のオーバーヘッドは大きい。大量のデータを処理しなければいけないような場合は、処理能力が求められるので、テキストデータを用いることが難しい場合もあるだろう。一方で、バイナリデータは高速に処理出来る反面、dankogai氏が言うようにバイナリデータを扱う際は構造の問題が非常にやっかいである。

バイナリデータの高速性とテキストデータの扱いやすさという特性を、いいとこ取りにする方法はないか?ということを考えたとき、多くの人々が利用するのがデータベースを初めとするミドルウェアであろう。データベースはテーブルの構造を柔軟に変更することが出来るし、クライアントからの要求に従ってテキストデータで入出力するのはお手の物である。データをインデックスや関係モデルで構造化し、高速に処理することが出来る。データベースには様々な知恵が詰め込まれており、データを高速かつ安全に、そしてインテリジェントに処理することが可能なのである。現在、Webサイトのバックエンドにデータベースが不可欠になっているのは、そのようなデータベースの「いいとこ取り」の特性が広く認められているからであろう。データベースはデータを蓄積する様々なアプリケーションで活用できる。Webだけでなく様々な分野、例えば今やiPhoneやAndroidのような電話機にも搭載されているのである。

とりあえず、これからプログラムを開発する時にデータをどこに格納しようか?と迷ったならば、まずはデータベースを使え!!と俺は言いたい。自分でファイルフォーマットを規定するのも結構であるが、そのようなことは手間の無駄である。データベースには先人の知恵が詰め込まれており、プログラマからデータの格納や検索に関する様々な手間を取り去ってくれる。データベースを使えば後悔はしないだろう。

0 コメント:

コメントを投稿