*大量データの一括処理:SQLiteによるリレーショナルデータベース入門 [#j5d40e47]

前回授業ではDNAデータベースを検索して、自分が必要とするデータを取り出し(検索・ダウンロード)、加工し(アラインメント)、目的とする解析(系統解析)を行った。アンケートでの結果「理解できた」という人が多かったのは、皆さんが、インターネットを使って何かを検索し、データを取り出すという作業に慣れているからだろう。

では、授業で使ったDNAデータベースやYahoo、Amazonなどのサイトで、キーワードを入力して検索をかけた時、どんなソフトウェアが働いて、データが取り出されているか想像したことはあるだろうか?DNAデータベースの場合、数1億件以上のデータ(配列にすると数百億!)という、ちょっと実感がわかないほど大量のデータが、インターネットを介して処理されていることになる。

自分の実験で沢山のデータを処理する場合も、データの量が多くなるほど目的のものを取り出すのが大変になってきて、1つ1つ手作業で処理するということは難しくなる。%%%そんなとき役に立ってくれるのが「データベース」だ。%%%先週使ったDNAデータベースでも、Yahooでも、Amazonでも、いずれも''リレーショナルデータベース''というシステムを利用することで、''塩基配列、生物情報、文献情報などのものすごく大量のデータから、一瞬にして必要な情報を検索し、抽出し、並び替える''という処理をおこなっている。この、

|SIZE(16):大量のデータの検索・抽出・並び替え|
と
|SIZE(16):複数のデータ(テーブル)を結合|

というのが、データベースには簡単にできて、テキストエディタやワープロには簡単にできないことだ。~
おそらく、今現在の時点でデータベースを使うことはあまりないだろうが、この技術を知っておくと、将来的にいろんな得をする場面に出会うことは間違い無い(あるいは、授業を聞いておくだけでも、楽をすることができるチャンスに気づくことができる)。さらに、自由に使えるようになれば、心と時間に余裕が生じるだろう。

せっかく情報処理を勉強するのだから、こういう便利な方法があることはぜひ知って欲しい。今日の授業の前半部分ではとにかく、データベースを使って簡単なデータ処理に挑戦してみる。

//今日の授業は普段よりも盛りだくさんだが、前半は%%%挑戦%%%、後半は%%%習得%%%という点に注意して、授業に集中してほしい。


**第15回授業の獲得目標:&worried; [#b9b462fd]
-''1. リレーショナルデータベース(SQLite)を使える環境を作る:FireFoxによるアドオンの使用''
-''2. SQLという言語を使って、データベースとお話しする''
--SQLiteを使って、情報の検索・抽出・並び替えを行う方法を習得する
-''3. データベースにおけるテーブルの概念を理解する''
-''4. SQLを用いて、複数のデータテーブルを連結して、必要なデータだけを抽出する方法に挑戦する''

**2つ以上のテーブル連結が必要な例と、エクセルによる操作に挑戦 [#c89a81e0]
まずは次のようなモデルケースを想定してみよう。
-''モデルケース''(自分が学校の先生になったことを想像してみる):
今手元に、国語、数学、英語の先生から提出された成績をまとめた書類がある。~
&ref(授業/H19/情報処理/13/成績集計表.doc);~
この成績表には学籍番号と成績がそれぞれ書かれている。これからあなたのクラスの学生全員の、成績の集計をしたい。生徒の名簿は、~
&ref(授業/H21/情報処理/13/名簿.doc);~
という名簿のファイルに、「''学籍番号、名前、よみがな''」が保存されている。~
さて、学生毎に選択している科目が違うのだが、3人の先生から集めた情報を1つ集計するにはどうすればいいだろうか?~
//(※この程度の数のデータなら、エクセルでもわりと簡単に集計できるが、今日勉強するSQLiteを使うと、この数百〜数千倍の規模のデータでも、簡単に処理できる)~
//&ref(授業/H22/情報処理/13/#13_2010_1.gif,50%);
-''エクセルを用いた演習''~
上のデータを開いて、それぞれのデータをExcelのカラム(列)にコピー・ペーストして、どうやれば良いか考え、やってみよう。
//--データがうまく準備できない場合は、次の4つのファイルを、右クリックしてダウンロードして使おう。~
//&ref(./meibo.txt);&ref(./kokugo.txt);&ref(./sugaku.txt);&ref(./eigo.txt);



**1. リレーショナルデータベース(SQLite)を使える環境を作る:FireFoxによるアドオンの使用⌣ [#vee37fe1]

データベースという言葉は、保存されたデータのまとまりそのものを指すことも、データを管理するシステムのことを指すこともある。この授業でも特に厳密な定義はしない。授業で使うのは、''リレーショナルデータベース''という''システム''(RDBS: Relational Data Base System)を無料で簡単に構築できるソフトウェア、''SQLite''だ。このソフトウェアを使って、実際のデータからデータベースを構築し、必要なデータを検索・抽出・並び替えすることを学ぶ。その過程で''SQL言語''という、データベースとお話するための言葉を使う。

一昨年までの授業では、自分のパソコンにフリーソフトウェア''SQLite''をインストールして、''コマンドライン''からデータベースを操作していた。~
ちょっとデモしてみるが、コマンドラインからの
-実行
-データの保存・利用

という点は、なかなか皆さんには馴染みの無いことらしく、あきらめてしまう人も多かったようだ。そこで昨年からは、いつも使っているFireFoxにデータベース利用機能のアドオンを追加して、SQLiteを利用することにする。

なお、皆さんが大学で使っているコンピュータにはAccessというデータベースソフトも入っているが、無料で、自分のパソコンでも使えるという点を重視して、フリーソフトウェアであるSQLiteを使うことにした。

***FireFoxでのSQLite Managerのインストール [#y239620f]
-FireFoxを立ち上げる
-FireFoxのメニューから「アドオン」をクリック~
&ref(./14-1.gif,60%);
-右上の検索フィールドで ''sqlite'' を検索~
&ref(./14-2.gif,60%);
-''SQLiteManager 0.8.0''をインストール~
&ref(./14-3.gif,60%);
-FireFoxを再起動~
&ref(./14-4.gif,60%);


***SQLiteについて自習する場合は、以下のサイトを参照してみよう [#g531ff60]
-SQLite http://www.sqlite.org/
--マニュアルの日本語訳: http://www.3rd-impact.net/Document/SQLite/Translation/Current/
--SQLite3 Windows用実行ファイル http://www.sqlite.org/sqlite-3_4_0.zip
//--PHP4からSQLiteを呼び出す ダイナミックライブラリ  http://pecl4win.php.net/list.php/4_4
//---&ref(php_sqlite.dll);
-SQLite SQL日本語リファレンス(日本語だけど古い):http://www.net-newbie.com/sqlite/lang.html
--コマンドチュートリアル(日本語だけど古い):http://www.net-newbie.com/sqlite/sqlite.html
-rakutoネット: SQLiteの使用例と解説:http://study.rakuto.net/php/command/
//-PHPマニュアル http://jp.php.net/manual/ja/index.php PHPの使い方がとてもよく分かる。プログラム例が豊富なので、とても助かる!
--SQLite CC http://www.takke.jp/soft/sqliteccj.html
---日本語表示も可能なSQLite用GUI

***SQLite Managerの起動 [#bf4e4d13]
+FireFoxメニュー > Web開発 > SQLite Manager を起動~
&ref(./14-5.gif,60%);
+''データベースディレクトリの指定'':  画面の右上の方にある「ディレクトリ」をクリックして、「規定ディレクトリ」をクリック。この操作で、データベースのデータファイルを保存するディレクトリ(フォルダーと同じ意味)を指定する。自分の「ドキュメント」フォルダをクリックして、「このフォルダを選択」しておこう。~
こうすることによって、作成されたデータベースは、ドキュメントフォルダに保存される。~
&ref(./14-6.gif,60%);
+''データベースの作成'': SQLiteのデータベースは、1つのファイルに全てのデータや設定が保存されるので、バックアップやデータのやりとりが非常に便利だ。~
では、サンプルデータの解析に使う''seiseki''という名前のデータベースを作成してみよう。
--FireFoxのメニューバーにある「データベース」から、「新しいデータベース」を選択し、データベース名の入力欄で''seiseki''と入力する。~
&ref(./#15-7.gif,60%);
~
これで準備は整った。


**データベースにおけるテーブルの概念を理解する⌣ [#cd0325ee]
SQLでは先ほど作ったデータベースファイルの中に、複数の''テーブル''を作成することで、データの操作を行う。
 テーブル というのは 表 のこと
例えば、エクセルを使って、次のような表(テーブル)を扱うのと、基本的には変わらない。
~
&ref(./#14-8.gif,50%);
~
また、
 1つのデータベースファイルの中には、複数のテーブルをしまっておける
 (エクセルで、複数のワークシートを使うようなもの)
という点でも、データベースとエクセルでできることは似ている。~
では、エクセルを使わずに、SQLiteを使ってテーブルを操作することの利点は何か?それは、
 大量のデータを含んだ、 複数のテーブルを、 1つの命令で簡単に処理できること
 また、
 テーブルの連結が簡単にできること
ちょっと想像してみてほしい。さきほどエクセルでテーブルの連結にトライしてみたが、あれが、何千、何万ものデータが入ったテーブルだったら、どうだろう。エクセルで開いて、並べ替えたり、データを抽出したりするのがどれだけ大変か。。。

**SQLiteを使って、2つ以上のテーブルを連結して、データを抽出する方法に挑戦!!⌣ [#fedfd7c9]
これから実際にSQLiteを使って何ができるかを体験してもらう。目標とするのは、さきほど例にあげたモデルケースを、SQLiteで簡単に処理することだ。繰り返しすと、
~
-''モデルケース''(自分が学校の先生になったことを想像してみる):
今手元に、国語、数学、英語の先生から提出された成績をまとめた書類がある。~
&ref(授業/H19/情報処理/13/成績集計表.doc);~
この成績表には学籍番号と成績がそれぞれ書かれている。これからあなたのクラスの学生全員の、成績の集計をしたい。生徒の名簿は、~
&ref(授業/H21/情報処理/13/名簿.doc);~
という名簿のファイルに、「''学籍番号、名前、よみがな''」が保存されている。~
さて、学生毎に選択している科目が違うのだが、3人の先生から集めた情報を1つ集計するにはどうすればいいだろうか?~
(※じつは、この程度の数のデータなら、エクセルでもわりと簡単に集計できる<SQLiteを使うと、この数百〜数千倍の規模のデータでも、簡単に処理できる>)~
&ref(授業/H22/情報処理/13/#13_2010_1.gif,50%);
~
&ref(授業/H22/情報処理/13/#13_2010_2.gif,50%);

***テーブル作成の準備 [#cae4a5d8]
まず、テーブルを確認しておく。''テーブル''には、上の例で示したような''カラム名''が必要になる。それぞれ、タイプしやすいようなカラム名にしておくといいだろう。
|テーブル|テーブル名|カラム|h
|名簿|meibo |gakuseki, namae, yomi|
|国語|kokugo|gakuseki,score|
|数学|sugaku|gakuseki,score|
|英語|eigo|gakuseki,score|

***データをデータベースに入れるために、タブ区切りテキストファイルを準備 [#y34dbaa4]
+''タブ区切りテキストファイルの準備''~
データをSQLiteで使える形にするには、''タブ区切りテキストファイル''の形にしておかなければならない。そこで、名簿とそれぞれの科目を、K2Editorを使って、タブ区切りテキストファイルとして保存する。それぞれ、
 meibo.txt
 kokugo.txt
 sugaku.txt
 eigo.txt
という名前で保存しておく。名簿の方はもともとタブ区切りになっているが、点数の方は空白で区切られているし、行頭に空白が入っているので、次の正規表現検索置換をして、テキストファイルにするのを忘れないように。
 検索文字列: ^ +  置換文字列<指定しない>
 検索文字列:  +  置換文字列: ¥t
-うまく出来ない場合は、次の4つのファイルを、右クリックしてダウンロードして使おう。~
&ref(授業/H24/情報処理/15/meibo.txt);&ref(授業/H24/情報処理/15/kokugo.txt);&ref(授業/H24/情報処理/15/sugaku.txt);&ref(授業/H24/情報処理/15/eigo.txt);

***データベースとテーブルの作成、テキストファイルからのデータの取り込み [#qe1a68e9]
先ほど作成した、''seiseki''という名前のデータベースに、データを取り込んで、上の4つ科目のテーブルを作成してみよう
+SQLite ManagerのImport Wizardを起動する(メニューバーの「データベース」から「取り込み」を選択してもよい)~
&ref(./#14-9.gif,60%);
--左側のパネルに4つのtableが出来上がれば、準備は完成だ。~
&ref(./#14-10.gif,60%);

-注)もしもここまでの準備がうまくできていない人は、&ref(./seiseki.sqlite);をダウンロードして、自分のドキュメントフォルダに入れて、SQlite Managerを立ち上げてみよう。このファイルには、上で準備した4つのテーブルが入っているので、この後の操作に使うことができる。(こうやって、データベースを1つのファイルで簡単にやり取りできるところがSQliteの利点だ)

***SQLiteを使って、データベースとお話しする [#adad315a]
***SQLiteを使って、簡単な英語でデータベースとお話しする [#adad315a]
ここから先は、''簡単な英語''を使って、データベースとお話しする。お話の内容(命令文)は、SQLite Managerの画面にある''SQL実行''をクリックして、入力欄に命令を入力することで行う。~
&ref(./#15_6.jpg);~
&ref(./#14-11.gif,60%);~
~
これから使う英語の意味をまとめておくと、
 select    :選び出して表示しなさい
 from  〜  : 〜というデータベースから
  where  :  ・・・という条件で
というものだ。
 命令の形式さえ守っていれば、コンピュータは内容を分かってくれるので
 変更できるところは自由に変更して楽しんでみよう
-使用例: selectの簡単な文章:
--書式: ''select <カラム名,,> from <テーブル名,,> where <カラム名>='<値>' order by <カラム名>;''
-では、次の命令を入力して、データベースとお話ししてみよう。また、命令文を自分で考えて少しずつかえて、結果を見てみよう。
--''select * from meibo;'' : 「meiboというテーブルから全てのレコード(注: *は全てのレコードを表す)表示しなさい
--''select * from meibo order by yomi;''  :「meiboというテーブルから全てのレコードを、yomiで並び替えて表示」
--''select gakuseki, namae from meibo;'' :「meiboというテーブルから、gakusekiとnamaeだけを表示しなさい」

***2つのテーブルを連結 [#xe29968a]
それでは、いよいよ2つのテーブルをgakuseiで関連づけてみよう。今、2つのテーブル、''meibo''と''kokugo''を考えてみると、gakuseki(学籍番号)が共通していることが分かる。
 meibo (gakuseki, namae, yomi);
 kokugo (gakuseki,score);
そこで、select文で条件指定するときに、「学籍番号が共通するものだけを選べ」という命令を入れてみる。このとき、''meibo''の学籍番号は、''meibo.gakuseki''で、''kokugo''の学籍番号は''kokugo.gakuseki''で表される。
--''select * from meibo, kokugo where meibo.gakuseki=kokugo.gakuseki;''~
これだと、2つのテーブルの全てのカラムが表示されるので、表示させるカラムを指定する。
--''select meibo.gakuseki, meibo.namae, kokugo.score from meibo, kokugo where meibo.gakuseki=kokugo.gakuseki;''
-同様にして3つ以上のシートからもデータを抽出できる。また、order byを使って並び替えも可能。
-''さらに発展的な連結''(非常に便利な連結方法)~
先ほどの連結方法で得られたレコード数は、97件だった。でも、実は、名簿には、100名分のデータが入っている。3名は国語の試験を受けていないため、成績が表示されなかったわけだ。
 select * from meibo, kokugo where meibo.gakuseki=kokugo.gakuseki
  ↑ この命令文だと、
 kokugo.gakuseki(国語のファイルの学籍番号)が存在している場合だけ、
 データが表示される
しかし、それでは困る場合もある。成績集計の上では、受験の有無にかかわらず、名簿に載っている全ての人に対して点数をつける必要があるからだ。そこで、SQLに ''left outer join on ...'' という命令を追加する。これは、「左側のテーブルにあるものは全て表示し、対応するデータがあるものは右側のデータも表示するというものだ」。この命令を使うことで、「meiboの内容は全て表示し、受験されている場合だけ、kokugoの点数も表示させる」ということが可能になる。
--''select meibo.gakuseki, meibo.namae, kokugo.score from meibo left outer join kokugo on meibo.gakuseki=kokugo.gakuseki''
-今度は100件のデータが全て表示されており、国語の受験が無い人については下の例の様に、点数が表示されていない
 06S4030  岩井文男  45
 06S4031  岩藤俊幸  
 06S4032  紀谷昌彦  46
このとき、国語を受験しなかった人の点数は''NULL''(無)になっている。
-次に、国語の点数の高い順番で、結果をソートして表示させてみよう
--''select meibo.gakuseki, meibo.namae, kokugo.score from meibo left outer join kokugo on meibo.gakuseki=kokugo.gakuseki order by kokugo.score desc'' 

-この授業では、以上の簡単なSQLの使いかただけ演習したが、その他のSQL命令の使い方の例は、以下を参考にしよう。
--SQLite コマンドの文法(英語)http://www.sqlite.org/lang.html
--やや古いが上記の日本語説明 http://www.net-newbie.com/sqlite/lang.html
--rakutoネット: SQLコマンド http://study.rakuto.net/php/command/
--PostgreSQLの日本語ドキュメント:http://www.postgresql.jp/document/pg824doc/html/sql-commands.html
---全てがSQLiteで使えるわけでは無いが、createとかselectの例は参考になる