SQLer 生島勘富 のブログ

RDB・SQLの話題を中心に情報発信をしています。

SQLとはなんぞや?

 SQLとはなんぞや?SQLができた当時は、COBOLのロジックを「なんとか簡単にできないか?」ということが主な目的でしたが、オブジェクト指向言語SQLがない状態を考えてみましょう。

例えばJOINを書いてみる。

以下のSQL文をオブジェクト指向言語っぽく書いてみましょう。あくまでイメージです。

SELECT *
FROM 社員
  INNER JOIN 部課
    ON 社員.部課ID = 部課.ID

 ※ retSetは社員のカラムにと部課名を合わせたもので、部課テーブルはIDがユニークとします。

■ネスティッドループ

for(Object row社員 : 社員){
  for(Object row部課 : 部課){
    if(row社員.部課ID == row部課.ID){
      retSet.add(row社員);  // LEFT JOIN のときには for の外に
      retSet.部課名 = row部課.部課名;
    }
  }
}

return retSet;

メソッドを作ってこんな感じにするとは思うが……。

for(Object row社員 : 社員){
  row部課 = 部課.seek(row社員.部課ID);
  if(row部課 != null){
    retSet.add(row社員);
    retSet.部課名 = row部課.部課名;
  }
}

return retSet;

■ソートマージジョイン

Object set社員 = 社員.sort(部課ID);
Object set部課 = 部課.sort(ID);

Object row部課 = set部課.current();

for(Object row社員 : set社員){
  while(row社員.部課ID > row部課.ID){
    row部課 = set部課.nextRow();
  }
  if(row社員.部課ID == row部課.ID){
    retSet.add(row社員);  // LEFT JOIN のときにはifの外に
    retSet.部課名 = row部課.部課名;
  }
}

return retSet;

■ハッシュジョイン

Object setHashed部課 = 部課.hash(ID);

for(Object row社員 : 社員){
  Object set部課 = setHashed部課.seek(row社員.部課ID.hash());
  for(Object row部課 : set部課){
    if(row社員.部課ID == row部課.ID){
      retSet.add(row社員);  // LEFT JOIN のときには for の外に
      retSet.部課名 = row部課.部課名;
    }
  }
}

return retSet;

 ※ 元のSQLにOreder By が入ってない。そのため、ロジックを追えば分かるけれど、ネスティッドループとソートマージジョインとでは結果のレコード順は違うことになる。SQLの解説書に「Oreder Byがないときには結果の順序は保証されない」と書かれているのはそのためです。

なぜ、SQLができたか。

 ●メモリーとデータ量の違い、データの分散度合いの違いなどによって最適なアルゴリズムは違う。
 ●メインループは「社員」テーブルではなく「部課」テーブルを使った方が良いかも知れない。
 ●今日速くても、一ヶ月後のデータ量では遅いかも知れない。
 ●結合のアルゴリズムはシステムの至る所で使うので、一々、ロジックを変えるのは大変だ。
 ●アルゴリズムプログラマ依存していては良いシステムはできないな。

 なんとか、抽象化できないものか……。

 「よし、アルゴリズムを書かずに、欲しいものを書くだけで結果が得られる言語を作ろう」
 「ユーザにも分かりやすくするために英語に近い表記を目指すぞ!」← これが最大の間違い(苦笑)
 「これをSEQUEL (Structured English Query Language)と名付けよう」

 という経緯で出来たものにトランザクションの一貫性など、主にエンタープライズ領域に特化した進化を遂げて、現在に至っています。

SQLを使わないという選択肢。

 RDBMSは、COBOLで作っても良いし(昔はCOBOL製があったらしい)、CassandraをラップしてJavaで作っても良い。SQL文というスクリプトを受けて、アルゴリズムを自動生成してSQL文で指定された結果を返すのがRDBMSです。SQLは魔法でも何でもなく、内部的には普通にアルゴリズムがあり、ループしながらデータを取っています。

 大昔はシステム開発といえばOSから作ったものです。汎用OSになれば、特化した処理には不要なものがたくさん含まれていて、メモリーも不必要に消費し無駄な処理も行われますから、ハードが滅茶苦茶高価だった頃は専用OSの方が効率的だったわけです。

 RDBMSユーザーインターフェースを持たずデータを扱うということに特化していますが、データを扱うことに対しては汎用化しています。その分、シンプルなデータアクセスに比べ非常に遅いですから、車輪の再開発になったとしても、どうしても特化したデータベース(リレーショナルに限らず)が必要ならば作ればよいのです。例えば、Googleはどうしても必要だから独自で作っていますね。それは何の問題もないのです。

 しかし、アルゴリズムを別立てで作りながら、肝心の部分でSQLを使うというのは理論的に何のメリットもない。理論的にメリットがないものを採用する、その議論の行き着く先は「できない人に合わせる」以外にないのです。

 ちょうどこんな感じ。

 分かって居る人から見れば、何がしたいのかは分からない。

 車輪の再開発をするならば、元の車輪を使ったらダメなんですわ。