<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>@blog.justoneplanet.info &#187; データベース</title>
	<atom:link href="http://blog.justoneplanet.info/category/computer-language/php/database/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.justoneplanet.info</link>
	<description>JavaScript、PHP、MySQLを使ったり</description>
	<lastBuildDate>Sun, 25 Jul 2010 07:34:20 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>PHP MySQL Improved Extension（mysqli）</title>
		<link>http://blog.justoneplanet.info/2009/05/11/php-mysql-improved-extension%ef%bc%88mysqli%ef%bc%89/</link>
		<comments>http://blog.justoneplanet.info/2009/05/11/php-mysql-improved-extension%ef%bc%88mysqli%ef%bc%89/#comments</comments>
		<pubDate>Sun, 10 May 2009 23:00:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[データベース]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=1160</guid>
		<description><![CDATA[mysqli拡張サポートによって、MySQL4.1以降で使える機能を利用できる。但し、個人的には全くこの手の関数を使わない。何故ならばMySQLに特化した関数であり、仮に他のDBに移行する場合、保守のコストがとっても高く [...]]]></description>
			<content:encoded><![CDATA[<p>mysqli拡張サポートによって、MySQL4.1以降で使える機能を利用できる。但し、個人的には全くこの手の関数を使わない。何故ならばMySQLに特化した関数であり、仮に他のDBに移行する場合、保守のコストがとっても高くなってしまうと考えているからだ。それにラーニングコストもかかるし、PDOのメソッド名とmysqliの関数名がごっちゃになる。</p>
<h3>■mysqliを使ったDBへの接続</h3>
<pre class="brush: php;">
&lt;?php
$dbh = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if(mysqli_connect_errorno()){
    //code for error
}
mysqli-&gt;close();
?&gt;
</pre>
<p>mysqliは例外をthrowしない。</p>
<pre class="brush: php;">
&lt;?php
$dbh = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if(!$dbh){
    //code for error
}
mysqli_close($dbh);
?&gt;
</pre>
<h3>■mysqliを使ったDBへのクエリ発行</h3>
<pre class="brush: php;">
&lt;?php
$name = mysqli-&gt;real_escape_string($_POST['name']);
$sql = &quot;SELECT `id`, `name` FROM `person` WHERE `name` = '$name'&quot;;
if(!$dbh-&gt;real_query($sql)){
    //print($dbh-&gt;error);
}
if($result = mysql-&gt;store_result()){
    while($row = $result-&gt;fetch_assoc()){
        print($row['id'] . ': ' . $row['name']);
    }
    $result-&gt;close();
}
?&gt;
</pre>
<p>$resultもcloseしなきゃならんとは。。。めんどい。。。</p>
<pre class="brush: php;">
&lt;?php
$name = mysqli_real_escape_string($_POST['name']);
$sql = &quot;SELECT `id`, `name` FROM `person` WHERE `name` = '$name'&quot;;
if(mysqli_real_query($dbh, $sql)){
    //print(mysqli_error());
}
if($result = mysql_store_result($dbh)){
    while($row = $result_fetch_assoc($result)){
        print($row['id'] . ': ' . $row['name']);
    }
    mysqli_free_result($result);
}
?&gt;
</pre>
<p>うーむ。実に不愉快だ。やはりmysqliは性に合わん！</p>
<h3>■mysqliを使ったプリペアドステートメント</h3>
<pre class="brush: php;">
&lt;?php
$sql = &quot;INSERT INTO `person`(`id`, `name`, `country_id`) VALUES(?, ?, ?)&quot;;
if($stmt = $dbh-&gt;prepare($sql)){
    $stmt-&gt;bindParam('s', $id, $_POST['name'], $_POST['country_id']);
    $stmt-&gt;execute();
    $stmt-&gt;bind_result($result_id, $result_name);
    while($stmt-&gt;fetch()){
        print($result_id . ': ' . $result_name);
    }
    $stmt-&gt;close();
}
?&gt;
</pre>
<p>これじゃ、ソースを書きたくならないな。</p>
<pre class="brush: php;">
&lt;?php
$sql = &quot;INSERT INTO `person`(`id`, `name`, `country_id`) VALUES(?, ?, ?)&quot;;
if($stmt = mysqli_prepare($dbh, $sql)){
    mysqli_stmt_bind_param($stmt, 's', $id, $_POST['name'], $_POST['country_id']);
    mysqli_stmt_execute()$stmt;
    mysqli_stmt_bind_result($dbh, $result_id, $result_name);
    while(mysqli_stmt_fetch()){
        print($result_id . ': ' . $result_name);
    }
    mysqli_stmt_close($stmt);
}
?&gt;
</pre>
<h3>■mysqliを使ったトランザクション</h3>
<pre class="brush: php;">
&lt;?php
$dbh-&gt;autocommit(false);
$dbh-&gt;query(&quot;INSERT INTO `person`(`id`, `name`, `country_id`) VALUES('4', 'Jack', '2')&quot;);
$dbh-&gt;query(&quot;INSERT INTO `person`(`id`, `name`, `country_id`) VALUES('5', 'Emily', '1')&quot;);
if(!$dbh-&gt;commit()){
    $dbh-&gt;rollback();
}
?&gt;
</pre>
<pre class="brush: php;">
&lt;?php
mysqli_autocommiti($dbh, false);
mysqli_query($dbh, &quot;INSERT INTO `person`(`id`, `name`, `country_id`) VALUES('4', 'Jack', '2')&quot;);
mysqli_query($dbh, &quot;INSERT INTO `person`(`id`, `name`, `country_id`) VALUES('5', 'Emily', '1')&quot;);
if(!mysqli_commit($dbh)){
    mysqli_rollback($dbh);
}
?&gt;
</pre>
<div class="kakomi">
<h4>mysqliの特徴</h4>
<p>「手続き型」と「オブジェクト指向型」の記述が可能である。</p>
</div>
<p>サーバによってはインストールされていない事もしばしばあるようだ。ますます使わんぞ、コリャ=3・・・</p>
<h4>命名</h4>
<p>余計なお世話型関数。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2009/05/11/php-mysql-improved-extension%ef%bc%88mysqli%ef%bc%89/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Data Object（PDO）</title>
		<link>http://blog.justoneplanet.info/2009/05/10/php-data-object%ef%bc%88pdo%ef%bc%89/</link>
		<comments>http://blog.justoneplanet.info/2009/05/10/php-data-object%ef%bc%88pdo%ef%bc%89/#comments</comments>
		<pubDate>Sun, 10 May 2009 14:54:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[データベース]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=1153</guid>
		<description><![CDATA[PDOには様々なDBに対する各々のドライバがある。一旦、インストールすれば（PDOを使用してDBへ接続している場合、）コードを殆ど書き換えることなく、DBを変更することが可能になる。
■PDOを使ったデータベースへの接続 [...]]]></description>
			<content:encoded><![CDATA[<p>PDOには様々なDBに対する各々のドライバがある。一旦、インストールすれば（PDOを使用してDBへ接続している場合、）コードを殆ど書き換えることなく、DBを変更することが可能になる。</p>
<h3>■PDOを使ったデータベースへの接続</h3>
<pre class="brush: php;">
&lt;?php
$dsn = 'mysql:host=localhost;dbname=dbname';
$dbh = new PDO($dsn, DB_USER, DB_PASS);
?&gt;
</pre>
<p>通常、PDOはエラーが発生しても何も表示しない（PDO::ERRMODE_SILENT）。これはセキュリティ上安全ではあるが、一方でデバッグを非常に困難にする。従って、例外を発生させ（ファイルに書き込みさせ）るようにすることも可能である。</p>
<pre class="brush: php;">
&lt;?php
try {
    $dsn = 'mysql:host=localhost;dbname=dbname';
    $dbh = new PDO($dsn, DB_USER, DB_PASS);
    $dbh-&gt;setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
    $dbh-&gt;setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(Exception $e){
    //code
}
?&gt;
</pre>
<h3>■PDOを使ったデータベースへのクエリ発行</h3>
<h4>SELECT文</h4>
<p>SELECT文のような、結果セットを得ることを主目的としている場合は、以下のようにqueryメソッドを用いる。また、queryメソッドを用いた場合、戻り値はPDOStatementオブジェクトである。</p>
<pre class="brush: php;">
&lt;?php
$sql = &quot;SELECT * FROM `person` WHERE `name` = 'John'&quot;;
$result = $dbh-&gt;query($sql);
foreach($result as $row){
    print($row['name'] . ': ' . $row['country_id']);
}
?&gt;
</pre>
<p>但し、以下のように書いた場合、$rowには「数字キー」と「カラム名のキー」が両方含まれているので値が重複する。これはデフォルトのデータ取り出しモードがPDO::FETCH_BOTHであり、「数字キー」と「カラム名のキー」での配列になっているためである。</p>
<pre class="brush: php;">
&lt;?php
$sql = &quot;SELECT * FROM `person` WHERE `name` = 'John'&quot;;
$result = $dbh-&gt;query($sql);
foreach($result as $row){
    foreach($row as $value){
        print($value . PHP_EOL);
    }
}
/*
1
1
John
John
2
2
*/
?&gt;
</pre>
<div class="kakomi">
<h5>データ取り出しモードの変更</h5>
<p>データ取り出しモードを変更するには、以下のように結果セットが含まれるPDOStatementオブジェクト$resultに対して、setFetchModeメソッドを実行せねばならない。</p>
<pre class="brush: php;">
&lt;?php
$sql = &quot;SELECT * FROM `person` WHERE `name` = 'John'&quot;;
$result = $dbh-&gt;query($sql);
$result-&gt;setFetchMode(PDO::FETCH_OBJ);
foreach($result as $row){
    print($row-&gt;name . ': ' . $row-&gt;country_id);
}
?&gt;
</pre>
</div>
<div class="kakomi">
<h5>ユーザ入力の値をSQL文に組み込むためのメソッド</h5>
<p>通常、SQLインジェクションを回避するために、ユーザ入力の値をSQL文に含める際にはサニタイジングしなければならない。以下のように、quoteメソッドを用いることで可能である。</p>
<pre class="brush: php;">
&lt;?php
$name = $dbh-&gt;quote($_POST['name']);
$sql = &quot;SELECT * FROM `person` WHERE `name` = '$name'&quot;;
$result = $dbh-&gt;query($sql);
?&gt;
</pre>
<p>但し、いくつかのドライバはこのメソッドを実装していないので、後述のプリペアドステートメントを用いたほうが良い。</p>
</div>
<h4>INSERT文、UPDATE文、DELETE文</h4>
<p>INSERT文、UPDATE文、DELETE文には変更（処理）した行数を返すexecメソッドを用いる。</p>
<pre class="brush: php;">
&lt;?php
$sql = &quot;INSERT INTO `person`(`id`, `name`, `country_id`) VALUES('4', 'Jack', '2')&quot;;
$num = $dbh-&gt;exec($sql);
print($num);//1
?&gt;
</pre>
<h3>■プリペアドステートメント（Prepared Statement）を用いたクエリの発行</h3>
<h4>プリペアドステートメントとは</h4>
<ul>
<li>1回のリクエストに対する処理の中で、SQL文の再利用を可能にする</li>
<li>DBがプリペアドステートメントをサポートしてない場合、PDOが内部の関数で可能にする</li>
<li>DBがプリペアドステートメントをサポートしている場合、DBの機能を使ってアプリケーションの性能の向上を可能にする</li>
<li>（SQLインジェクションを誘発させる）クォート漏れに対するリスク回避を可能にする</li>
</ul>
<pre class="brush: php;">
&lt;?php
$sql = &quot;INSERT INTO `person`(`id`, `name`, `country_id`) VALUES(?, ?, ?)&quot;;
$stmt = $dbh-&gt;prepare($sql);
$stmt-&gt;execute(array(
    $id,
    $_POST['name'],
    $_POST['country_id']
));
?&gt;
</pre>
<p>INSERT文、UPDATE文、DELETE文には、ユーザ入力の値をSQL文に含めることが非常に多い。とはいえ、以下のようにSELECT文でも当然ながら、プリペアドステートメントを用いることはある。</p>
<pre class="brush: php;">
&lt;?php
$sql = &quot;SELECT * FROM `person` WHERE `name` = ?&quot;;
$stmt = $dbh-&gt;prepare($sql);
$stmt-&gt;execute(array('John'));
//$stmt-&gt;setFetchMode(PDO::FETCH_OBJ);
$result = $stmt-&gt;fetchAll();
var_dump($result);
/*
array(1) {
  [0]=&gt;
  array(6) {
    [&quot;id&quot;]=&gt;
    string(1) &quot;1&quot;
    [0]=&gt;
    string(1) &quot;1&quot;
    [&quot;name&quot;]=&gt;
    string(4) &quot;John&quot;
    [1]=&gt;
    string(4) &quot;John&quot;
    [&quot;country_id&quot;]=&gt;
    string(1) &quot;2&quot;
    [2]=&gt;
    string(1) &quot;2&quot;
  }
}
*/
?&gt;
</pre>
<p>但し、PHPのバージョンによって、（MySQL独自拡張の）LIMIT句に対するプリペアドステートメントにバグがあるため、それ（LIMIT句）以外での使用が望ましいと個人的には思う。また、LIMIT句は数値の値しか許容しないため、PHPで（型変換などを使って）サニタイジングすることは比較的に容易である。さらに、PDOStatementクラスに（結果を1行だけ返す）fetchメソッドが「あるバージョン」と「ないバージョン」があるため、このメソッドの使用はなるべく避けたほうが良い。</p>
<h3>■PDOを使ったトランザクションの実行</h3>
<p>以下のようにして、トランザクションを利用する。</p>
<pre class="brush: php;">
&lt;?php
try {
    $dsn = 'mysql:host=localhost;dbname=dbname';
    $dbh = new PDO($dsn, DB_USER, DB_PASS);
    $dbh-&gt;setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
    $dbh-&gt;setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $dbh-&gt;beginTransaction();
    $dbh-&gt;exec(&quot;INSERT INTO `person`(`id`, `name`, `country_id`) VALUES('4', 'Jack', '2')&quot;);
    $dbh-&gt;exec(&quot;INSERT INTO `person`(`id`, `name`, `country_id`) VALUES('5', 'Emily', '1')&quot;);
    $dbh-&gt;commit();
}
catch(Exception $e){
    $dbh-&gt;rollBack();
}
?&gt;
</pre>
<h4>各メソッドについて</h4>
<dl>
<dt>beginTransaction</dt>
<dd>トランザクションを開始する</dd>
<dt>commit</dt>
<dd>確定する</dd>
<dt>rollBack</dt>
<dd>破棄して最初の状態に戻す</dd>
</dl>
<div class="kakomi">
<h4>トランザクションとは</h4>
<p>「全て成功する」か「全て失敗する」かのどちらかしか存在しないことを保証する機能。この機能が必要な例として、たいていの参考書では「銀行の振込み」などが扱われる。</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2009/05/10/php-data-object%ef%bc%88pdo%ef%bc%89/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Joins（SQLにおけるテーブル結合）</title>
		<link>http://blog.justoneplanet.info/2009/05/10/sql-joins%ef%bc%88sql%e3%81%ab%e3%81%8a%e3%81%91%e3%82%8b%e3%83%86%e3%83%bc%e3%83%96%e3%83%ab%e7%b5%90%e5%90%88%ef%bc%89/</link>
		<comments>http://blog.justoneplanet.info/2009/05/10/sql-joins%ef%bc%88sql%e3%81%ab%e3%81%8a%e3%81%91%e3%82%8b%e3%83%86%e3%83%bc%e3%83%96%e3%83%ab%e7%b5%90%e5%90%88%ef%bc%89/#comments</comments>
		<pubDate>Sat, 09 May 2009 19:03:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[データベース]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=1142</guid>
		<description><![CDATA[テーブル結合とは、複数のテーブルから一つのレコードセットをつくり出す。多くのアプリケーションは非常に複雑なテーブル結合を使っている。

サンプルテーブル
personテーブル


id
name
country_id

 [...]]]></description>
			<content:encoded><![CDATA[<p>テーブル結合とは、複数のテーブルから一つのレコードセットをつくり出す。多くのアプリケーションは非常に複雑なテーブル結合を使っている。</p>
<div class="kakomi">
<h4>サンプルテーブル</h4>
<h5>personテーブル</h5>
<table>
<tr>
<th>id</th>
<th>name</th>
<th>country_id</th>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td>2</td>
</tr>
<tr>
<td>2</td>
<td>Mike</td>
<td>1</td>
</tr>
<tr>
<td>3</td>
<td>Nick</td>
<td>99</td>
</tr>
</table>
<h5>countryテーブル</h5>
<table>
<tr>
<th>id</th>
<th>name</th>
</tr>
<tr>
<td>1</td>
<td>USA</td>
</tr>
<tr>
<td>2</td>
<td>Japan</td>
</tr>
<tr>
<td>3</td>
<td>Canada</td>
</tr>
</table>
</div>
<h3>■内部結合（inner join）</h3>
<p>内部結合とは、一歩のテーブルに存在するcountry.idが、もう一方のテーブルに含まれていないとき、行の結合が失敗し結果セットから除外される結合である。</p>
<pre class="brush: sql;">
SELECT
    `person`.`id`,
    `person`.`name`,
    `country`.`name`
FROM
    `person`
INNER JOIN
    `country`
ON
    `person`.`country_id` = `country`.`id`;
</pre>
<p>ONキーワードで結合条件「`person`.`country_id` = `country`.`id`」と指定するとことができる。上述の場合、「INNER JOIN」でなく「JOIN」でも結果は等しいが、可読性の問題などが生じるため、結合の種類はSQL文に明記することをお勧めする。</p>
<div class="kakomi">
<h4>実行結果</h4>
<table>
<tr>
<th>id</th>
<th>name</th>
<th>name</th>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td>Japan</td>
</tr>
<tr>
<td>2</td>
<td>Mike</td>
<td>USA</td>
</tr>
</table>
</div>
<h3>■左外部結合（left outer join）</h3>
<p>外部結合とは、どちらか一方のテーブルに存在する行が、結果セットに含まれる結合である。「left outer join」はFROM節の左側のテーブル（person）に合わせて結合する。以下のようにすると左外部結合ができる。</p>
<pre class="brush: sql;">
SELECT
    `person`.`id`,
    `person`.`name`,
    `country`.`name`
FROM
    `person`
LEFT OUTER JOIN
    `country`
ON
    `person`.`country_id` = `country`.`id`;
</pre>
<div class="kakomi">
<h4>実行結果</h4>
<table>
<tr>
<th>id</th>
<th>name</th>
<th>name</th>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td>Japan</td>
</tr>
<tr>
<td>2</td>
<td>Mike</td>
<td>USA</td>
</tr>
<tr>
<td>3</td>
<td>Nick</td>
<td>NULL</td>
</tr>
</table>
</div>
<h3>■右外部結合（right outer join）</h3>
<p>「right outer join」はテーブル（country）に合わせて結合する。以下のようにすると右外部結合ができる。</p>
<pre class="brush: sql;">
SELECT
    `person`.`id`,
    `person`.`name`,
    `country`.`name`
FROM
    `person`
RIGHT OUTER JOIN
    `country`
ON
    `person`.`country_id` = `country`.`id`;
</pre>
<div class="kakomi">
<h4>実行結果</h4>
<table>
<tr>
<th>id</th>
<th>name</th>
<th>name</th>
</tr>
<tr>
<td>2</td>
<td>Mike</td>
<td>USA</td>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td>Japan</td>
</tr>
<tr>
<td>NULL</td>
<td>NULL</td>
<td>Canada</td>
</tr>
</table>
</div>
<p>LEFTキーワードとRIGHTキーワードはどちらのデータに空白部分が含まれていても良いかを決めるワードである。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2009/05/10/sql-joins%ef%bc%88sql%e3%81%ab%e3%81%8a%e3%81%91%e3%82%8b%e3%83%86%e3%83%bc%e3%83%96%e3%83%ab%e7%b5%90%e5%90%88%ef%bc%89/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Relational Database and SQL（RDBとSQL）</title>
		<link>http://blog.justoneplanet.info/2009/05/10/relational-database-and-sql%ef%bc%88rdb%e3%81%a8sql%ef%bc%89/</link>
		<comments>http://blog.justoneplanet.info/2009/05/10/relational-database-and-sql%ef%bc%88rdb%e3%81%a8sql%ef%bc%89/#comments</comments>
		<pubDate>Sat, 09 May 2009 15:30:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[データベース]]></category>

		<guid isPermaLink="false">http://blog.justoneplanet.info/?p=1130</guid>
		<description><![CDATA[■データベースの作成
以下のように、「CREATE DATABASE」文や「CREATE SCHEMA」文を使用する。

CREATE DATABASE &#60;dbname&#62;;


CREATE SCHEMA &#038; [...]]]></description>
			<content:encoded><![CDATA[<h3>■データベースの作成</h3>
<p>以下のように、「CREATE DATABASE」文や「CREATE SCHEMA」文を使用する。</p>
<pre class="brush: sql;">
CREATE DATABASE &lt;dbname&gt;;
</pre>
<pre class="brush: sql;">
CREATE SCHEMA &lt;dbname&gt;;
</pre>
<h3>■テーブルの作成</h3>
<p>以下のように、「CREATE TABLE」文を使ってテーブルを作成する。</p>
<pre class="brush: sql;">
CREATE TABLE &lt;tablename&gt; (
    &lt;colname&gt; &lt;coltype&gt; [&lt;colattributes&gt;],
    [...
    &lt;colname&gt; &lt;coltype&gt; [&lt;colattributes&gt;]]
);
</pre>
<p>例えば以下のようになる。</p>
<pre class="brush: sql;">
CREATE TABLE book (
    id INT NOT NULL PRIMARY KEY,
    isbn VARCHAR(13),
    title VARCHAR(255),
    author VARCHAR(255),
    publisher VARCHAR(255)
)
</pre>
<h3>■インデックスの作成</h3>
<pre class="brush: sql;">
CREATE INDEX &lt;indexname&gt; ON &lt;tablename&gt; (&lt;column&gt;[, ... &lt;column&gt;]);
</pre>
<p>例えば以下のようになる。</p>
<pre class="brush: sql;">
CREATE INDEX book_isbn ON book (isbn);
</pre>
<p>但し、一般的には以下のようにテーブルの作成と同時に行うことが多い。</p>
<pre class="brush: sql;">
CREATE TABLE `book` (
    `id` int(11) NOT NULL auto_increment,
    `isbn` varchar(13) default NULL,
    `title` varchar(255) default NULL,
    `author` varchar(255) default NULL,
    `publisher` varchar(255) default NULL,
    PRIMARY KEY  (`id`),
    KEY `book_isbn` (`isbn`)
);
</pre>
<h3>■データベースの削除</h3>
<pre class="brush: sql;">
DROP SCHEMA &lt;dbname&gt;;
</pre>
<h3>■テーブルの削除</h3>
<pre class="brush: sql;">
DROP TABLE &lt;tablename&gt;;
</pre>
<hr />
<h3>■データの操作</h3>
<h4>追加</h4>
<p>データを追加するには、以下のようにINSERT（ INTO）文を使用する。テーブルのカラム名は運用上のメリットが非常に大きいため、記述することを強くお勧めする（カラムの追加に対するSQL文の耐性）。</p>
<pre class="brush: sql;">
INSERT INTO &lt;tablename&gt;(&lt;colname&gt; [, ... , &lt;colname&gt;]) VALUES(&lt;value&gt; [, ... , &lt;value&gt;]);
</pre>
<h4>更新</h4>
<p>データを更新するためには、以下のようにUPDATE（~SET~）文を使用する。但し、以下のコードは全レコードが特定の値に上書きされてしまう。</p>
<pre class="brush: sql;">
UPDATE &lt;tablename&gt; SET &lt;colname&gt; = &lt;value&gt; [, ... , &lt;colname&gt; = &lt;value&gt;];
</pre>
<p>通常は、以下のようにWHERE節などと組み合わせて使用し、特定のレコードのみを更新する。</p>
<pre class="brush: sql;">
UPDATE `address_book` SET `name` = 'Mike' WHERE `id` = '1';
</pre>
<h4>削除</h4>
<p>データを削除するには、以下のようにDELETE文を使う。但し、以下のコードは全レコードが削除される。</p>
<pre class="brush: sql;">
DELETE  FROM &lt;tablename&gt;;
</pre>
<p>通常は以下のようにWHERE節などと組み合わせて使用する。</p>
<pre class="brush: sql;">
DELETE  FROM `address_book` WHERE `name` = 'John';
</pre>
<hr />
<h3>■データの表示</h3>
<p>データを表示するには、以下のようにSELECT文を使用する。</p>
<pre class="brush: sql;">
SELECT * FROM `address_book`;
</pre>
<p>通常、アプリケーションで全件のデータが必要なときというのは稀である。そして全件をSQLから抽出すると、サーバのメモリを圧迫することになる。従って、以下のようにWHERE節などと組み合わせて使うことが多い。</p>
<pre class="brush: sql;">
SELECT `tel` FROM `address_book` WHERE `name` = 'John';
</pre>
<h4>WHERE節について</h4>
<p>WHERE節では、条件をANDやORで複数指定できる。また、LIKE演算子を使用し大文字/小文字を区別しないようにしたり、「%（任意の複数文字）」や「_（任意の一文字）」の記号を使用して検索できる。</p>
<pre class="brush: sql;">
SELECT `tel` FROM `address_book` WHERE (`name` = 'John') OR (`name` LIKE '%Joh%' AND `age` = '27')';
</pre>
<p>正規表現と記法が異なるのが、個人的にはシックリこない。</p>
<div class="kakomi">
<h4>インデックス</h4>
<p>日本語に直訳すると「索引」。リソース内の特定の項目を検索するためのメカニズム。一般的にはアプリケーションがWHERE節などで検索に使用するカラムに対して指定される。</p>
<ul>
<li>「インデックス」はデータベースサーバがテーブルの行を特定するために使われる</li>
<li>「インデックス」は特殊なテーブルである</li>
<li>「インデックス」は行を特定するために使用される列と、行が物理的に配置されている場所を示す情報のみを含んでいる</li>
</ul>
<h4>主キー（primary key）</h4>
<p>一組のデータレコードを一意に識別するための特殊なインデックス</p>
<h4>テーブルの関係性</h4>
<p>テーブルの関係性として「1:1」と「1:複数」の場合は簡単に処理できるが、「複数:複数」の場合はintermediate tableなどを使用しなくてはならない。</p>
<dl>
<dt>1:1</dt>
<dd>子テーブルの1レコードが、親テーブルの1レコードと関連する</dd>
<dt>1:複数</dt>
<dd>子テーブルの複数レコードが、親テーブルの1レコードと関連する</dd>
<dt>複数:複数</dt>
<dd>子テーブルの複数レコードが、親テーブルの複数レコードと関連する</dd>
</dl>
<h4>関係性を意識したテーブルの作成</h4>
<h5>1:1</h5>
<p>以下のように、primary keyを共通にしてみると良い。</p>
<pre class="brush: sql;">
CREATE TABLE `book` (
    `id` int(11) NOT NULL,
    `isbn` varchar(13) default NULL,
    `title` varchar(255) default NULL,
    `author` varchar(255) default NULL,
    `publisher` varchar(255) default NULL,
    PRIMARY KEY  (`id`),
    KEY `book_isbn` (`isbn`)
);
CREATE TABLE `book_author` (
    `id` int(11) NOT NULL PRIMARY KEY,
    `author_id` int(11) NOT NULL
);
</pre>
<h5>1:多</h5>
<p>以下のように、REFERENCESを使用してbookテーブルを参照するようにする。</p>
<pre class="brush: sql;">
CREATE TABLE `book` (
    `id` int(11) NOT NULL auto_increment,
    `isbn` varchar(13) default NULL,
    `title` varchar(255) default NULL,
    `author` varchar(255) default NULL,
    `publisher` varchar(255) default NULL,
    PRIMARY KEY  (`id`),
    KEY `book_isbn` (`isbn`)
);
CREATE TABLE `book_chapter` (
    `id` int(11) NOT NULL PRIMARY KEY auto_increment,
    `isbn` varchar(13) REFERENCES `book`(`isbn`),
    `chapter_number` INT NOT NULL,
    `chapter_title` varchar(255)
);
</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.justoneplanet.info/2009/05/10/relational-database-and-sql%ef%bc%88rdb%e3%81%a8sql%ef%bc%89/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
