minimize

事業拡大のため、新しい仲間を募集しています。
→詳しくはこちら

ここは、僕がOracleを使いたくない理由をどんどん挙げていこうというコーナーです(笑)。
とはいっても僕は実際現場ではOracleを使う羽目になっているので
実際に使ってみて駄目だと感じた点について紹介していきます。

新しく書いたものが「上」になるように並べていきます。

PreparedStatement で CHAR 型を使うとき

Oracle の JDBC でも当然 PreparedStatement は使えます。

SELECT * FROM XXX WHERE NAME=?

のように、? を使ったバインド変数によるSQL文発行ができます。
ところが、この機能にとんでもないバグがあります。

NAMEカラムが CHAR(10) だったとしましょう。

PreparedStatement stmt = conn.preparedStatement("SELECT * FROM XXX WHERE NAME=?");
stmt.setString(1, "naoki");
stmt.executeQuery();

このコードは、正常に動きません。
何が悪いか。
正しくは、以下のようにしなければなりません。

PreparedStatement stmt = conn.preparedStatement("SELECT * FROM XXX WHERE NAME=?");
stmt.setString(1, "naoki     ");
stmt.executeQuery();

…信じられますか?わざわざスペースで埋めなければならないのです。
これはコードを汚すだけでなく、DBのカラム長が変わったら
プログラムを書き換えなければならない事を意味します。

こんな腐った実装を何年も放置しているOracle。
やはり「JavaからOracleは使うな」と言わざるを得ないでしょう。

ライセンス

もちろんOracleはフリーソフトウェアではありませんから
ライセンスが無いと使えません。
それは別にいいのですが、クライアントまで動かないというのは納得いきません。

多くの開発現場では開発者がクライアントライセンスを持たせてもらえません。
それはつまり、データベースサーバに直接ログインしてSQL*Plusを使わないと
データベースにアクセスできないということを意味するのです。

ちなみにJDBCドライバはライセンス無しでも動きますが
その代償としてメチャクチャ速度が遅いです。

Oracleがどんな言い訳をしようと、僕は以下のことを断言できます。
JDBCドライバが遅いのは、Oracleがわざとそうしているのです。
なぜなら、JDBCドライバはライセンスの無い人でも使えるからです。

SQL*Plus

Oracleには標準でSQL*PlusというSQLクライアントが付属しています。
使ったことある人はわかると思いますが、使いにくいったらありゃしないです。
しかも、Oracle信者は頑なにこの不便なアプリを使おうとします。
それがどれだけ非効率な事か、誰か教えてあげて下さい。

接続に時間が掛かる

例えば、JDBC経由でConnectionを張ろうとした場合
環境にもよりますが 300~600ms 程度は掛かります。

「そんなもんプーリングすりゃいいだろ」って声も聞こえてきそうですが
それはOracle側の言い訳に過ぎません。
MySQLなら、プーリングなんかしなくても常に1ms以下の接続時間を提供してくれます。

テスト時など普通プーリングは使いません。
したがって、Oracleを使っているとDBを使ったテストに非常に時間が掛かることになります。

メモリを使い過ぎる

開発時には「ローカルでDBを起動させる」必要があります。
これを聞いて「え~っ!」と驚く人は、Oracle以外のDBを
自分でインストールしてみるといいでしょう。

それ位のことが出来ないと、開発の効率が上がりません。
データベースは何もOSのような特別な存在ではないのです。
Excelでデータを管理するかわりに使える程度の
単なる「データ格納箱」と考えましょう。

データベースの起動に何分も掛かったり、インスタンスを一つ追加するだけで
大量のリソース(メモリやディスクスペース)を浪費してしまうのを
「当たり前」だと思わないで下さい。
空きメモリが20MBもあれば、普通のデータベースはローカルで動かせるのです。

JDBCドライバがチープ

JavaからOracleデータベースにアクセスするには、
JDBCドライバを使わなければなりません。
しかし、このJDBCドライバの「質」といったらひどいったらありません。

バグはもちろんありますし、速度は遅い、対応していない機能は多い…
と、まるで「JavaからOracleは使うな」と言っているようなものです。

ちなみに、Java以外(例えばODBC)のドライバにも同様のことが言えます。
こうなっている本当の理由は ライセンス の項目を読んでみて下さい。

シェルとの連携が悪い

例えば、PerlからOracleを使うときにはDBIというパッケージを使いますが
このときにも様々な障害が待ち構えています。
今どき、ORACLE_HOME や NLS_LANG を環境変数で設定しておかないと動かないなんて
話にならないですよ、ホント。

エラーメッセージがわかりにくい

上の場面でもそうですが、全体的にエラーが発生したときのメッセージが
非常にわかりにくいです。「日本語訳が」というよりも「英語そのものが」です。
僕がOracle上でエラー発生したとき、
あの意味の無いエラーコード(ORA-XXXXX)をGoogleで検索して
似たような事象で困ってる人達の書き込みを探します。

なんでこんな面倒くさい事をしなければならないのでしょうか。
エラーメッセージに一言わかりやすい情報を入れてくれればいいだけなのに。
Oracleは、開発者の利便性の事など何一つ考えていないのです。

バグが多過ぎる

Oracleのバージョンにもよりますが、多くのOracle製品には山ほどバグが存在します。
その為、定期的にリリースされるパッチを当てなければまともに動かない事が多いのです。
なぜ、欠陥のある製品をそれほどまでに人々が使いたがるのか
僕にはわかりません。

制約が多い

例えば、OracleにはNVARCHARというデータ型があります。
これは文字コードなどを意識せず、純粋な「文字長」だけで文字列を格納するための仕組みです。

とても便利なのですが、限られた場面でしか使えないという制約があるのです。
PL/SQLには連想配列という、Javaで言うところのHashMap的な変数を使えるのですが
この型にはNVARCHARが使えません。
また、少なくともOracle8のときはPL/SQL内でNCLOB(BLOBのマルチバイト対応版)を
使うことが出来ませんでした。

これらは明らかに、Oracleの「機能未実装」なのですが
結局、NVARCHARやNCLOBを避けて使うことになってしまいます。
将来的にこういった事態になった場合、データ型を変更するというのは
あまりに危険だからです。
それだったら多少不便ですが安全に、初めからVARCHARを使った方が良いのです。

これをOracleは「仕様」だというかもしれませんが
僕から見れば明らかに「不具合」なのです。
しかしOracleはそれを直そうとしません。
こういった制約は、Oracleを使っていると日常茶飯事に発生します。

ダブルクォーテーションが使えない

Oracleにおいて、

INSERT INTO TABLE_A VALUES ('aaa');

はOKですが

INSERT INTO TABLE_A VALUES ("aaa");

はNGです。
はい、腐ってますね。
今どきこんなチープなSQLパーサ(解析)を採用してるDBなんて他にありますか?