連載:C# 3.0入門

最終回 LINQ to SQL/落ち穂拾い

株式会社ピーデー 川俣 晶
2008/12/05
Page1 Page2 Page3

SQL Serverのワナ

 話の枕として、なぜSQL Serverが「使えない」のかという話から今回は始めよう。

 まず、RDB(リレーショナル・データベース)という技術そのものが「設計変更に弱い」という致命的な欠陥を擁する、という話は過去に書いたので繰り返さない。

Database Expert「XMLデータベース開発方法論」

 ここで述べるのは、Microsoft SQL Serverという具体的な製品についての話である。

 さて、ここでは以下のような事例があると仮定して話を進めよう。

 A君はテキスト処理に興味があるC#プログラマーである。彼が扱う膨大な文書には決まった構造はなく、例外処理も多い。そのため、きっちりとしたスキーマを作成しなければ扱えないRDBとはあまり縁がなく、スキーマレスでXMLを使うことが多かった。

 あるとき、A君は以下のようなWebアプリケーションの開発を依頼された。

  • 10万件の「名前、日付、得点」のデータがある
  • 特定の名前や日付に対応する得点を検索して出力したい

 さて、ここでA君は考え込んだ。10万件のデータを含むXML文書であっても、解析にはそれほど時間はかからない。しかし、Webアプリケーションともなれば、立て続けにいくつもリクエストが来る可能性がある。リクエストが1回来るごとに、10万件のXML文書の解析を行っていたら、サーバの処理はあふれてしまうかもしれない。

 そこで、A君はもっと素早く処理できるデータベースの採用を検討することになる。ここで最初にA君の目に入るのは、SQL Serverということになる。Visual Studioのインストール時に、Express Editionという無償で使用できるSQL Serverの小規模版が同時にインストールできるからだ。Visual Studioのユーザーなら、興味はなくとも名前ぐらいは聞いたことがあるだろう。

 そこでA君は考えてみる。わずか3項目しかないシンプルなデータ構造で、データ量もわずか10万件だ。大規模な設計変更などあり得ないぐらいのシンプルさであるし、駄目ならつぶして作り直しても大した手間にはならない。設計変更に弱いというRDBの弱点は、この場合ほとんど関係ないだろう。逆に、正しく使えばデータの安全性は高まるし、性能も上がりそうである。

 そう……。ちょっとデータを入れておくだけの用途なら、RDBの弱点は必ずしも弱点ではないのだ。そこで、A君はSQL Server Express Editionの採用を決断して開発に着手する。

 ところが、A君は即座に自分の無力さを痛感することになる。

 SQL Serverの世界は、それ自体が1つの独立した世界を構成するほどに大きい。膨大なドキュメントがあって、かつ、それらは部外者には容易に読めない言葉で書かれている。どれほどC#の経験があっても、それだけではSQL Serverには歯が立たないのだ。しかも、SQL Serverはプロ用のツールとして進化してきた関係上、複雑で高度な機能が大量にそろっている。そのような前提で設計されている以上、機能制限版のExpress Editionであっても、決して素人に分かりやすくはない。

 A君はドキュメントの量と質のダブルパンチに打ちのめされつつ、ようやく初心者向けのチュートリアルにたどり着くことになる。

 そして、A君はようやくSQL Server Management StudioやVisual Studioにビルドインされたサーバ・エクスプローラを使って、手動でデータベースの作成や管理ができるようになる。テーブルを作成し、いくつかのテスト・データを入力するぐらいのことは、何とか達成できるだろう。

 ここで、A君はようやくホッとすることができる。なぜなら、データベースさえ用意できれば、そこから先はA君がよく知っているC#プログラミングでデータベースを操作できるからだ。

 だが、A君の前にはさらなる絶望が待ちかまえている。なぜなら、C#プログラムからデータベースを操作するというのは、実はC#プログラミングではないからだ。C#とはまったく別の言語である問い合わせ言語「SQL」をC#プログラム中に埋め込み、それを実行させる必要があるのだ。

 A君はまったく新しいSQLという言語を見よう見まねで書き始める。そして、テスト・プログラムがやっと完成し、コンパイルも通るようになった。しかし、それを実行してもエラーが出て動作しない。SQLで書かれたクエリは、C#コンパイラから見れば単なる文字列でしかないので、コンパイル時には一切内容が検証されず、構文エラーが検出されるのは、実行時まで遅延される。

 しかも、A君にはエラー・メッセージの内容が理解できない。エラー・メッセージの意味を理解するためには、しばしばSQLやデータベースに関する広範囲の基礎知識が必要とされるが、チュートリアルをかじった程度のA君にそれだけの知識があろうはずもない。エラーの原因が分からねば、コードを直しようがない。

 絶望したA君は、もう2度とSQL Serverなど使うものかと思いながら、それまで書いたコードを破棄して、手慣れたXMLを使ってコードを書き始めることになる。

LINQ to SQLという突破口

 以上は、筆者の過去のいくつかの経験を誇張してまとめ直したものである。ただし、筆者の場合、A君よりはSQL Serverについての利用経験や知識がある。例えば、SQL Serverのデータベースを参照するデモ・プログラムなどは、昔から時々作成している。だから、筆者はA君ほど絶望はしていない。

 しかし、使おうとすると膨大なドキュメントの迷宮の中に迷いやすいというデメリットがあると感じるのは事実である。SQL Serverとはそれ専門で扱っている技術者には何ということもない当たり前の存在なのだろうが、たまに少しだけ使おうとする技術者にはハードルが高すぎる感がある。

 ……とこれまでは思っていた。

 しかし、この記事を書くために「LINQ to SQL」を試したところ、そのような認識がすでに過去のものであったことを思い知らされた。Visual Studio 2008とC# 3.0そしてLINQを使えば、A君は絶望する必要はなかったのだ。それどころか、ちょっとしたデータの保管場所として、SQL Serverを気楽に使用できるほど手軽になったといってもよい。

 なぜそこまでいえるのか。その理由の一部はLINQ to SQLにあるのだが、それは理由のすべてではない。むしろ、LINQ to SQLを成立させるために実装された「O/Rマッピング」こそが、C#プログラマーにとってのSQL Serverのハードルを劇的に下げる効能を持つといった方が正しいだろう。

 マイクロソフトのドキュメントでは「O/Rデザイナ」という用語は使われているが、O/Rマッピングという用語は使われていない。しかし、ここでは説明の便宜上、O/Rマッピングという言葉を使うことにする。

 では、O/Rマッピングとは何だろうか。これはRDBとオブジェクトの橋渡しを行う機能であり、実際にデータが格納されているのはRDBであるにもかかわらず、プログラマーはそれをC#のオブジェクトとして扱えるのである。つまり、プログラマーはSQLの構文を知らずとも、オブジェクトの使い方だけ知っていればコーディング可能となるわけである。

 しかし、O/Rマッピングさえ実現できればそれでいいという話ではない。例えば、任意の設計を行ったクラスをRDBに格納するためにマッピングを行う技術も世の中には存在する。そのような仕掛けがあれば、RDBに関する知識を完全に排除して開発を行うことができて効率が上がりそうだが、実際は必ずしもそうではない。

 なぜなら、オブジェクト指向にとって都合のよい構造が、RDBにとっても都合がよいとは限らないからだ。効率的なクエリを実行するためには、どうしてもRDBにとって効率のよいデータベース設計を行う必要がある。そして、効率的なクエリの必要がなければ、最初からRDBを持ち出す必要がない以上、それはたいていの場合必須の要求となる。

 LINQ to SQLが持つO/Rマッピングは、これとは逆の方向でマッピングを行う。つまり、既存のRDBのデータベースに対して、それをオブジェクト経由でアクセスするレイヤを生成してくれるのである。これは万能ではないが、あらかじめ設計され、構築されたRDBを検索し、更新するようなプログラムなら、C#とマッピング・オブジェクトの知識だけで記述できる。SQLの細かい構文を学ばずとも、コーディング可能となるのだ。

 もし、それだけでは効率的なクエリが実現できない場合は、後述の方法で実際にどのようなSQLのクエリが生成されているかを調べ、O/Rマッピングを使わずに直接SQL文を実行させることもできる。LINQ to SQLの世界にあるO/Rマッピングは、世界を支える唯一の支柱ではなく、いくつもの支柱の1つにすぎない。昇りやすい支柱が1つ増えたことで、気軽に訪問しやすくなったというだけの話である。

 

 INDEX
  C# 3.0入門
  最終回 LINQ to SQL/落ち穂拾い
  1.SQL Serverのワナ/LINQ to SQLという突破口
    2.LINQ to SQLのサンプル/LINQ to SQLとメソッド構文/まとめ
    3.部分メソッド定義/C# 3.0コンパイラ/連載の終わりに
 
インデックス・ページヘ  「C# 3.0入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間