情報工学科 ネットワーク系演習 III Web Database 担当 菅原 真司 ver.2.1.1 目次 第1章 Web Database 概説 1 1.1 データベースシステムとは何か . . . . . . . . . . . . . . . . . . . . . . 1 1.2 WebDB の構成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 RDBMS 5 2.1 RDBMS の概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2 RDB 設計の基礎 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.3 データ操作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 SQL 17 3.1 SQL の概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.2 MySQL の基本操作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 PHP と WebDB の連携 33 4.1 PHP について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.2 HTML フォームからの DB 操作 . . . . . . . . . . . . . . . . . . . . . . 33 Web Database システムの設計と構築 39 第2章 第3章 第4章 第5章 5.1 課題の提示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 5.2 設計方針 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 5.3 システム構築 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 課題とレポートの提出 43 6.1 提出課題 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 6.2 提出方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 プレゼンテーション 47 7.1 プレゼンテーションの一般的な留意事項 . . . . . . . . . . . . . . . . . . 47 7.2 本演習でのプレゼンテーションについて . . . . . . . . . . . . . . . . . . 47 第6章 第7章 i はじめに 本テキストでは,情報工学科ネットワーク系演習 III で準備されている演習テーマのう ちの,Web Database について説明をします. おそらく他のテーマも同様だと思いますが,取り組むべき内容の概要は説明されるもの の,細かい部分は学生の自らの努力に委ねられることになります.ですから,分からない ことが出てきたときに,常に受け身の状態でいると,全く前に進みません.誰かが教えて くれるはずだという期待や,教えてくれないからできないのだという言い訳は禁物です. 自分で資料を探し,試行錯誤することで,理解を深めようという姿勢が大事になります. そして,このような姿勢でいろいろな問題に臨むことが,今後,各研究室に所属して,卒 業研究に取り組む際の大きな助力になると思います. この演習科目を履修する方には,本テキストを良く読んで,積極的に参加してくれるこ とを期待します. 1 第1章 Web Database 概説 1.1 データベースシステムとは何か 電子式汎用計算機が世の中に登場して,まだ70年程という比較的新しい技術分野であ るにもかかわらず,ハードウェアとソフトウェアの両面で,コンピュータ技術の発展には 著しいものがあります.これは,近年急速に発展してきた情報通信ネットワーク技術と相 俟って,我々の生活にもはや欠かすことのできない重要な役割を果たしています. 多くのコンピュータシステムが情報通信ネットワークにより互いに接続されている世 界では,各コンピュータ上で動作するアプリケーションが多種多様なデータを作り出し, ネットワークを介してこれらを交換し,互いに役立てることによって多くの利益を生み出 しています.そしてこのようなデータは今後も一層多様化,複雑化,大規模化してゆくこ とでしょう. 各種アプリケーションが作り出したデータは,効率的な利用を図るためにも,統合さ れ,蓄積管理され,共有されることが望ましいのですが,このような役割を果たすものが データベースシステム (database system, DBS) であると言えます. 一般にデータベース (database, DB) とは,複数の利用目的で共有することを前提とし て格納されたデータ群であり,かつ,必要に応じてその中から特定のデータを速やかに取 り出すことのできる仕組みを持つものと考えられます.そして多くの場合,データベース は,ある実世界の状態や構造をモデル化し,データとして蓄積しており,これらのデータ を必要とする,複数のユーザやコンピュータのプロセスに対して,アクセス許すような仕 組みになっています. また,データベースの構成要素としては,データを永続的に保持するため,ハードウェ アシステムとして通常は磁気ディスクのような不揮発性の二次記憶装置を用い,同時にこ れらのデータを管理するためのソフトウェアシステムであるデータベース管理システム (database management system, DBMS) が装備されます. DBMS にはいくつかの種類がありますが,現在の主流となっているのは,リレーショ ナルデータベース管理システム (relational database management system, RDBMS) で す.このタイプの DBMS は,表形式でデータを管理し,複数の表を組み合わせて数学的 な処理を施すことにより必要なデータを取り出します.オブジェクト指向データベース (object oriented database, OODB) と比較すると,現実世界の直感的なモデル化に多少 難があるなどの問題点はありますが,扱いやすく,最も普及している DBMS の形態であ ると言えます. 第1章 2 Web Database 概説 今日,データベースシステムは,世界中のありとあらゆるビジネスを支えていると言っ て間違いありません.例えば,人事管理システム,在庫管理システム,販売管理システム, 生産管理システム,CAD や CASE などのエンジニアリングデータ,化合物情報,遺伝子 情報,医学情報などの科学データ,コンピュータネットワークの管理データ · · ·.枚挙に 暇がありません.そして,そのようなシステムに共通した利用形態として,また,最近で は特に一般の人々の生活に密着した利用にも広がっているのが,Web ページ上から利用 するデータベースシステムです.インターネット上で利用できるサービスのほぼすべてが 何らかの形で Web データベースシステム(これ以降,WebDB システムと略記します.) を用いていると言ってよいでしょう. この演習では,RDBMS を用いた WebDB システムの基本的な操作から,簡単なシス テムの設計と構築までを行います.今後はこの形態のシステムに関する内容に絞って話を 進めてゆきます. 1.2 WebDB の構成 1.2.1 基本的なシステム構成 前述のように DB とはデータを体系的に格納する機能と必要に応じてデータを取り出 す機能を併せ持つものを意味しています.すなわち,基本的な設計,あるいは枠組みが完 成した,利用段階にある DB に対するデータの操作では,データの「追加」, 「削除」, 「変 更」,「探索」,「取得」の5つが主となります. さらに,これも前述しましたが,現在の DB を含むコンピュータシステムは,インター ネットに代表される大規模情報通信ネットワークにより互いに接続することが可能となり ました.昨今の PC(personal computer) と呼ばれるコンピュータの高性能化,低価格化, に伴い,特に専門家ではない一般の多くの人々がコンピュータを所有し,インターネット に接続してデータを交換するような使い方が爆発的に普及したことにより,特に商用のコ ンピュータシステムを用いたサービスは多くのものがネットワークを介した利用を可能と し,人々に多大なる利便性を提供しています.当然このようなサービスのほとんどすべて に DB システムが大きく関与していることは明白であり,インターネットに接続したあら ゆるコンピュータから上記のデータ操作が行われていることは自明のことと言えます. このようなネットワークを介した DB の操作として現在最も一般的で,普及しているの が WWW(World Wide Web) のブラウザをインタフェースに用いたものです.しかし, WWW サイトの閲覧が,一般の人々の PC 所有とインターネット接続をこれほど短時間 に大きく普及させた最も大きな原動力のひとつであったことを鑑みると,Web ブラウザ が多くの人にとって最も馴染み深く使いやすいインタフェースであり,多くのシステムが これを用いた操作を前提としていることは当然の帰結であるとも言えます. 以上のような背景から,Web ブラウザをインタフェースとして用いた DB システムは 現在の大規模ネットワーク接続を前提としたコンピュータシステムには不可欠な要素と なっています. WebDB の最も特徴的な点は,ユーザから見て,ブラウザが使えて,ネットワーク接続 が可能なコンピュータさえあれば,DB に容易にアクセスすることができることです.こ れは DBMS とデータをサーバ側に置くことで,ユーザは特別なアプリケーションを自分 1.2 WebDB の構成 3 クライアント WebDB システム リクエスト リクエスト (操作要求) (操作要求) Web ブラウザを介した Web サーバ DBMS ユーザによる操作 アプリケーション 大規模ネットワーク 橋渡しの (インターネット) 実行環境 捜査結果の受け取り データ データ (処理結果) (処理結果を Web ページ上に表示) 図 1.1 WebDB システムの構成 で持つ必要はありません.しかし,あたかも Web サイトにアクセスするような気分で, 実際には上記の5つの DB 操作をネットワーク越しに行うことができます. これは Web システムを介して DB を操作していることになりますが,この場合はサー バ上に Web サーバアプリケーションと DBMS が存在し,さらにこれら2つを繋ぐ仕組 みが必要となります.具体的には OS(Unix 系 OS, MS Windows, MacOS 等) の動作す るサーバ上に Web サーバ (Apache 等) と DBMS(Oracle, MySQL, PostgreSQL 等) が 載り,それらを橋渡しする処理の実行環境(CGI*1 や,HTML に埋め込まれたスクリプ ト等*2 によるものが好例)を備えるというような構成のシステムが多く存在すると思いま す.(図 1.1 参照.) 1.2.2 動的なページと静的なページ WebDB を利用するユーザの PC をクライアント,サービスを提供する WebDB シス テムをサーバと呼ぶことにしましょう.このとき一般に,クライアントからの検索等の要 求によって,サーバが返す結果は常に異なります.同じクライアントからの同じ要求で も,データが更新されていればサーバの返す結果はやはり異なります.すなわち WebDB サーバでは,クライアントからの要求に合わせたお決まりのデータを準備しているだけで は不十分で,常に要求を受けるたびに DB 内の最新の情報を反映させた結果をクライアン トに返信する必要があります. *1 *2 Common Gateway Interface, 言語ではありません.CGI はどんな言語でも書けます.(サーバが許さ ないと動作しませんが · · ·.C, Perl が主流でしたが,現在では PHP, Python, Ruby など様々な言語を 許すサーバが出てきました.) 現在,データベースとの連携で CGI を使うことは主流ではなくなりつ つあります. このような使い方をするスクリプト言語の筆頭にあげられるのが PHP で,Perl でも書けます. Java Servlet / JavaServer Pages も類似の機能を持ちますが,これらはひとつの仕様であり,言語としては Java です. 第1章 4 Web Database 概説 このことはいくつかの WebDB を用いたサービスを思い浮かべてみてもすぐわかると 思います*3 .すなわち,WebDB システムの提供する Web ページは,クライアントの要 求に応じて動的 (dynamic) に Web ページを生成して提供していることになります.実際 には,Web ページの基本デザインフォーマットの中に,クライアントの要求に応じた情 報を部分的に埋め込むことで実現しているのが普通です. このようなページを「動的なページ」と呼ぶことにすると,逆の概念は「静的 (static) なページ」ということになります.これはクライアントの要求や状況によって,その都度 サーバが提示する情報を変化させる必要の無いページで,想定されるクライアントの要求 の数だけ,事前に提示する HTML ファイルを準備してあるような,単純なシステムで実 現できます. *3 例えば,使っても使っても金額が減らない銀行預金残高は嬉しいですが,預金しても反映されないのは困 りますね. 5 第2章 RDBMS 前章で,WebDB システムの概要についてお話ししましたが,この章では,その中でも 重要な役割を果たす RDBMS について説明します. 2.1 RDBMS の概要 RDBMS(Relational Database Management System) は,その名の通り,リレーショナ ル型データベースの管理システムです.リレーショナル DB は,複数のテーブル (table) と呼ばれる表形式のデータを互いに関連づけて,情報を保持,操作するように設計されて います. 大量のデータを扱うデータベースを想像してみましょう.この場合,非常に大きなサイ ズのテーブルをひとつ保持することでその機能を実現することが考えられます.非常にシ ンプルな構成で,どんな情報もそのテーブルを参照すれば用が足りますから,一見非常に わかりやすいシステムのように思えます.しかし,1つのテーブルの大きさが大きくなり すぎると,ユーザもテーブル全体の構成を把握しにくくなり,管理が難しくなることが考 えられます.また,テーブル単位でデータの操作をするとすれば,どんな情報を操作する 場合でも大きなテーブル全部を一度読み込み,片っ端からチェックして,操作の要求され る部分を探した上で,処理を行うことになりますから,ハードウェアに負担がかかり,円 滑に操作をしにくくなることも考えられます.さらに,大きなテーブルにすべての情報を 整理する場合,どの情報に関しても同じ種類の属性を準備しておくことになりますので, 必要の無い属性については準備したスペースが利用されないケースも生じるでしょう.一 般に汎用的な属性を持つテーブルを作れば,無駄が生じやすいと考えられます. 以上のことから,情報を少数の大きなテーブルにまとめることはデメリットが大きいこ とがわかります.そこで,テーブルをいくつかに分割して,互いにあるルールで関連づ け,結びつけて使用することが考えられます.そうすることで,テーブルの数が増える面 倒はありますが,これさえうまく管理できれば,必要な情報のみをコンパクトに保持した テーブルにアクセスしたり,必要であれば複数の小さいサイズのテーブルを組み合わせ, 操作することにより,柔軟で,素早いデータ操作を行うことが可能になります.これが RDBMS の本質的な設計思想と考えて良いと思います. RDBMS の具体的な例についても触れておきましょう.世の中には多くの RDBMS が 存在し,実際に本演習で取り上げるような WebDB システムを含めて,多くのサービス の礎となっています.商用の DBMS で大変有名なものは,Oracle Database, Microsoft 第2章 6 RDBMS SQL Server, IBM DB2 が挙げられます. 小規模なものなら,Microsoft Access でしょ うか.また,オープンソースの DBMS で有名なものとしては,MySQL と PostgreSQL が双璧でしょう.ちなみに本演習では MySQL を用います. 2.2 RDB 設計の基礎 前節で述べたように,DBMS では,複数のテーブルが全体としてひとつのデータベー スを構成し,それらのテーブルが互いに関連づけられることにより,効率よく操作を行う ことが可能となります. このような思想で設計されている DBMS を適切に運用するためには,テーブルが複数 あっても,互いに矛盾せず,データの一貫性を保てるようにしておく必要があります.ま た,複数のテーブルに同様の情報が重複して存在することも排除しておく必要もありま す.こうしたことに配慮して構築された DB を利用する場合,同様のことを何度も入力し なければならないような冗長な作業を減らしたり,データの更新等を行う際の誤りの発見 が容易になるようなメリットもあります. 2.2.1 正規化と非正規形 前述のように,RDB の設計において,データの無駄な繰り返しを排除して,一貫性を 保てるように,テーブルを分割していくことを「正規化」と呼びます. 正規化にはいくつかの段階があります.正規化がなされていない状態として,非第 1 正 規形 (non-first normal form),第 1 段階の正規化が第 1 正規形 (first normal form, 1NF), 次いで第 2 正規形 (second normal form, 2NF),第 3 正規形 (third normal form, 3NF), さらに高次の正規化 (further normalization) としてボイス-コッド正規形 (Boyce-Codd normal form, BCNF),第4正規形 (forth normal form, 4NF),第5正規形 (fifth normal form, 5NF) が定義されています. 正規化の段階は,高いほど格納情報が整理され,冗長性を排除したり,構造や操作を分 かり易くしますが,どんな場合でも最も高い段階の正規化が,常に良いデータベース操作 を実現するとは限りませんから,対象のデータベースにあわせてどこまで正規化を行うか については,設計者が良く検討する必要があります. この演習では第 3 正規形まで簡単に説明します. 1. 非第 1 正規形(または「入れ子リレーション (nested relation)」をもつ構造) リレーション*1 の定義域*2 (domain) が構造を持ち,単純でない.定義域が集合(ま たは配列,リスト等)の集合である場合や,ひとつの定義域が複数の定義域の直積 からなる場合など. 2. 第 2 正規形 リレーションの定義域が単純.入れ子構造が無い.第 1 正規形のリレーショ *1 RDB のデータ構造のこと.テーブルとして表現. *2 データの値の集合のこと. 2.2 RDB 設計の基礎 7 ンを,すべての非キー属性*3 が候補キー*4 に完全関数従属*5 (fully functionally dependent) になるように分割.すなわち,候補キーの真部分集合に対する関数従 属性*6 がなくなるように,その決定子*7 (determinant,候補キーの真部分集合) と その決定子に関数従属である属性集合だけをもつリレーションと,その決定子に関 数従属であるそれらの属性集合を元のリレーションから除いたリレーションに分解 していく. 3. 第 3 正規形 リレーションが第 2 正規形.かつリレーションのすべての非キー属性がそのリレー ションのどの候補キーにも推移的に従属しない. 上記の説明では正規化を理解する上でやや抽象的ですから,ひとつの例を挙げます.あ る大学と取引のあるお店の注文伝票データを DB に整理することを考えてみてください. 各注文伝票に記入される情報は,「伝票番号」,「受注日」,「顧客番号」「顧客名」*8 ,「商品 番号」,「商品名」,「単価」,「個数」とします.(図 2.1 参照.)これをひとつのテーブルに まとめようとすると,以下の表 2.1 のようになります. 注文伝票 伝票番号 5001 受注日 2007年9月 10日 注文顧客 L032 S 研究室 様 商品番号 商品名 単価 個数 N001 ノート 120 5 M021 USB メモリ 3,150 3 C015 コピー用紙 525 10 図 2.1 ある店の注文伝票 このテーブルが非効率であることはすぐに見てわかります.ひとつの伝票番号につい て,「商品番号」,「商品名」,「価格」,「個数」という同種の属性が複数あります.一度に 注文伝票に書き込まれる商品の種類が増えるたびに商品の上記4つの属性を増やす必要が あり,定型のテーブルにまとめるには扱いにくいですし,1 枚の注文伝票当たりの最大の 商品種類数を予め大きめに設定しておいたとしても,それ以下の数の注文しかない伝票で は,無駄(用意していても使わないスペース)が生じます.これはテーブルの中にリスト 構造が存在し,入れ子構造になっていますから,単純な構造とは言えず,典型的な非(第 *3 *4 *5 *6 *7 *8 どの候補キーの要素でもない属性. タプル(行)を一意に識別する最小の属性集合(属性または属性の組).これらのうち任意のひとつが主 キーとなる. 例えば,X が Y を決定するために必要な最小集合である場合,Y は X に対して完全関数従属である(X → Y と表現)という. 属性間の従属関係で,ある属性の値が x ならば,別のある属性の値が y でなければならないという関係. この場合,後者の属性は前者のそれに関数従属している.(x → y) X → Y の関係における X に相当.ちなみに Y は非決定子. 図 2.1 中では,まとめて「注文顧客」としています. 第2章 8 RDBMS 表 2.1 注文伝票 DB の非正規形テーブル例 伝票番号 受注日 顧客名 顧客番号 商品番号 1 商品名 1 価格 1 個数 1 5001 5002 5003 5004 5005 9/10/07 9/10/07 9/11/07 9/12/07 9/15/07 S 研究室 I 研究室 S 研究室 J課 K 研究室 L032 L055 L032 D102 L115 N001 P055 N025 N083 P031 ノート 120 79,800 105 315 115,700 5 2 15 20 1 商品番号 2 M021 C015 P048 P055 商品名 2 USB メモリ コピー用紙 電源ケーブル PC PC ボールペン ファイル PC 価格 2 個数 2 商品番号 3 商品名 3 価格 3 個数 3 3,150 525 3 5 C015 コピー用紙 525 10 1,850 79,800 2 2 P105 CD-R 1,575 2 1)正規形であると考えられます. 2.2.2 正規化の例 それでは,非正規形のテーブルの正規化を例を挙げて説明します.まず最初の正規化と して,同一レコード内に重複する属性を取り除き,注文商品が増えても属性を増やさなく て良い構造に修正します.(表 2.2 参照.) 表 2.2 第 1 正規形の例 伝票番号 受注日 顧客名 顧客番号 商品番号 商品名 価格 個数 5001 5001 5001 5002 5002 5003 5004 5004 5005 5005 5005 9/10/07 9/10/07 9/10/07 9/10/07 9/10/07 9/11/07 9/12/07 9/12/07 9/15/07 9/15/07 9/15/07 S 研究室 S 研究室 S 研究室 I 研究室 I 研究室 S 研究室 J課 J課 K 研究室 K 研究室 K 研究室 L032 L032 L032 L055 L055 L032 D102 D102 L115 L115 L115 N001 M021 C015 P055 C015 N025 N083 P048 P031 P055 P105 ノート 120 3,150 525 79,800 525 105 315 1,850 115,700 79,800 1,575 5 3 10 2 5 15 20 2 1 2 2 USB メモリ コピー用紙 PC コピー用紙 ボールペン ファイル 電源ケーブル PC PC CD-R このように,テーブル内の入れ子構造を解消し,単純な構造のリレーションを第 1 正規 形と呼びます.これにより,入力ごとに属性を増やす必要が無く,重複する属性の無い テーブルを実現できました. しかし,これでもまだ不満が残ります.一度に複数の注文を受けた場合に,商品の名前 を入力するたびに,受注日と顧客名が同じなのにこれらも毎回入力しなければなりませ ん.また,商品が決まれば価格は一意に決まるのに,冗長な入力を繰り返さなければなり ません.今度はこれを修正します. 2.2 RDB 設計の基礎 9 候補キーは, 「伝票番号」と「商品番号」の組になります.これですべてのタプルは一意 に特定できます.ここで,「伝票番号」に完全関数従属する「受注日」,「顧客番号」,「顧 客名」は分割してひとつの独立したリレーションとします(「伝票番号」,「受注日」,「顧 客番号」, 「顧客名」の属性からなるリレーション).また,「商品番号」に完全関数従属す る「商品名」 , 「価格」も独立させましょう( 「商品番号」 , 「商品名」 , 「価格」の属性からな るリレーション).すると,それらを切り離して残るリレーションは,「伝票番号」と「商 品番号」の組を候補キーとして,これに完全関数従属する「個数」からなるもののみにな ります.これで第 2 正規形のリレーションが完成します.(表 2.3, 2.4, 2.5 参照.) 表 2.3 第 2 正規形の例:注文伝票テーブル 伝票番号 受注日 顧客番号 顧客名 5001 5002 5003 5004 5005 9/10/07 9/10/07 9/11/07 9/12/07 9/15/07 L032 L055 L032 D102 L115 S 研究室 I 研究室 S 研究室 J課 K 研究室 表 2.4 第 2 正規形の例:商品テーブル 商品番号 商品名 価格 N001 M021 C015 P055 C015 N025 N083 P048 P031 P055 P105 ノート 120 3,150 525 79,800 525 105 315 1,850 115,700 79,800 1,575 表 2.5 USB メモリ コピー用紙 PC コピー用紙 ボールペン ファイル 電源ケーブル PC PC CD-R 第 2 正規形の例:注文内容テーブル 伝票番号 商品番号 5001 5001 5001 5002 5002 5003 5004 5004 5005 5005 5005 N001 M021 C015 P055 C015 N025 N083 P048 P031 P055 P105 個数 5 3 10 2 5 15 20 2 1 2 2 さらにもう一段階正規化をしてみましょう.注文伝票テーブルには「顧客番号」と「顧 第2章 10 RDBMS 客名」の 2 つの属性がありますが,これらは,一方が他方に従属しています*9 .すなわち, 「伝票番号」から「顧客番号」が一意に決まる( 「顧客番号」が, 「伝票番号」に完全関数従 属する)とすると,「顧客名」は,「顧客番号」に従属しますから,結局,候補キーである 「伝票番号」にも推移的に従属することになります. 推移的な従属を切り離して独立させたものが第 3 正規形ですので,今度はこれを行いま す.表 2.6, 2.7 を見てください. 表 2.6 第 3 正規形の例:注文伝票テーブル 伝票番号 受注日 顧客番号 5001 5002 5003 5004 5005 9/10/07 9/10/07 9/11/07 9/12/07 9/15/07 L032 L055 L032 D102 L115 表 2.7 第 3 正規形の例:顧客テーブル 顧客番号 顧客名 D102 L032 L055 L115 J課 S 研究室 I 研究室 K 研究室 第 2 正規形のテーブルのうちで,第 3 正規形に修正する必要があるのは,注文伝票テー ブルのみなので,これを分解したものを示しました.前述のように,「顧客番号」により 「顧客名」が決まるので,これを独立させて顧客テーブルとし,第 2 正規形の注文伝票テー ブルからその関係を除いたものを第 3 正規形の注文伝票テーブルとしています. 第 2 正規形のうち,第 3 正規形にしても変化の無かった残りの2つのテーブルと上記 の 2 つのテーブルを合わせて,合計4つのテーブルが,第 3 正規形のリレーションとなり ます. 正規化について,イメージが湧いたでしょうか? RDB 設計に関する話題として,も うひとつだけ説明しておきたいことがあります.それが次で述べるデータ型です.最後に そちらの話について少しだけ付け加えておきます. 2.2.3 データ型 RDB 構築の際には,テーブルの各属性に,どのような種類のデータを格納するのかに ついて考える必要があります.これをデータ型の設計と言います. テーブルに属性を作るときに,その属性を表現するためのデータの種類を指定すること になりますが,そのデータの種類すなわちデータ型は大きく分けて,数値型,日付型,文 字列型の3つがあり,さらに各型の中にも複数の種類があります.例えば,数値型の INT, TINYINT 等,日付型の DATE, DATETIME 等,さらに文字列型の CHAR, VARCHAR 等です. *9 この場合はどちらがどちらに従属すると言ってもよいですが,これ以降は, 「顧客名」が「顧客番号」に従 属するものとして話を進めます. 2.3 データ操作 テーブルの属性を設計するときには,その属性を表現するデータの種類と長さ(精度) を指定します.これを行うことで,データを効率よく格納したり,検索したりすることが できます. 詳しい種類と使い方については,自分で積極的に調べてみてください. 2.3 データ操作 前節では,RDB 設計の中心に,正規化があることをお話ししました.データの無駄な スペースを排除して,整合性,一貫性を維持したり,データの部品化を可能にして更新に 備えたり,データ構造や操作の分かり易さを高めたりすることなどが主な目的ですが,こ れが実現されると同時に,一般にテーブルは小さく分割されてゆきます.そこで,実際に データを引き出すときには,ひとつひとつのテーブルではデータが細かく独立しすぎてい るため,それらのテーブルを組み合わせ,結びつけることで必要なデータを得ることに なります.これをデータの操作と呼びます.つまり,RDB 設計時の正規化と,利用時の データ操作は対になっていて,RDB を適切に構築し運用するためにはどちらも非常に重 要な要素になります. RDB におけるデータ操作には,リレーショナル代数 (relational algebra) とリレーショ ナル論理 (relational calculus) がありますが,今回は前者についてのみ触れることにしま す.リレーショナル代数には,各種の演算子がありますが,基本的なものは以下の5つ です. • 和 (union) • 差 (difference) • 直積 (cartesian product) • 射影 (projection) • 選択 (selection) これらについては,データベース論*10 等の講義でも詳しく説明していますから,良く 理解している人も多いと思います.その他のリレーショナル代数演算子として,さらに以 下の4つが挙げられます. • 結合 (join) • 自然結合 (natural join) • 共通 (intersection) • 商 (division, quotient) これらについてもほとんど講義で説明していますので,説明は不要かもしれませんが, 結合についてのみ,講義で触れていない内容を少し補足したいと思います.一般的な結合 の操作に関しては説明は不要だと思いますが,その他にもいくつかのバリエーションがあ りますので,ここではそれらの一部について例を挙げて説明します.ある研究室の備品に 関するデータが表 2.8∼2.11 の通りにあると思ってください.それでは説明に入ります. *10 本年度は 3 年前期の講義として菅原が担当. 11 第2章 12 RDBMS 2.3.1 外部結合 (outer-join) まず外部結合についてお話しします.外部結合はさらに「左外部結合」,「右外部結合」, 「完全外部結合*11 」の 3 種類に分類できます.これらはそれぞれ,2 つのテーブルを左右 に並べてそれらの結合を考えたときに,結果のテーブルに左のテーブルの全行(全タプ ル)が表示されるもの,同様に右のテーブルの全行が表示されるもの,さらに同様に左右 のテーブルの全行が表示されるものになります.これらは,左右の 2 つのテーブルが完全 に一致せず,さらにテーブル中に空欄があっても結合を行い,結果を表示できます. 表 2.8 備品テーブル 1 備品番号 備品名 種別番号 1001 1002 1003 1004 1005 1006 机 1 1 2 書棚 キーボード 電話機 USB メモリ 2 1 ホワイトボード 表 2.9 備品テーブル 2 備品番号 備品名 同時利用 2001 2002 2003 PC 2002 2001 2001 プリンタ スキャナ 表 2.10 文房具テーブル 備品番号 備品名 種別番号 3001 3002 3003 ボールペン 3 3 3 はさみ ノート 表 2.11 備品種別テーブル 種別番号 種別 1 2 3 PC 関連 什器 文房具 前述の備品テーブル 1 を左に,備品種別テーブルを右に置いたと仮定して,それらの左 外部結合を考えてみましょう.共通の属性は「種別番号」ですから,左の備品テーブル 1 の全部の行を表示するようにして,各行の「種別番号」と同じ値を右の備品種別テーブル から探し,結合します.結果を表 2.12 に示します. このとき,注意すべきことは,左のテーブルの備品テーブル 1 では,電話機の種別番号 が null であり,右の備品種別テーブルと結合できませんが, 「種別」属性の値を null とし て,結合の結果として生成されるテーブルに残ります.これに対して,備品種別テーブル *11 今回の演習で用いる RDBMS の MySQL では,完全外部結合はサポート外ですが,参考のため説明しま す. 2.3 データ操作 13 表 2.12 左外部結合の例 備品番号 備品名 種別番号 種別 1001 1002 1003 1004 1005 1006 机 1 1 2 什器 書棚 キーボード 什器 PC 関連 電話機 USB メモリ ホワイトボード 2 1 PC 関連 什器 の行のうち,文房具の行は,結合すべき相手となる行が備品テーブル 1 内に存在しないた め,結果のテーブルには表示されません. 全く逆のことが、右外部結合では起こります.上記で最初に置いた左右のテーブルはそ のままで,右外部結合を施した結果を表 2.13 に示します.左の備品テーブル 1 の電話機 の行は,右の備品種別テーブルと結合できませんから結果のテーブルには残りません.ま た,右の備品種別テーブルの文房具の行は,左の備品テーブル 1 と結合できませんが,結 果のテーブルには残ります.この場合の備品番号と備品名は null になります. すなわち,左右の外部結合ではそれぞれ左右のどちらのテーブルの行を全部残すことを 前提とする(それにもう一方のテーブル上の行を結合させる)のかが異なるということに なります. 表 2.13 右外部結合の例 備品番号 備品名 種別番号 種別 1001 1002 1003 1005 1006 机 1 1 2 2 1 3 什器 書棚 キーボード USB メモリ ホワイトボード 什器 PC 関連 PC 関連 什器 文房具 これらに対して,完全外部結合では,左右のテーブルに null が含まれていても,両者の すべての行を表示します.上記の2つの例と同様のテーブルを使用した場合の完全外部結 合の例を表 2.14 に示します. 表 2.14 完全外部結合の例 備品番号 備品名 種別番号 種別 1001 1002 1003 1004 1005 1006 机 1 1 2 什器 書棚 キーボード 什器 PC 関連 電話機 USB メモリ ホワイトボード 2 1 3 PC 関連 什器 文房具 この結合では,左右両方の行がすべて結果のテーブルに残り,該当する値がない(見つ 第2章 14 RDBMS からない)場合には null として表示しています. 外部結合に関する補足はこんなところです. 2.3.2 内部結合 (inner-join) 次に,内部結合についてお話しします.上で述べた外部結合とは異なり,こちらの結合 では,2 つの元になるテーブルのキーが互いに一致した行のみを表示します.ですから, 結果のテーブルに null は新しく生じません.表 2.15 を見てください.外部結合と同様の 2つのテーブルを用いて結合を行った結果です. 表 2.15 内部結合の例 備品番号 備品名 種別番号 種別 1001 1002 1003 1005 1006 机 1 1 2 2 1 什器 書棚 キーボード USB メモリ ホワイトボード 什器 PC 関連 PC 関連 什器 一見して分かるように,備品テーブル 1 で,種別番号の無い電話機の行と,備品種別 テーブルで,相手テーブルに結合されることがない文房具の行は,どちらも結果のテーブ ルからは除外されています. 皆さんのイメージ通りの典型的な「結合」操作の姿ですね*12 . 2.3.3 自己結合 (self-join) 次は自己結合です.これは同じテーブルを 2 回使用して新しいテーブルを作ります.で すから,これまでの説明の仕方を踏襲すると,左右に並べる 2 つのテーブルは,同一の テーブルになります. 備品テーブル 2 は,PC,プリンタ,スキャナの3つの備品について,それぞれがこの 中の他のどの備品と同時に使用されることが多いかについて記述したデータです.つま り,PC はプリンタと最も多く同時に使用されます.また,プリンタとスキャナはどちら も PC と同時に使用されることが最も多いことを示しています.*13 このテーブルを 2 回 使って自己結合を施した結果が表 2.16 です. どうでしょうか.自己結合の操作は理解できたでしょうか? 2.3.4 交差結合 (cross-join) 今度は交差結合ですが,これは 2 つのテーブルの行同士のすべての組み合わせが網羅 されるように結合しますから,リレーショナル代数演算での,行の直積を考えるのと同じ *12 つまり,細かい分類を意識して呼ぶとすると,データベース論で説明した所謂「結合」というのは内部結 合のことです. *13 プリンタとスキャナを組にして使用することはあまり無いですね.お気づきと思いますが,このテーブル は,自己結合の説明のために無理矢理こじつけて作りました.上記3つの機器の同時使用についてまとめ たデータにどんな意味があるのかについては,考える必要はありません. (考えても意味はありません. あしからず.) 2.3 データ操作 15 表 2.16 自己結合の例 備品番号 備品名 同時利用 備品番号 備品名 同時利用 2001 2002 2003 PC 2002 2001 2001 2002 2001 2001 プリンタ 2001 2002 2002 プリンタ スキャナ PC PC ことになります.ですから当然ですが,操作後出来上がるテーブルの行の総数は,2つの テーブルの行数の積になります. 単なる直積ですから,属性間のつながりを考える必要も無いので,共通するキーなし に,互いに接点の無いまま結合が行われます.今回の例で言うと,備品テーブル 2 と備品 種別テーブルは,両者に全く接点がありませんが,これでも交差結合は可能です.こうし て作成したテーブルを表 2.17 に示します. 表 2.17 交差結合の例 備品番号 備品名 同時利用 種別番号 種別 2001 2002 2003 2001 2002 2003 2001 2002 2003 PC 2002 2001 2001 2002 2001 2001 2002 2001 2001 1 1 1 2 2 2 3 3 3 什器 プリンタ スキャナ PC プリンタ スキャナ PC プリンタ スキャナ 什器 什器 PC 関連 PC 関連 PC 関連 文房具 文房具 文房具 この結合は,これだけで使用されることは少ないと思います.どちらかと言えば,結合 操作の過程で生じる操作,という感じでしょうか*14 . 2.3.5 和結合 (union) 最後になりましたが,和結合について補足します.これは,2 つのテーブルを左右に見 て結合するのではなく,単純に上下に結合します.ですから,主キーはありません.2 つ のテーブルをひとつのテーブルとしたいときに行う操作です.ただし,この場合気をつけ なければいけないのは,結合する 2 つのテーブルは,属性の数が(厳密には種類も)同一 である必要があります. この操作は結合の一形態として紹介する場合がありますが,前述の交差結合と直積の関 係と同様,これも実質的にはリレーショナル代数演算の「和」と同じものと思って良いと 思います. 例として,備品テーブル 1 と文房具テーブルの和結合を表 2.18 に示します. *14 直積を取った後,注目する属性間の要素同士に何らかの関係(等しいとか,どちらかがどちらかより大き いとか · · ·)がある場合のみ操作結果のテーブルに残すと,通常の(内部)結合になります. 第2章 16 RDBMS 表 2.18 和結合の例 備品番号 備品名 種別番号 1001 1002 1003 1004 1005 1006 3001 3002 3003 机 1 1 2 書棚 キーボード 電話機 USB メモリ ホワイトボード ボールペン はさみ ノート 2 1 3 3 3 2.3.6 データ操作のまとめ データ操作について,結合操作の補足を中心にお話ししました.講義で説明済みのた め,今回説明を省いた操作が数多くありますが,RDB 設計では当然こちらも非常に重 要*15 ですので,データ操作の節の冒頭で述べた,結合を含めて9つのリレーショナル代 数演算について,良く理解を深めておいてください. *15 数からすると,こちらの方がずっと多いので,遥かに重要!と言えます. 17 第3章 SQL 3.1 SQL の概要 SQL とは何か SQL は,1969 年から 1970 年にかけて,IBM 社 San Jose 研究所の E.F.Codd によっ て提案された RDB システムのための言語として,同研究所の D.Chamberlin によって最 初に開発されました.その後,1987 年に ISO によって標準化され,現在も拡張され続け ています. 元々は RDB を操作するための言語として開発されましたが,ISO の SQL 規格では特 にそのことに言及していません.ですから,RDB 以外でも利用して良いし,実際に利用 されています.また,ISO SQL:1999 では,オブジェクト指向機能や構造を持ったデータ を扱う機能も装備するように拡張され,オブジェクト-リレーショナル DB にも対応して います.現在 SQL は,RDB の標準データベース言語であると言って良いでしょう. SQL 以前の DB 言語が,目的のデータをどのように取り出すかを指定する「手続き型」 の言語であったのに対して,SQL は,基本的には,どのようなデータを取り出すかを指定 する「非手続き型」の言語です.ただし,現在では前述のように機能の拡張が進み,SQL だけで簡単なアプリケーションが開発できるような計算完備の言語を目指して,処理の流 れを制御するために,手続き型の要素を備えつつあります. なお,ISO では,「SQL」の名称は何かの頭文字ではなく,固有の名称であるとしてい ますので,正式には SQL は略称ではないことになっています*1 . 3.1.1 MySQL さて,講義で聴くような話ばかりでは,演習の意味がありませんから,そろそろ内容も 演習に相応しいものに移ります. 概念としての RDBMS については,講義でも前章でも説明しました.そこでここでは, 今回の演習で実際に用いる RDBMS を紹介したいと思います.どの RDBMS を選択する かという基準として考えたのは,機能的に十分充実していること,皆さんがこの演習を離 れてからも,自分で手軽に利用できるように,オープンソースであることが望ましいこ と,さらに,WebDB を構成するための RDBMS として世界的に見ても大きなシェアを 持ち,皆さんの今後のエンジニアとしての活躍のための基礎トレーニングに相応しい(勉 *1 当初,IBM で開発された SQL は,Structured Query Language の略称であったと言われています. 第 3 章 SQL 18 強が無駄にならない)ものであること,の3つです.そして結論として,今回の演習では MySQL を RDBMS として使用することにしました. MySQL は,MySQL AB の創始者のひとりである Michael Widenius 氏(通称 Monty) が開発した RDBMS です.1995 年には,MySQL AB の前身である TcX DataKonsult AB 内で使用できるようになり,その後,Linux, Solaris, MacOS X, Windows 等で使用 できるように開発が進められました. 特徴として,マルチスレッド,マルチユーザの RDBMS であり,堅牢で処理速度が速 いという評価が一般的です.また,非常に多くのデータが扱えるため,応用範囲が広い と言われています.日本では,楽天,ライブドアのシステム,世界的には,米国 Yahoo! Finance, Google AdWords 等での利用実績があるそうです. また,C, C++, Java, Perl, PHP, Python, Ruby 等,豊富な API を持っていることも 魅力で,これだけ使える言語があれば,自分の得意な物がないと泣く人はほとんどいな いと思います.さらに,多言語対応で,日本語ならば,SJIS, EUC, Unicode で使用でき ます. なお,MySQL は商用プログラムとして購入することもできますが,構築したデータ ベースを商用に用いないのであれば,前述のように,オープンソースとしても無料配布さ れています.個人所有の PC が家にあるのであれば,是非積極的にソース(または実行 ファイル)を入手して,楽しんでみてはどうでしょうか? さて,話がすっかり今回用いる RDBMS である MySQL の紹介の方に行ってしまいま した.RDBMS の章でもお話ししていますが,SQL は RDBMS を構成する要素の一部分 という位置づけになります.よって,今回の演習では,RDBMS である MySQL の提供 する機能としての SQL を用いて,設計したテーブル群の構築,操作,修正,削除等を行っ ていきます. 3.1.2 必要となるシステム 前述のように,RDBMS には MySQL, DB を操作する言語として SQL を用います.ま た,後述しますが,最終的な目標のひとつとして WebDB システムの設計と構築がありま すので,Web 上でのデータ操作環境が求められます.よって,本演習では,Web サーバ, RDBMS,およびこれらの橋渡しをする実行環境を以下のように準備します. • OS:Solaris 10 (SunOS 5.10) • RDBMS:MySQL ver.5.1.30 • Web サーバ:Apache ver.2.0.63 • 実行環境:PHP ver.5.3.2 3.2 MySQL の基本操作 さて,堅苦しい話はこれで終わりにします.ここからは,上で紹介した MySQL を用い た実際のデータ操作についての簡単なインストラクションになります.念のために付け加 えますが,ここで紹介する操作が今後の演習で必要となる操作のすべてであるとは限りま 3.2 MySQL の基本操作 せん*2 .不足する知識は自ら補ってください. 始める前に注意を一言だけ. 3.2.1 一般的な注意 MySQL でコマンド(命令)を発行する際には,下記の4点に注意してください. • SQL コマンドに大文字・小文字の区別はありませんが,DB 名とテーブル名には区 別があります. • SQL コマンドは最後に「;」 (セミコロン)を付けて enter キーを押してください*3 . • COLUMNS, DATABASES のように,綴りが複数形になっているものがあるので 注意してください. • アルファベット,数字,その他の記号は半角で入力してください. お待たせしました.それでは始めましょう. 3.2.2 接続と終了 まず最初は,MySQL をコマンドラインから利用するためのツール「mysql」を起動し ます.次のようにコマンドを入力してください.下の例ではユーザ名は a205000 になっ ています. cse$ mysql -u a205000 -p Enter password: ここでパスワードを入れてあげると,次のようなメッセージが表示されます*4 . Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1688 Server version: 5.1.30-log Source distribution Type ’help;’ or ’\h’ for help. Type ’\c’ to clear the buffer. mysql> これで DB の操作が可能になります.「mysql>」はプロンプトで,皆さんからの入力 を DBMS が待っていますよ,という意味です.プロンプトに続いていろいろなコマンド を入れることでデータの操作をしますが,接続したときの画面に表示されているように, 「help;」と入力すると,mysql の操作に関するコマンドの説明が出てきます. *2 はっきり言えば,「すべてではありません」が正しいです. 「;」 (セミコロン)を忘れて enter キーを押した場合,プロンプトが「−>」となって止まってしまいま すが,これは mysql が, 「まだ入力は終わってないよね?」と言って残りの入力を待ってくれている状態 です.こんなときは慌てずに「−> ; 」と,セミコロンを入れてから enter キーを押しましょう. *4 微妙に違うところは許してくださいね. *3 19 第 3 章 SQL 20 また,mysql の起動は,どのディレクトリからでも行えるはずです*5 . 今度は反対に,mysql を終了してみましょう.これは簡単です. mysql> exit Bye cse$ 終了できましたか?あるいは別の方法として,こんなのもあります. mysql> quit Bye cse$ 3.2.3 DB 一覧 今度は DB の中身を見るコマンドです.これは小文字で入力しても OK です. mysql> SHOW DATABASES; 既に DB があれば,その名前が例えば次のように表示されます. mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | a205000db | | test | +--------------------+ 2 rows in set (0.00 sec) この例では,3 つの DB があることが分かります.さらに各 DB の中にはテーブルがあ りますから,これを確認することができます.例えば,a205000db という DB のテーブ ルにどんなものがあるか見るには, mysql> SHOW TABLES FROM a205000db; とやりますが,生憎からっぽなので, mysql> SHOW TABLES FROM a205000db; Empty set (0.00 sec) mysql> というメッセージが返ります. *5 mysql の実体は,/opt/webstack/mysql/5.1/bin の下にあります. 3.2 MySQL の基本操作 3.2.4 テーブル情報の確認 さらに,DB 内のテーブルのフィールド名(属性名)とその定義を見るときには,例え ば,a205000db という DB の中の,seiseki というテーブルの場合には, mysql> SHOW COLUMNS FROM a205000db.seiseki; と入力すれば良いのですが,まだそんなテーブルは無いので, mysql> SHOW COLUMNS from a205000db.seiseki; ERROR 1146 (42S02): Table ’a205000db.seiseki’ doesn’t exist mysql> と怒られてしまいました. この後,テーブルを作りますので,そのときに試してみてください. 3.2.5 テーブルの作成 それではいよいよ実際にテーブルを作ってみましょう.a205xxxdb または p205xxxdb という自分用の DB を使ってください. これ以降,a205000db というデータベース上にレ ストランガイドを作る例を示します. まず,どの DB を使うかの指定をしますので,USE a205000db と入力します. mysql> USE a205000db Database changed mysql> これで,使用する DB が変更されます.MySQL の起動直後には,特に指定をしない限 りどの DB も選択されていない状態になっています.この場合,DB 内のテーブルを操作 するときには毎回,「DB 名. テーブル名」と明示的に指定しなければなりません.これは 面倒なので,USE で指定することにより,いちいち DB 名を付けた指定をしなくて良い ようにします. その後,テーブルの定義をします.本来はよく考えて設計したテーブルを定義するので すが,ここでは簡単な例を挙げておきます.具体的には,テーブルの名前,フィールドの 名前とデータ型(大きさ),さらにフィールド値に空欄 (NULL) を許すかどうか,フィー ルド値が主キーであるかどうかを決めます.最後の 2 つはデフォルトで*6 NULL を許し, 主キーでない,となります. • テーブル名:list t • 識別番号のフィールド:id c 整数なので,数値型 INT と指定 • レストラン名のフィールド:name c 文字数は 16 文字以内として,文字列型,可変長文字列 VARCHAR(16) *6 特別に何も指定しなければということ.知ってますよね? 21 第 3 章 SQL 22 • 住所のフィールド:add c 同様に 32 文字以内として, VARCHAR(32) 上記のように指定するには,CREATE TABLE を使って,下記のように入力します. mysql> CREATE TABLE list_t (id_c INT, name_c VARCHAR(16), -> add_c VARCHAR(32)); Query OK, 0 rows affected (0.00 sec) mysql> Query OK と言っていますので,うまくいったようですが,先ほど使えなかった, SHOW TABLES を使って,本当にテーブルができたか確認します. mysql> SHOW TABLES; +---------------------+ | Tables_in_a205000db | +---------------------+ | list_t | +---------------------+ 1 row in set (0.00 sec) mysql> テーブルはできていましたね.さらにテーブルの中身を見てみます. mysql> SHOW COLUMNS FROM list_t; +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | id_c | int(11) | YES | | NULL | | | name_c | varchar(16) | YES | | NULL | | | add_c | varchar(32) | YES | | NULL | | +--------+-------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) mysql> こう表示されれば OK です.上記のテーブルの Null というところには,すべての Field で YES とありますから,これは NULL を許すということです.また,Key というのは主 キーであるかどうかなのですが,どれも空欄になっていますから,どれも主キーでないと いうことです.Default は,初期値として何が入っているかということなので,今回の例 では初期値が設定されていなかったため,NULL となっています. ここまでで,テーブルの枠は完成しました.次はデータの入力です. 3.2.6 データの追加 データはレコード単位(テーブルの行単位)で追加,挿入をします.まず,レコードを 追加するには次のようにします. 3.2 MySQL の基本操作 mysql> INSERT INTO list_t SET id_c=1, name_c="Yamamotoya", -> add_c="Nagoya-shi Naka-ku Sakae"; Query OK, 1 row affected (0.00 sec) mysql> または, mysql> INSERT INTO list_t (id_c,name_c,add_c) -> VALUES("2","Yaba-ton","Nagoya-shi Naka-ku Ohsu"); Query OK, 1 row affected (0.00 sec) mysql> のように,まとめても OK です.後者は, mysql> INSERT INTO list_t (id_c,name_c,add_c) -> VALUES("3","Atsuta-Horaiken","Nagoya-shi Atsuta-ku Kanbe-cho"), -> ("4","Furaibo","Nagoya-shi Naka-ku Kanayama"), -> ("5","Yokoi","Nagoya-shi Naka-ku Sakae"); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> のように書けるので,便利です. 3.2.7 データの検索 DB を構成するテーブルの第 1 号ができました.まずはこれ全体を表示してみましょう. mysql> SELECT * FROM list_t; +------+------------------+--------------------------------+ | id_c | name_c | add_c | +------+------------------+--------------------------------+ | 1 | Yamamotoya | Nagoya-shi Naka-ku Sakae | | 2 | Yaba-ton | Nagoya-shi Naka-ku Ohsu | | 3 | Atsuta-Horaiken | Nagoya-shi Atsuta-ku Kanbe-cho | | 4 | Furaibo | Nagoya-shi Naka-ku Kanayama | | 5 | Yokoi | Nagoya-shi Naka-ku Sakae | +------+------------------+--------------------------------+ 5 rows in set (0.00 sec) mysql> うまく行きました.では,WHERE 句を使って条件をつけて,検索をしてみます.こ の場合は, SELECT フィールド名 FROM DB 名. テーブル名 WHERE 条件式; 23 第 3 章 SQL 24 または,USE DB を指定した後なら, SELECT フィールド名 FROM テーブル名 WHERE 条件式; という SELECT コマンドを使います.例えば,識別番号 (id c) が「3」のレストラン を検索するなら,条件式は,id c=3 になります.やってみましょう. mysql> SELECT * FROM list_t WHERE id_c=1; +------+------------------+--------------------------+ | id_c | name_c | add_c | +------+------------------+--------------------------+ | 1 | Yamamotoya | Nagoya-shi Naka-ku Sakae | +------+------------------+--------------------------+ 1 row in set (0.00 sec) mysql> うまく行きました.上記の例では,WHERE 句で「=」を使って検索しましたが,条件 を表す場合に他の比較演算子,>, <, >=, <=, <> が使用できます.意味はそれぞれ, >, <, ≥, ≤, 6= です. 同様に WHERE 句と合わせて使用できるものに以下があります.自分で調べて使って みましょう. • IN 例:WHERE id c IN (1, 2, 5) • BETWEEN · · · AND · · · 例:WHERE id c BETWEEN 3 AND 5 • AND (&& も同義) 例:WHERE name c=”Yokoi” AND (&&でも良い) id c=5 • OR( || も同義) 例:WHERE name c=”Yaba-ton” OR( || でも良い)id c=1 • NOT 例:WHERE NOT (name c=”Furaibo” OR id c=2) • LIKE と NOT LIKE 例:WHERE add c LIKE ”%Atsuta-ku%” • IS NULL と IS NOT NULL 例:WHERE add c IS NULL 3.2.8 エイリアス 上記のような検索を行って,結果が返って来ると,テーブル作成時に付けたフィールド 名が一緒に表示されます.このフィールド名を別の適当な名前に変えて表示することがで きます.この別名を「エイリアス」と呼びます.書式は, フィールド名 AS エイリアス名 3.2 MySQL の基本操作 です. id c, name c, add c をそれぞれ,Number, Restaurants, Address に書き換えて表示さ せてみましょう. フィールド名 AS エイリアス名 mysql> SELECT id_c AS Number, name_c AS Restaurants, add_c AS Address -> FROM list_t; +--------+------------------+--------------------------------+ | Number | Restaurants | Address | +--------+------------------+--------------------------------+ | 1 | Yamamotoya | Nagoya-shi Naka-ku Sakae | | 2 | Yaba-ton | Nagoya-shi Naka-ku Ohsu | | 3 | Atsuta-Horaiken | Nagoya-shi Atsuta-ku Kanbe-cho | | 4 | Furaibo | Nagoya-shi Naka-ku Kanayama | | 5 | Yokoi | Nagoya-shi Naka-ku Sakae | +--------+------------------+--------------------------------+ 5 rows in set (0.00 sec) mysql> これで思った通りにできました. 3.2.9 レコードの並べ替え表示 取り出したレコードを,テーブルに登録してある順で表示するのでは不十分ですね.何 かの順に並べ替えて表示してみましょう.例えば,お店の名前のアルファベット順に並べ るには, ORDER BY フィールド名 ASC または DESC mysql> SELECT * FROM list_t ORDER BY name_c ASC; +------+------------------+--------------------------------+ | id_c | name_c | add_c | +------+------------------+--------------------------------+ | 3 | Atsuta-Horaiken | Nagoya-shi Atsuta-ku Kanbe-cho | | 4 | Furaibo | Nagoya-shi Naka-ku Kanayama | | 2 | Yaba-ton | Nagoya-shi Naka-ku Ohsu | | 1 | Yamamotoya | Nagoya-shi Naka-ku Sakae | | 5 | Yokoi | Nagoya-shi Naka-ku Sakae | +------+------------------+--------------------------------+ 5 rows in set (0.00 sec) mysql> うまくできましたね.ちなみに DESC を指定すると逆順になります. 25 第 3 章 SQL 26 3.2.10 テーブルの更新 次はテーブルの更新をやってみましょう. レコードの変更 最初はレコードの変更です.次の例を見てください. mysql> UPDATE list_t SET name_c="Furaibo Kanayama" WHERE id_c=4; Query OK, 0 rows affected (0.00 sec) Rows matched: 1 Changed: 0 Warnings: 0 mysql> SELECT * FROM list_t; +------+------------------+--------------------------------+ | id_c | name_c | add_c | +------+------------------+--------------------------------+ | 1 | Yamamotoya | Nagoya-shi Naka-ku Sakae | | 2 | Yaba-ton | Nagoya-shi Naka-ku Ohsu | | 3 | Atsuta-Horaiken | Nagoya-shi Atsuta-ku Kanbe-cho | | 4 | Furaibo Kanayama | Nagoya-shi Naka-ku Kanayama | | 5 | Yokoi | Nagoya-shi Naka-ku Sakae | +------+------------------+--------------------------------+ 5 rows in set (0.00 sec) mysql> UPDATE を使って4番のレストランの名前を Furaibo から Furaibo Kanayama に変 更しました.うまくいって満足ですが,このとき,WHERE 句を書き忘れて enter して しまうと大変です.どうなるかは · · ·.考えてみましょう. レコードの削除 次はレコードの削除です.次の例を見てください. mysql> DELETE FROM list_t WHERE id_c=4; Query OK, 1 row affected (0.00 sec) mysql> SELECT * FROM list_t; +------+------------------+--------------------------------+ | id_c | name_c | add_c | +------+------------------+--------------------------------+ | 1 | Yamamotoya | Nagoya-shi Naka-ku Sakae | | 2 | Yaba-ton | Nagoya-shi Naka-ku Ohsu | | 3 | Atsuta-Horaiken | Nagoya-shi Atsuta-ku Kanbe-cho | | 5 | Yokoi | Nagoya-shi Naka-ku Sakae | +------+------------------+--------------------------------+ 4 rows in set (0.00 sec) mysql> 3.2 MySQL の基本操作 DELETE FROM で識別番号4のレストランをレコードごと削除しました.SELECT * で確認すると,意図した通り4番のレストランのデータが消えています.このとき, WHERE 句の指定を失敗して意図していないものを消してしまわないように気をつけて ください. レコードごとではなく,あるレコードのあるフィールドのデータだけ消したい場合があ りますね.このときはレコードの変更のときと同様にして,SET フィールド名=NULL とすれば空欄になります. さあ,だんだん MySQL の操作も慣れてきましたね.もう少し説明を続けますが,こ れまでより簡単な解説にとどめます.その代わり,皆さんは自分で調べて試して見てくだ さい. 3.2.11 フィールドの操作 フィールドの追加の書式は以下のようになります. ALTER TABLE テーブル名 ADD 新フィールド名 データ型 実行結果の例は, mysql> ALTER TABLE list_t ADD tel_c VARCHAR(8); Query OK, 4 rows affected (0.02 sec) Records: 4 Duplicates: 0 Warnings: 0 mysql> SHOW COLUMNS FROM list_t; +--------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------+-------------+------+-----+---------+-------+ | id_c | int(11) | YES | | NULL | | | name_c | varchar(16) | YES | | NULL | | | add_c | varchar(32) | YES | | NULL | | | tel_c | varchar(8) | YES | | NULL | | +--------+-------------+------+-----+---------+-------+ 4 rows in set (0.00 sec) mysql> 確かに,tel c というフィールドが増えていますね. 同様にして,フィールド名の変更,フィールド定義の変更ができます.これは上記の ADD の代わりに CHANGE を使います. 3.2.12 テーブルの操作 テーブル名の変更は,下記の例のように,ALTER TABLE ∼ RENAME AS ∼ を使 います. mysql> ALTER TABLE list_t RENAME AS restaurant_t; Query OK, 0 rows affected (0.00 sec) mysql> SHOW TABLES; 27 第 3 章 SQL 28 +----------------+ | Tables_in_test | +----------------+ | restaurant_t | +----------------+ 1 row in set (0.00 sec) mysql> また,テーブル自体を削除したい場合は,DROP TABLE を使います.でも,間違っ て大事なテーブルを消さないように気をつけてください. mysql> DROP TABLE restaurant_t; Query OK, 0 rows affected (0.00 sec) 3.2.13 フィールド属性 この辺りも,ごく簡単に触れます. 1. NULL と NOT NULL テーブル定義のときに,フィールドに入力するデータに NULL 値を許すかどうか を設定します.テーブル名,データ型の後に書き加えます. 2. 初期値の追加 各フィールドに対して,初期値を設定します.NULL と同様にテーブル定義の際 に,テーブル名とデータ型の後に 「DEFAULT 初期値」のように書き加えます. 3. プライマリキー(主キー) プライマリーキーを設定すると,重複する入力を許しません.1つのテーブルにつ きひとつのフィールドにのみ設定できます.これも上記と同様に,テーブル名と データ型の後に,PRIMARY KEY を書き加えます. 4. オートインクリメント フィールドにデータを入力するたびに数値が1ずつ自動的に増えるようにできま す.同じ値が入らないので,レコードを一意に指定する ID などを振りたいときな どに使います.これも上記と同様のやり方で,AUTO INCREMENT と書き加え ます. 5. ZEROFILL 2 桁以上を指定した数値フィールドに,それ未満の数値を入力したとき,上位の桁 を 0 で埋める設定です.これまた同様にして,ZEROFILL と書き加えます. 6. UNSIGNED 数値フィールドに UNSIGNED を指定すると,0 以上の数値のみが入力可能にな 3.2 MySQL の基本操作 ります. 3.2.14 関数 一番単純な使い方は,mysql のプロンプトからすぐに「SELECT 関数」と入力するこ とですが,勿論,様々に組み合わせて使うこともできます.引数の無いものもありますか ら注意してください. 集計関数 主にあるフィールドに所属するすべてのデータについて計算します.その場合,引数は フィールド名になります.GROUP BY と併用して,グループ毎の計算が可能です.ご くごく代表的なものだけ下記に示します. • 平均値:AVG( ) • 合計値:SUM( ) • 最大値:MAX( ) • レコード数集計値:COUNT( ) 算術演算子を使った計算 加算,減算,乗算,除算,剰余は,順に,+, −, ×, /, % で使用できます.これも関数 と同様に,SELECT と組み合わせて使うのが一番単純ですが,通常は条件式等に組み合 わせて利用する場面が多いと思います. 計算結果のフィールドへの入力 既存のフィールドのデータを使って計算し,その結果を別のフィールドに書き込むこと がしばしば行われます.ALTER TABLE でフィールドを追加して,UPDATE を使っ て SET 以下でフィールド名 = 計算式(関数や算術演算子とフィールド名の組み合わせ) とすれば可能です.想像できますか? 3.2.15 結合 実際のデータ操作では,テーブルの結合が重要になります.理論的な話は 2.3 節「デー タ操作」のところで詳しく述べましたが,実際の SQL を用いたデータ操作ではどうなっ ているのでしょうか? 例を挙げて簡単に説明しましょう.これまで,レストランガイドの例をお話しして来ま したが,これを続けます.今,restaurant t という名前のテーブルがあり,下記のように なっているものとしましょう. +------+------------+---------------------+--------+ | id_c | name_c | add_c | eval_c | +------+------------+---------------------+--------+ | 1 | Yamamotoya | Naka-ku Sakae | NULL | | 2 | Yaba-ton | Naka-ku Ohsu | NULL | | 3 | Horaiken | Atsuta-ku Kanbe-cho | NULL | 29 第 3 章 SQL 30 | 4 | Furaibo | Naka-ku Kanayama | NULL | | 5 | Yokoi | Naka-ku Sakae | NULL | +------+------------+---------------------+--------+ このテーブル内の eval c というフィールドは,各レストランの評価を表すものと思っ てください. さて,ここでレストランの評価をまとめたテーブルを作ります.こんな感じです. mysql> CREATE TABLE rating_t (gradeid_c TINYINT AUTO_INCREMENT -> NOT NULL PRIMARY KEY, comment_c VARCHAR(10) NOT NULL); Query OK, 0 rows affected (0.00 sec) mysql> つまり,rating t というテーブルを作って,そのフィールドとして,桁数の小さい整 数型の gradeid c と,10 文字の可変長文字型の comment c を用意しました.このとき, gradeid c には,オートインクリメント,NOT NULL,さらにプライマリーキーを指定し ています.理由は分かりますね?このフィールドは主キーにしたいので,入力に際して, 重複した値を与えてしまったり,空欄になってしまったりしたら困るからです. これらにそれぞれ,評価ランク ID 番号と,それに対応する評価コメントを入れます. こんな感じです. mysql> INSERT INTO rating_t (comment_c) -> VALUES("excellent"), ("wonderful"), ("yummy"), -> ("OK"), ("poor"), ("terrible"); Query OK, 6 rows affected (0.00 sec) Records: 6 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM rating_t; +-----------+-----------+ | gradeid_c | comment_c | +-----------+-----------+ | 1 | excellent | | 2 | wonderful | | 3 | yummy | | 4 | OK | | 5 | poor | | 6 | terrible | +-----------+-----------+ 6 rows in set (0.00 sec) mysql> 各レストランの評価を決めて,入力したとしましょう*7 .こんな具合です. +------+------------+---------------------+--------+ | id_c | name_c | add_c | eval_c | +------+------------+---------------------+--------+ *7 あくまでも例ですから. 3.2 MySQL の基本操作 | 1 | Yamamotoya | Naka-ku Sakae | 2 | | 2 | Yaba-ton | Naka-ku Ohsu | 3 | | 3 | Horaiken | Atsuta-ku Kanbe-cho | 1 | | 4 | Furaibo | Naka-ku Kanayama | NULL | | 5 | Yokoi | Naka-ku Sakae | 3 | +------+------------+---------------------+--------+ これでリレーションを形成する2つのテーブルができました.それでは,これらを実際 に結合してみましょう. 左外部結合と右外部結合 まずは左外部結合です. mysql> SELECT * FROM list_t LEFT JOIN rating_t ON eval_c=gradeid_c; +------+------------+---------------------+--------+-----------+-----------+ | id_c | name_c | add_c | eval_c | gradeid_c | comment_c | +------+------------+---------------------+--------+-----------+-----------+ | 1 | Yamamotoya | Naka-ku Sakae | 2 | 2 | wonderful | | 2 | Yaba-ton | Naka-ku Ohsu | 3 | 3 | yummy | | 3 | Horaiken | Atsuta-ku Kanbe-cho | 1 | 1 | excellent | | 4 | Furaibo | Naka-ku Kanayama | NULL | NULL | NULL | | 5 | Yokoi | Naka-ku Sakae | 3 | 3 | yummy | +------+------------+---------------------+--------+-----------+-----------+ 5 rows in set (0.00 sec) mysql> 予想通りの結果になっていますか?今度は右外部結合を試してみましょう.SQL 文は 上記の場合の「LEFT JOIN」を「RIGHT JOIN」に変えれば OK です. mysql> SELECT * FROM list_t RIGHT JOIN rating_t ON eval_c=gradeid_c; +------+------------+---------------------+--------+-----------+-----------+ | id_c | name_c | add_c | eval_c | gradeid_c | comment_c | +------+------------+---------------------+--------+-----------+-----------+ | 3 | Horaiken | Atsuta-ku Kanbe-cho | 1 | 1 | excellent | | 1 | Yamamotoya | Naka-ku Sakae | 2 | 2 | wonderful | | 2 | Yaba-ton | Naka-ku Ohsu | 3 | 3 | yummy | | 5 | Yokoi | Naka-ku Sakae | 3 | 3 | yummy | | NULL | NULL | NULL | NULL | 4 | OK | | NULL | NULL | NULL | NULL | 5 | poor | | NULL | NULL | NULL | NULL | 6 | terrible | +------+------------+---------------------+--------+-----------+-----------+ 7 rows in set (0.00 sec) mysql> 内部結合 内部結合は,同様に下記のようにできます. mysql> SELECT * FROM list_t INNER JOIN rating_t ON eval_c=gradeid_c; 31 第 3 章 SQL 32 +------+------------+---------------------+--------+-----------+-----------+ | id_c | name_c | add_c | eval_c | gradeid_c | comment_c | +------+------------+---------------------+--------+-----------+-----------+ | 1 | Yamamotoya | Naka-ku Sakae | 2 | 2 | wonderful | | 2 | Yaba-ton | Naka-ku Ohsu | 3 | 3 | yummy | | 3 | Horaiken | Atsuta-ku Kanbe-cho | 1 | 1 | excellent | | 5 | Yokoi | Naka-ku Sakae | 3 | 3 | yummy | +------+------------+---------------------+--------+-----------+-----------+ 4 rows in set (0.00 sec) mysql> その他の結合 その他にも,自己結合,交差結合,和結合 · · · 等がありますが,自分で調べてやってみ てください.これ以上の説明は省略します. こんなところで,だいたいの SQL の基本操作は理解できたでしょうか? 次は PHP と Web アプリケーションの話題に進みます. 33 第4章 PHP と WebDB の連携 4.1 PHP について PHP (PHP:Hypertext Preprocessor) については,既に少なくとも基礎的な内容に限 れば,受講者の皆さんは,十分学習済みだと思います.本演習では,その PHP のスクリ プトと HTML を組み合わせ,DBMS を操作する実行環境を実現して,WebDB システム を構築することを目指します. PHP はオープンソースのスクリプト言語で,Web アプリケーション開発では現在,大 変高い人気があります.その理由としては,他の言語と比較して習得し易いこと,多くの ライブラリが最初から組み込まれていること,などを挙げることができるでしょう. プログラミングでは,関数を実行する形式で処理を記述でき,100 以上の関数が準備さ れているため,これを生かすことで比較的複雑な処理も容易に実装できるというメリット もあります. これ以上の PHP に関する説明は省略して,どんどん先に行きましょう. 4.2 HTML フォームからの DB 操作 さて,この演習での目標のひとつは,Web ブラウザから DB を操作できるシステムを 構築することです.既に受講者の皆さんは,HTML と PHP が連携したシステムの構築 の経験がありますので,どのようにこれらを組み合わせて使うのも自由ということにしま しょう. 基本的な WebDB システムでは,ユーザが検索条件を記入したり,検索のためのキー ワード等を変数としてシステムに渡してあげるような機能が必須です.それにはまず入力 画面が必要になりますから,これを HTML で書くことになります. また,検索結果を表示させるために,その枠組みを HTML で書く必要があります.そ して,その中に PHP スクリプトを埋め込み,RDBMS と Web サーバとの橋渡しの実行 環境を作って*1 ,うまく検索結果を受け取れるようにすれば良いですね. 本演習で用いる環境下で実現する WebDB 操作のための典型的な処理をまとめると,次 のようになります. *1 前述のように,このような実行環境の作り方はいろいろありますが,本演習では,HTML に PHP スク リプトを埋め込む方法で実現しましょう. 第 4 章 PHP と WebDB の連携 34 1. MySQL への接続 2. 使用する DB の指定 3. SQL コマンドの発行 4. データ表示 5. MySQL との接続解除 これらの処理に対応する関数は,スクリプト中で次のように用いられます. 4.2.1 MySQL への接続と使用する DB の指定 まず MySQL への接続ですが,これは,mysql connect() という PHP の関数を使いま す.また,使用する DB を指定するには,mysql query() という,やはり PHP の関数を 使います.例を挙げると,こんな感じです. $conn = mysql_connect($sv, $user, $pass) or die("Connection Error!"); mysql_select_db($dbname) or die("Connection Error!!"); まず,mysql connect() 関数ですが,引数を3つ取っています.それぞれ順に,サーバ 名,ユーザ名,パスワードの入った変数だと思ってください.結果として返り値を返し て,$conn に代入しますが,接続に失敗したとき,後ろの or die(”メッセージ”) で,その 処理を終了し,引数のメッセージを返すようになっています.システム構築の途中では, 失敗したことが分かるので,このメッセージは有効です.ただしシステム運用時にはどう するか考えてください. 次の mysql select db() は,引数がひとつで,データベース名の入った変数です.同様 に失敗したときのために or die() が後ろに控えています. 4.2.2 SQL コマンドの発行 これはいろいろありますから,ひとつだけ例を挙げましょう.上で指定したデータベー ス内に,list t というテーブルがあって,そこから id c,name c を name c のアルファ ベット順に出力するには,こんな感じです. $sql = "SELECT id_c, name_c FROM list_t ORDER BY name_c"; $res = mysql_query($sql, $conn) or die("Data Retrieval Error!"); mysql query() でクエリを投げる(検索要求を出す)のですが,引数として SQL 文と, さっきの mysql connect() の返り値の入った変数 $conn が入っていますね.SQL 文につ いては,勿論長い文を引数として直接書き込みたくないので,その前に変数(文字列を表 す)に格納しておいて,それを渡すようにしています.ところで $conn にはいったい何 が入っているのでしょう?解りますか?*2 SELECT 文以外の SQL 文も同様に書けます.例えば,INSERT INTO ∼ VALUES ∼ でデータの追加,DELETE FROM ∼ WHERE ∼ でデータの削除,UPDATE ∼ *2 解らない人はどうするかって? はい,調べて調べて.PHP の web サイトに立派なマニュアルがありま す. 4.2 HTML フォームからの DB 操作 SET ∼ でデータの更新が同じようにできます.つまり,mysql query() に入れて使えば 良いのです.ここではこれ以上説明しませんが,必要な SQL 文については,マニュアル を見て,どんどん調べてみてください. 4.2.3 データ表示 データの表示には,その 1 レコード分のデータが文字列 $res に入っているとすると, 例えばこんな関数を使います. echo "<table border=\"1\">"; echo "<tr>"; echo "<td>ID</td>"; echo "<td>Name of Restaurant</td>"; echo "<td>Address</td>"; echo "</tr>"; while ($row = mysql_fetch_array($res, MYSQL_ASSOC)) { echo "<tr>"; echo "<td>".$row["id_c"]."</td>"; echo "<td>".$row["name_c"]."</td>"; echo "<td>".$row["ad_c"]."</td>"; echo "</tr>"; } echo "</table>"; 問題の関数は,mysql fetch array() です.MYSQL ASSOC も気になりますが,これ も含めて自分で調べてみてください.周りの HTML や PHP の記述が解らない人は · · ·, やっぱり復習するしかないでしょう. 4.2.4 MySQL との接続解除 これは簡単で, mysql_close($conn); となります. 蛇足ですが,ここまでたくさんの mysql xxx() という関数がありましたね.PHP では 多くの MySQL 向けの関数が準備されています.これも一度マニュアルの関数一覧あた りで調べてみるのが良いでしょう. ここから先は,受講者個人が HTML と PHP スクリプトにより,好きなようにやって 良いのですが,参考のために,上で説明した例をまとめて,データ表示をするプログラム の例(の一部)を書いておきます.必要に応じて参照してください. 4.2.5 データの表示用 HTML と PHP スクリプトの例 <html> <head> 35 第 4 章 PHP と WebDB の連携 36 <title>Data Indication</title> </head> <body> <h3>データを表示する</h3> <?php // データベースとの接続の準備 $sv = "localhost"; $dbname = "sugawara"; $user = "sugawara"; $passwd = "xxxxx"; // 文字コード $enc_disp = "EUC-JP"; $enc_db = "EUC-JP"; // データの文字コード変換をする関数(ここで自分で定義する) function cnv_enc($string, $to, $from) { // 文字コードを変換する $det_enc = mb_detect_encoding($string, $from . ", " . $to); if ($det_enc and $det_enc != $to) { return mb_convert_encoding($string, $to, $det_enc); } else { return $string; } } // データベースとの接続 $conn = mysql_connect($sv, $user, $passwd) or die("Connection Error!"); mysql_select_db($dbname) or die("Conection Error!!"); // SQL コマンドによるデータ検索 $sql = "SELECT id_c, name_c, add_c FROM list_t ORDER BY name_c"; $res = mysql_query($sql, $conn) or die("Data Retrieval Error!"); // データの表示 echo "<table border=\"1\">"; echo "<tr>"; echo "<td>ID</td>"; echo "<td>レストラン名</td>"; echo "<td>住所</td>"; echo "</tr>"; while ($row = mysql_fetch_array($res, MYSQL_ASSOC)) { echo "<tr>"; echo "<td>".$row["id_c"]."</td>"; echo "<td>".cnv_enc($row["name_c"], $enc_disp, $enc_db)."</td>"; echo "<td>".cnv_enc($row["add_c"], $enc_disp, $enc_db)."</td>"; echo "</tr>"; } echo "</table>"; // データベースとの接続を解除 mysql_close($conn); 4.2 HTML フォームからの DB 操作 ?> </body> </html> ちょっとだけ注釈を付けます.この中で,文字コードについて何か処理をしています が,これは,データベース中のデータを表示する際に,その文字コードを設計者の意図 通りに変換するためのものです.mb detect encoding() という関数が使われていますが, これは第 1 引数の文字列の文字エンコーディングを検出し,検出した文字エンコーディ ングを返します.ここでは,表示する文字列のコードも,データベースに格納されている 文字列のコードも,”EUC-JP”としていますから,この場合は変換する必要がないのです が,違う場合には必要になります.文字列の変換は,mb convert encoding() 関数を使っ ています. 文字コードについては,よく考えてください*3 .うまく表示されないと使えませんか らね. *3 このような変換をしなくて良いように,予め,データベースに格納する文字列と表示される文字列のコー ドは同じであるという前提に立って設計しても良いです.勿論,そうでない方が一般的なシステムとな り,作るのが難しくなる訳ですけど. 37 39 第5章 Web Database システムの設計と 構築 5.1 課題の提示 この演習で最終的に設計・構築するシステムの条件を以下に示します.これを満たして いれば,あとは自由としますので,受講者が各々好きな用途とそれに必要な機能を考え て,自分のオリジナリティを主張できるようなシステムを設計,構築,提示してくれるこ とを期待しています*1 . • HTTP, PHP, MySQL を組み合わせることにより,WebDB 機能を備えたシステ ムを構築する. • 冗長性を排除し,一貫性のある複数のテーブルからなる RDB を用いたデータを扱 うシステムであること. • 最大の属性数を持つテーブルは,その属性数が少なくとも 3 以上であること. • システムに必要な機能を実現するために,レコードの追加,削除を行うことが必要 であり,これを web ブラウザ上から操作できること. • システムに必要な機能を実現するために,あるレコードのある属性について個別に 修正することが必要であり,これを web ブラウザ上から操作できること. • システムに必要な機能を実現するために,ある条件で,それに該当するレコードま たはその一部属性を取り出すことが必要であり,これを web ブラウザから操作で きること. • ユーザにとって操作しやすい画面遷移があること. • できる限り見栄えが良いこと. • できる限り現実に役に立つシステムに近いこと*2 . *1 例えば,レストランガイドや,住所録などでもいいですが,これだけだとつまらないので何か自分独自の 工夫が必要ですね. *2 時間の制約もあるので,本当に役に立つものを作るのは難しいですが,機能を増やせば使えそうなものを 意識して設計してください. 第5章 40 Web Database システムの設計と構築 データベースに接続 データの検索 データの追加 データの変更 データの削除 データベース接続を解除 図 5.1 データベース処理の流れ 5.2 設計方針 どのようなシステムを構築するか,おおまかなアイデアが固まったら,下記のような内 容について考えておくと,システム構築がうまく行くと思います. 5.2.1 テーブル構成 意図するシステムによって,扱うデータが異なりますが,それがどんな属性を持つレ コードから構成されていて,提供するサービスでは,何らかの操作を行うことにより,そ こからどんな情報を引き出す,あるいは追加,修正する必要があるのか,考えてみてくだ さい. また,演習第 1 回で説明した正規化のことも思い出して,一貫性のある,無駄の少ない テーブルを構成することを意識してください. 5.2.2 データベース処理の流れ データベース処理は,おおまかに言うと,「データベースへの接続」,「データの読み書 き」,「データベースへの接続解除」の 3 段階になります. データベースへの接続では一般に,そのデータベースがスクリプトと同じ計算機上にあ る必要はありません.スクリプトから接続できさえすれば OK です. データの読み書きは,さらに「参照」と「更新」に分類できます.参照する処理には, 「データ検索」 ,更新する処理には, 「データの追加」 , 「変更」 , 「削除」などがあります.こ れを図 5.1 に示します. これらの処理では,データベースへの接続と接続解除に,mysql connect() 関数, mysql close() 関数がそれぞれ使われることは前述の通りです.また,データの読み書き では,SELECT(データの取り出し,条件をつければ検索),INSERT(データの追加), UPDATE(データの変更),DELETE(データの削除)がそれぞれ使えることも,すで に理解していると思います. ちなみに,mysql close() を使わなくても,持続的でない接続は,スクリプト終了時に, 自動的に解除されます. 5.3 システム構築 41 終了画面1 初期画面 入力値により 遷移先が異なる 終了画面3 終了画面2 図 5.2 画面遷移の例 5.2.3 画面遷移 データの処理の流れがフローチャートなどにまとめられたら,それに対応する形で,画 面遷移についても考えておくと良いでしょう. 初期状態から始まって,何らかの処理をする度に,システムの状態は変化し,それに 従って,ユーザに提示する情報も変化します.ですから,システムが持つ内部状態に合わ せてそれぞれに対応した画面を準備することになります. まず,初期画面に何らかの入力があり,その入力に従って,取りうる状態は何通りかに なります.それらすべての場合の画面を準備して,その各々で同様に次の入力に備えま す.画面遷移はどんどん枝分かれしていきますね.これを図示すると図 5.2 のようになり ます. 5.3 システム構築 テーブル構成,処理のフローチャート,画面遷移設計ができたら,いよいよプログラム を書いてみましょう. その前に,DB 上にテーブルを準備することは演習第 1 回で得た知識で十分できるはず ですから,この時点で,これは準備しておいた方が良いかもしれません.システムが出来 上がるに従って,テーブル構成に不都合が出てきたらその都度見直せば良いのです. プログラミングでは,システムをいくつかの部品に分解して組み立て,それを繋ぎあわ せます.それぞれの部品がきちんと動作することを確認してから繋ぎあわせることを考え た方が作業がうまく行くと思います.部品の要素として一番多いのは各状態に対応する画 面だと思います.複雑な処理を行うシステムであるほど,画面の数は増えますからね. 出来上がった部品点数が増え,繋ぎあわせてゆくと,いろいろ不都合も出て来るでしょ うから,その場合はその度に修正して,部品同士がうまく協調するようにしましょう. 設計→部品作成とテスト→部品間の接続→不具合の修正とフェイズが進んで,本質的に うまく行かないことが出てきたら*3 ,根本から見直すため,設計のフェイズに戻ります. これでシステム構築のプロセスのループができましたから,良いシステムが出来上がるま で,このループを何度も繰り返してゆきます. *3 普通最初はたくさん出るでしょう. 42 第5章 Web Database システムの設計と構築 あとは,既に学習済みの PHP のプログラミングスキルを駆使して,自分のやりやすい ようにやるのが一番かも知れません.これ以上はくどくど書きません.皆さんが,それぞ れ個性的なシステムを構築してくれることを期待しています. 43 第6章 課題とレポートの提出 この章では,レポートについて,求められる内容と,提出方法について説明します. 6.1 提出課題 レポートは,3 回に分けて提出してもらいます.また,3 回目のレポートの提出の際に は,これに対応するスクリプトと RDB のテーブルを演習環境の自分のディレクトリに置 いてもらいます.これらについて下記に述べます. 6.1.1 第 1 回レポート RDBMS について理解し,MySQL を用いて,以下の操作を行った結果を報告してくだ さい.なお,各操作では,その動作や結果が分かるように,画面上に表示される結果を提 示してください*1 .操作の細かな内容は受講者に任せます.また,下記の操作内容は必要 条件ですから,もっといろいろ試してみた人は,報告内容を増やしても構いません*2 . 1. 自分で適当な独自のテーブルを複数考案する*3 .ただし,属性数が最大のテーブル は 3 以上の属性を持つものとする. 2. 以下の 10 種類の操作を行う. • テーブルの定義 • データ入力(テーブルの作成) • レコードの追加 • あるレコード内に存在する,ある属性値の更新 • レコードの削除 • テーブル名の変更 • where 句により条件をつけた検索(3 通り以上,ただし関数を合わせて用いる ものを含むこと) • レコードの並べ替え • 左右外部結合 *1 本テキストの 3.2 節のようなレポートになることが望ましい. といっても,レポートのページ数は常識的な枚数でお願いします.グラムで測って評価する訳ではありま せんので,勿論評価は内容が勝負です.(20 ページぐらいまでなら見ますけど · · ·.) *3 3.2 節の例ではレストランガイドでしたね.ここでは自分独自のものを考案してください.当然他の人と は違うものを求めます. *2 第 6 章 課題とレポートの提出 44 • 内部結合 6.1.2 第 2 回レポート 自分で定義し,作成したテーブル*4 のひとつについて,その一覧を web ブラウザ上に表 示するための,HTML と PHP を用いたスクリプトを書き,その動作結果を報告してくだ さい.また,報告書の最後に,その注釈付きのスクリプトを添付してください. 余力があれば,下記の動作を行う同様のスクリプトを作成し,同じように報告書に加え てください. • ユーザ入力によりレコードを追加した後,テーブル一覧を出力して確認する • 何らかの方法でユーザの指定するレコードを削除した後,テーブル一覧を出力して 確認する 勿論さらに余力のある人は,同様にもっと多くの動作を行うスクリプトを書いて報告し てくれても結構です. 6.1.3 第 3 回レポート 5章の内容について,報告してください.以下の内容を必須とします. 1. システム名*5 2. 目的 このシステムは何をするためのものなのか? 説明してください. 3. 機能(仕様) システムの持つ機能をすべて記述してください. 4. 設計方針 どのような手順で設計したかについて記述してください.また,画面遷移の構成 や,テーブルの構成等についても説明してください. 5. マニュアルと動作例 操作マニュアルを作成し,受講者のディレクトリで動作させるためのマニュアルを 作成してください.このとき,実現したすべての機能を試してみることができるよ うに記述することを条件とします.また,それらの機能のうちの代表的な(特徴的 な)ものについては,その動作例を図示してください*6 . 6. 特長 システムを構築するに当たって,工夫したところ,他には無いと主張できる機能な どについてまとめてください.レポートの中で,ここが最も重要です. 7. 改善点 今回の演習中には完成,改善できなかった機能,そのための方法論等についてまと めてください. *4 演習の第 1 回で作成したテーブルで構いません. どんなことができる WebDB なのか,見当がつくような名前が良いです.独創的な名前を希望します. *6 これは,次の「特長」で述べても構いません. *5 6.2 提出方法 8. 感想 演習を通しての感想を自由に述べてください. 9. 連絡先メールアドレス 動作チェック等で質問したいことがある場合に,連絡を取りたいので,最も良く連 絡のつくアドレスを記述してください. 10. 付録 システムに関わる RDB テーブルの一覧と,注釈付きの全スクリプトを添付してく ださい. このレポートに添付したスクリプトと同じものを,自分の演習環境のディレクトリに 置き,ユーザ「shinji」が実行できるようにしてください.実行の仕方はレポート中のマ ニュアルに示してください.また,このファイルとテーブルは,成績が確定するまでその ままにしておいてください.確定の時期は web 上でお知らせします. 6.2 提出方法 6.2.1 書式 フォーマットは特に設けませんので,読み易さに配慮して適切に記述してください. ファイル形式は,PDF,または MS Word とします. なお,当然のことですが,すべてのレポートには,冒頭に学籍番号と氏名を記入するこ とを忘れないでください. 6.2.2 提出先と提出期限 提出は以下のように,電子メールで行ってください.本文は特に必要ありません. • 宛先 shinji at nitech.ac.jp*7 • 件名 webdb1-20115xxx(学籍番号 20115xxx の受講者の第 1 回レポートの場合) • 添付ファイル名 webdb2-20115xxx.pdf(学籍番号 20115xxx の受講者の第 2 回 レポートで,PDF ファイルでの提出の場合) レポートの受理は,web 上に提示しますので必ず確認してください*8 .何らかの理由 で*9 レポートがうまく届かない場合には,その提出が web に反映されていない訳ですか ら,皆さんにはすぐ解るはずですので,速やかに連絡をください*10 . 第 1 回,第 2 回レポートの提出期限は,それぞれ,演習第 1 回,第 2 回の次週の金曜日 17:00 必着とします(締め切り厳守).第 3 回レポートの提出期限は演習中に指示します. *7 *8 at は@です.念のため. 受理から提示まで多少時間差があります.web の更新日時に注目してください. 多くの場合は,メーラのフィルタに引っかかるケースです. *10 これを放置した場合,折角提出したレポートが受理されず,結果として単位を落とすこともあり得ます. *9 45 47 第7章 プレゼンテーション 本演習テーマの締めくくりに,プレゼンテーションを行ってもらいます.これまで設 計・構築した WebDB システムについて,その独創性や特長,工夫した点などを,他の人 にわかりやすく説明してください.実際にスライドを準備して発表をし,質疑応答を経験 することで,WebDB システムについての,さらに深い理解を得ることを目指します. また,発表は英語を用いることで,今後技術者として避けることのできない国際的な情 報発信の技術の基礎を身につけることも同時に期待しています. この章では,そのプレゼンテーションの準備と発表の仕方について簡単に説明します. 7.1 プレゼンテーションの一般的な留意事項 7.2 本演習でのプレゼンテーションについて 前述の,3 回のレポートの他に,プレゼンテーションと質疑応答も,この演習の評価対 象になります.しっかり準備をしてください. 7.2.1 形式とルール 以下のような形でプレゼンテーションを行います. • PC 上で表示できるスライドをプロジェクタで投影し,全員が1人ずつ,プレゼン テーションを行う • 内容として,構築したシステムの,用途と動作概要,特長(独創性,工夫した点) の説明を含むものとする • プレゼンテーションは英語で行う • 質疑応答も原則英語で行う • 持ち時間は,発表 7 分,質疑応答 3 分の計 10 分とする • 発表は,良く練習しておくこと • 持ち時間を超過しないように十分留意すること 7.2.2 スライド作成のルールとヒント 以下に従って,プレゼンテーション用のスライドを作成してください. 第 7 章 プレゼンテーション 48 • 原則として,MS PowerPoint を使用する*1 • スライド作成や,プレゼンテーションを行うために自分の PC を使用することを認 めるが,プロジェクタとの接続が可能なものであることを条件とする • 英語で記述すること • スライドの枚数は,英語での発表を勘案すると,5∼6枚程度が適当か? • 1 枚目には,タイトルと学籍番号,名前を書く 7.2.3 発表でのちょっとしたテクニック • 指し棒,またはポインタを持つ手は,スクリーンに向かって左に立つ場合は左手, 右に立つ場合は右手とし,できるだけ聴衆に背を向けないようにする • 聴衆とできる限りアイコンタクトを試みる • 大きな声で,はっきりと話すことを心がける 7.2.4 発表で使える便利な英語表現 いろいろ書いてみようと思いましたが,たくさんありすぎてまとめきれません.英語プ レゼンテーション技術に関して参考になりそうな書籍は多数出ていますので*2 ,各自調べ てみてください.また,第6回の演習時間中にも,基本的なものを紹介するつもりです. *1 PowerPoint 以外を使用する場合は相談してください. *2 一例を挙げると,志村史夫,“理科系のための英語プレゼンテーションの技術,” ジャパンタイムズ (1996). 49 おわりに この演習テーマを一通り終えた受講者の皆さんは,その内容について,どのように感じ たでしょうか? 以外に簡単だったと思った人もいるでしょう.逆に,思いのほか難し かったと思う人も,多かったかも知れません.でも,難しくて大変だったとしても,最後 までやり終えたことは,その人にとって,大きな収穫になると思います. 今回は,時間の制約等もあり,下記のような内容に踏み込むことができませんでした. 受講生の皆さんの中には,自分でこのような問題に気づいて取り組んでくれた人もいたで しょうが,大部分の人はそこまで行かなかったかもしれません.でも,折角学習を始めた のですから,できることならこれからも,ひとりでも多くの皆さんが,WebDB への関心 を持ち続けてくれるよう期待したいと思います. • RDBMS におけるユーザと管理者の別を意識した処理の流れ • 複数のユーザが同時に利用する場合の排他制御(ロック) • テーブル一覧表示の際に,一度の表示できるレコード数の制限 • フォームを用いた場合の,セキュリティ(悪意のあるコードへの対処) さて,これで終わりです.今回の演習が,今後の皆さんの学習に役立ってくれることを 願っています. レポートの提出,忘れないでくださいね.
© Copyright 2024 Paperzz