PREPARATION
受験対策

オススメ!OSS-DB情報

第5回 データ型

データベースに限らず、コンピュータでは様々なデータを扱うことができます。
データは、例えば、数値、文字、日時、といった種別に分類できます。
数値データは、さらに整数、浮動小数点数、十進数などに細分類されます。
このような分類は、コンピュータによる処理の都合上のものですが、SQLを含め、多くの言語では、それぞれのデータがどのデータ型なのかを明示的に宣言する必要があります(型の宣言を必要とせず、自動的に柔軟な判断をする言語もあります)。
例えば、"123"というデータがあったとき、これが整数なのか、浮動小数点数なのか、はたまた(数字が並んでいるだけの)文字列なのか、人間がプログラム上で指定しなければ、コンピュータのプログラムは必ずしも期待通りの処理をしてくれるとは限りません。

データ型の名前はプログラム言語によって異なります。
SQL言語は、文法やコマンドだけでなく、データ型についても標準化されていますが、細かいところでRDBMSの種類による違いがありますので、それぞれのデータベースについてデータ型を注意してみておく必要があります。

SQLでは、表(テーブル)の列について、データの型を指定します。
PostgreSQLで利用できるデータ型については、マニュアルの以下のページに記述されています。
http://www.postgresql.jp/document/current/html/datatype.html
非常に多くのデータ型があることに驚く人も多いでしょう。標準SQLで規定されているものもあれば、規定されていないものもあります。標準SQLで規定されているものは、他のほとんどのRDBMSでもほぼ同じように利用できますが、RDBMSによって実装が違う場合があるので、まったく同じように使えるとは限りません。
標準SQLで規定されていないものの多くは、PostgreSQL独自の機能拡張なので、他のRDBMSでは利用できません。

数値を表すのに通常使われるデータ型には、INTEGER(整数)、REAL(浮動小数点)、DOUBLE PRECISION(倍精度浮動小数点)、NUMERIC(十進数)などがあります。
PostgreSQLでは、INTEGERは4バイト、REALとDOUBLE PRECISIONはプロセッサ(CPU)で規定された単精度および倍精度の小数、NUMERICは1000桁まで(事実上無制限)です。
他のRDBMSには、NUMERICの桁数の制限の小さなもの、INTEGER、REAL、DOUBLE PRECISIONが内部的に十進数に変換される(結果として、精度や桁数の制限が異なる、また数値演算時に型変換のオーバーヘッドが発生する)ものもあります。
従って、同じデータ型を使っていても、RDBMSの種類によって、同じデータが格納できなかったり、数値演算の結果が異なる、ということもあります。

文字列を表すのに通常使われるデータ型には、CHAR(固定長)、VARCHAR(可変長)、TEXT(可変長、長さ無制限)などがあります。
CHARとVARCHARはどのRDBMSでも利用できますが、その最大サイズ、および、長さをバイト数と文字数のどちらで指定するか、はRDBMSの種類によって違います。
例えば VARCHAR(100)という型の列に日本語の文字列を入れるとき、そこに何文字まで格納できるかは、RDBMSの種類とエンコーディング方式に依存します。
PostgreSQLではCHAR、VARCHARとも文字数で長さを指定しますから、VARCHAR(100)の列には、エンコーディング方式の如何に関わらず100文字まで格納できます。
Oracleなどでは長さをバイト数で指定するのがデフォルトとなっていますから、同じ型の列に格納できるのは、エンコーディングが EUC_JP なら50文字まで、UTF8なら33文字までになります。
TEXTは可変長文字列で、定義時に最大長を指定する必要がないので、利便性が高いのが特長ですが、標準SQLでは規定されておらず、PostgreSQLやMySQLなど一部のRDBMSでしか使えないことに注意してください。

日時を表すデータ型には、DATE(日付のみ)、TIME(時刻のみ)、TIMESTAMP(日付+時刻)などがあります。
これらのデータ型は多くのRDBMSで共通ですが、Oracleでは実装が異なり、DATEは日付+時刻で、またTIMEがありません。同じDATEでもデータの内容が違うため、同じSQL文では動作が異なります。つまり、同じ動作をさせるためにはSQLを変える必要があります。
PostgreSQLなどではDATEに時刻が入っていないので、例えば date_col がDATE型の列であるとして、
WHERE data_col= '2012-04-01'
のようなWHERE句によって、日付が2012年4月1日のデータを抽出できますが、OracleのようにDATEに時刻が入っている場合は、
WHERE trunc(data_col) = '2012-04-01'
のような記述にする必要があります。
なお、trunc は切り捨て演算を実行する関数で、主に浮動小数点の小数点以下を切り捨てるのに使いますが、OracleではDATE型のデータを渡して、時刻部分を切り捨てるのにも使います。PostgreSQLなどではDATE型のデータを trunc 関数に渡すとエラーになります。

解説:松田神一

応募者全員プレゼント!
オープンソース データベース標準教科書 -PostgreSQL-