114

オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

Embed Size (px)

Citation preview

Page 1: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)
Page 2: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

オープンソースデータベース標準教科書― PostgreSQL ―(Ver1.0.0)

2011-10-04 版 LPI-Japan 発行

Page 3: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

まえがき

このたび、特定非営利活動法人エルピーアイジャパンは、オープンソースデータベース技術者教育

に利用していただくことを目的とした教材、「オープンソースデータベース標準教科書」を開発し、

インターネット上にて公開し、提供することとなりました。

この「オープンソースデータベース標準教科書」は、データベース技術習得のニーズの高まりに応

えるべく、まったく初めてデータベースについて学習する人のために開発されました。既にリリー

スされ好評を得ている「Linux標準教科書」「Linuxサーバ構築標準教科書」の姉妹版となります。

本教科書は、「OSS-DB技術者認定試験 Silver」の学習教材としても利用可能です。

公開にあたっては、「オープンソースデータベース標準教科書」に添付されたライセンス(クリエ

イティブ・コモンズ・ライセンス)の下に公開されています。

本教科書は、最新の技術動向に対応するため、随時アップデートを行っていきます。また、テキ

スト作成やアップデートについては、意見交換のメーリングリストで、誰でもオープンに参加でき

ます。

•「オープンソースデータベース標準教科書」PDF 版、EPUB 版のダウンロード

http://www.oss-db.jp/ossdbtext/text.shtml

• メーリングリスト http://list.ospn.jp/mailman/listinfo/linux-text

• 意見交換用Wikiサイト http://oss-db.jp/oss-db-wiki/

執筆者・制作担当者紹介

松田神一(企画・進行担当/ LPI-Japan)

オープンソースソフトウェアの進歩・普及と PCの低価格化・高性能化により、誰でも簡単にWeb

アプリケーションを構築できるようになりました。ほとんどのWeb アプリケーションでは、その

バックエンドにデータベースを利用しており、データベースの利用・運用管理技術は IT 技術者に

とって必須のものとなっています。しかし、データベースの利用に使われる SQL 言語は、他のプ

ログラム言語とは特性が大きく異なるため、習得が簡単ではありません。データベースの初心者が、

SQL言語とデータベース運用管理技術の基礎を学ぶことのできる、教科書のようなものが必要と考

えて、本教科書を企画しました。

宮原徹(企画・執筆担当/株式会社びぎねっと)

本教科書は、データベースを初めて触る方でも迷わないためのガイドとなるよう、できるだけ簡潔

に分かりやすく、実際に動かしてみて理解できることを目標に執筆しました。一方で、データベー

スは OSと同じく奥が深いソフトウェアのため、本教科書で解説できたのはほんのさわりに過ぎま

LPI-Japan i www.oss-db.jp

Page 4: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

せん。特に運用管理やパフォーマンス、データベース設計については、より詳細な解説書にあたっ

てみてください。この教科書を手に取った方のデータベーススキル修得の一助になれば幸いです。

高橋征義(PDF版・EPUB版制作担当/株式会社達人出版会)

本教科書の PDF・EPUB作成のお手伝いをいたしました。技術の習得において、紙の書籍で学ぶ

ことの優位性はまだまだ大きいものがありますが、特に進化の激しい業界においては、素早い制作

と頻繁な改訂を得意とする電子書籍のメリットも小さくありません。さらに、今回採用した EPUB

は、PC・タブレットからスマートフォンまで、一つのファイルで対応できるのが特徴です。このよ

うな便利なテキストを提供することで、エンジニアの方々の技術力向上に貢献できれば幸いです。

木村真之介(意見交換用Wikiサイト作成)

皆様の意見交換用のWikiサイト(http://oss-db.jp/oss-db-wiki/)を開設しました。本教科書に

関するご意見・ご質問・誤植等の報告はぜひWikiサイト(http://oss-db.jp/oss-db-wiki/)にお寄

せください。本教科書が皆様の学習のお役に立てれば幸いです。

教科書開発に協力いただいた皆さん

本教科書は、オープンソースソフトウェア開発の手法を取り入れ、何回かのフェーストゥフェー

スのミーティングと、メーリングリストを使ったコミュニケーションで構成の企画および原稿のレ

ビューなどを行いました。

• 案浦 浩二• 石井 達夫(SRA OSS, Inc.日本支社)

• 伊津野 匡• 上田 和章(ネットプラン松山)• 岡田 賢治(株式会社ネットマイスター)• 加藤 剛(株式会社アークシステム)• 綱川 貴之(富士通株式会社)• 遠山 洋平(株式会社びぎねっと)• 永安 悟史(アップタイム・テクノロジーズ合同会社)• 濱田 大助(日本文理大学)• 早坂 一王(株式会社クレスコ)• 古橋 勇作(日本 HP)

• 本間 裕一(株式会社エヌサイト)• 三谷 篤(SRA西日本)

• 吉田 貴紀(SRA OSS, Inc.日本支社)

• 吉田 敏和(NTTコムウェア株式会社)

LPI-Japan ii www.oss-db.jp

Page 5: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

著作権

本教科書の著作権は特定非営利活動法人エルピーアイジャパンに帰属します。

All Rights Reserved. Copyright(C) The Linux Professional Institute Japan.

使用に関する権利

●表示本教科書は、特定非営利活動法人エルピーアイジャパンに著作権が帰属するものであること

を表示してください。

●改変禁止本教科書は、改変せず使用してください。本教科書に対する改変は、特定非営利活動法

人エルピーアイジャパンまたは特定非営利活動法人エルピーアイジャパンが認める団体により行わ

れています。フィードバックは誰でも参加できるメーリングリストで行われていますので、積極的

にご参加ください。http://list.ospn.jp/mailman/listinfo/linux-text

●非営利本教科書は、営利目的(※)以外で教材として自由に利用することができます。教材とし

て営利目的での利用は、特定非営利活動法人エルピーアイジャパンによる許諾が必要です。本教科

書を利用した教育において、本教科書自体の対価を請求しない場合は、営利目的の教育であっても

基本的に使用できます。その場合も含め、LPI-Japan事務局までお気軽にお問い合わせください。

(※)営利目的の利用とは以下のとおり規定しております。

• 営利企業において、当教材の複製を用いた研修や講義を行うこと、または非営利団体において有料セミナー等に利用すること

本教科書の使用に関するお問合せ先

特定非営利活動法人エルピーアイジャパン(LPI-Japan)事務局

〒102-0082 東京都千代田区一番町 15 一番町コート 6F

TEL:03-3261-3660

FAX:03-3261-3661

E-Mail:[email protected]

この教科書の目的

本教科書の目的は、データベースの経験の無い技術者を対象に、基本的なデータベースの操作

方法について実習を通して学習することにあります。SQL文を使ってデータベースを操作したり、

データベースの作成や管理についての基礎を学習します。OSS-DBエンジニアのスキルを認定する

OSS-DB技術者認定試験のための教育および学習にも役立てていただけます。

LPI-Japan iii www.oss-db.jp

Page 6: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

想定している実習環境

本教科書での実習環境として、以下の環境を構築しています。

●データベース

本教科書では、PostgreSQL バージョン 9.0 を利用します。バージョンに依存する内容はほとん

ど無いため、その他のバージョンでも学習は可能ですが、表示など一部異なる場合があります。イ

ンストールは RPMパッケージから行っていますが、独自にソースコードからインストールしても

かまいません。

● OS

本教科書では、32 ビット版の CentOS バージョン 5.7 を利用します。上記 PostgreSQL のバー

ジョンが動作すれば、その他のディストリビューションでもかまいません。

●マシンの構成と HDD

マシンの構成は、市販されている一般的な構成の PC を想定しています。その PC に Linux と

PostgreSQL をインストールします。よって、HDD の内容は完全にクリアされます。そのため

HDDの中を消してよい PCを用意するか、HDDの中身をあらかじめバックアップしておく必要が

あります。

●ネットワーク

利用する PCは、ネットワークで接続されており、インターネットにも接続できることを前提と

しています。接続されていない場合には、別の方法で PostgreSQLのパッケージをダウンロードお

よびコピーしてインストールを行ってください。

●仮想環境

専用の PC 環境が用意できない場合は仮想環境を使う方法もあります。仮想環境とはWindows

や Mac OS X 上で PC をソフトウェアで実現し、稼働している OS 上にあたかも別のマシンが

動作しているかの様に振る舞うもので、たとえば VMware社の VMware Workstation(Windows)

や VMware Fusion(Mac OS X)、Parallels 社の Parallels Desktop(Mac OS X) や VirtualBox、

QEMU等があげられます。

●クラウド環境

クラウド上に用意した環境を使う方法もあります。CentOS、またはその他の Linux が動作する

環境に PostgreSQLがインストールしてあれば、本教科書の内容を学習できます。

LPI-Japan iv www.oss-db.jp

Page 7: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

その他の情報源

OSS-DB技術者認定試験

http://www.oss-db.jp/

日本 PostgreSQLユーザ会(JPUG)

http://www.postgresql.jp/

PostgreSQLのマニュアル

JPUGのサイトから「日本語ドキュメント」http://www.postgresql.jp/document/

メーリングリスト(pgsql-jp)

http://ml.postgresql.jp/mailman/listinfo/pgsql-jp

Let’s PostgreSQL

http://lets.postgresql.jp/

LPI-Japan v www.oss-db.jp

Page 8: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

目次

まえがき i

第 1章 SQLによるデータベースの操作 基礎編 1

1.1 データベース利用の基本パターン . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.2 psqlツールの利用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.3 SQLの実行方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

1.4 データの検索(SELECT) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

1.5 WHERE句による絞り込み検索 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

1.6 ORDER BY句による並び替え . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

1.7 表の結合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

1.8 行データの入力(INSERT) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

1.9 データの更新(UPDATE) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

1.10 行データの削除(DELETE) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

第 2章 データ型 18

2.1 数値データ型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2.2 文字列データ型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.3 日付・時刻データ型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

第 3章 データベース定義基礎編 23

3.1 表の作成(CREATE TABLE) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3.2 表定義の修正(ALTER TABLE) . . . . . . . . . . . . . . . . . . . . . . . . . . 24

3.3 表の削除(DROP TABLE) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

3.4 行データのセーブ・ロード . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

第 4章 基礎編演習 29

4.1 演習 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

4.2 演習 2:郵便番号データベース . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

4.3 練習の解答 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

第 5章 SQLによるデータベースの操作 応用編 35

5.1 AND/OR演算子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

5.2 LIKE演算子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

LPI-Japan vi www.oss-db.jp

Page 9: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

目次

5.3 BETWEEN演算子 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

5.4 集約関数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

5.5 副問い合わせ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

5.6 日付・時刻型データの取り扱い . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

5.7 複雑な結合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

5.8 LIMIT句による検索行数制限 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

第 6章 データベース定義の応用 46

6.1 主キー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

6.2 外部キー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

6.3 NULLについて . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

6.4 シーケンス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

第 7章 マルチユーザでの利用 58

7.1 ユーザの作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

7.2 接続と認証 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

7.3 ネットワーク経由接続 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

7.4 アクセス権限 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

7.5 トランザクション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68

第 8章 パフォーマンスチューニング 74

8.1 インデックス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

8.2 SQL実行プランの分析 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

8.3 バキューム処理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

8.4 クラスタ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79

第 9章 バックアップとリストア 81

9.1 ファイルのコピー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

9.2 pg_dumpコマンドによるバックアップ . . . . . . . . . . . . . . . . . . . . . . . . 81

9.3 psqlによるリストア . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82

第 10章 Webアプリケーションとの連携 84

10.1 PHPとは? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

10.2 Apacheと PHP環境の設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

10.3 PHPと PostgreSQLの連携 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87

第 11章 実習環境の構築方法 96

11.1 OSのインストール . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

11.2 RPMパッケージのダウンロードとインストール . . . . . . . . . . . . . . . . . . . 96

11.3 データベースの初期化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

11.4 データベースを起動 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

11.5 動作の確認 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

LPI-Japan vii www.oss-db.jp

Page 10: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

目次

11.6 RPMからインストールした場合の各種ディレクトリ . . . . . . . . . . . . . . . . . 100

11.7 データベースの作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

11.8 表の作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

11.9 データの入力 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

LPI-Japan viii www.oss-db.jp

Page 11: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第1章

SQLによるデータベースの操作基礎編

データベースの操作には SQLを使用します。この章では、SQLを利用したデータベースの

操作の基礎を学びます。すでに作成されているデータベースに対して、SQLを使ってデータ

の検索や更新などを行ってみましょう。

1.1 データベース利用の基本パターン

データベースの役目は、利用者からの要求に応じて様々なデータを管理することです。それらを

分類すると、以下のようなパターンに分けることができます。

• 表を作成する(CREATE TABLE)

データベースにデータを保管するには、「表(TABLE)」を作成する必要があります。表の項目名

や、データの種類(文字や数値など)を指定する必要があります。

• データを挿入する (INSERT)

データベースにデータを保管することを「挿入 (INSERT)」と呼びます。データの種類に合わせ

たデータを挿入する必要があります。

• データを検索する (SELECT)

データベースからデータを取り出すことを「検索 (SELECT)」と呼びます。条件を指定して一部

を取り出したり、複数の表から組み合わせでデータを取り出すなど、様々な検索が行えるのがデー

タベースのメリットです。

• データを更新する (UPDATE)

データベースのデータに修正を加えることを「更新 (UPDATE)」と呼びます。すべてのデータを

一括で修正したり、条件を指定して一部のデータだけを修正したりできます。

• データを削除する (DELETE)

データベースからデータを取り除くことを「削除 (DELETE)」と呼びます。条件を指定して、取

り除きたいデータを絞り込みます。

LPI-Japan 1 www.oss-db.jp

Page 12: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.2 psqlツールの利用

1.2 psqlツールの利用

PostgreSQLに対して SQLを実行してデータベースを操作するには、psqlツール(以下 psql)を

利用します。

注意:ここからの作業は付録 Aで説明しているセットアップが行われていることを前提としてい

ます。うまく作業が行えない場合には、付録 Aのセットアップが正しく行われていることを確認し

てください。

1.2.1 psqlでデータベースに接続する

psqlは Linux上で実行できるコマンドとして提供されているので、利用するには Linuxにログイ

ンする必要があります。

1. ユーザ postgresで作業可能にする

psql を実行するには、シェルで作業しているユーザをユーザ postgres に切り替えます。ユーザ

postgresは、Linuxに PostgreSQLをパッケージでインストールした時に自動的に作成されている

ユーザです。管理者ユーザ rootでログインした後、suコマンドでユーザ postgresに切り替えます。

suコマンドでユーザを切り替えるには、以下のように suコマンドに-(ハイフン)をつけて実行

するようにしてください。

[root@localhost ~]# su - postgres-bash-3.2$

2. データベース一覧を表示する

psql に-l オプションをつけて実行します。psql は PostgreSQL に接続し、現在作成されている

データベースの一覧を表示します。

-bash-3.2$ psql -lデータベース一覧

名前 | 所有者 | エンコーディング | 照合順序 | Ctype(変換演算子) | アクセス権-----------+----------+------------------+-------------+-------------------+-----------------------

ossdb | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 |

postgres | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 |

template0 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres +

| | | | | postgres=CTc/postgres

template1 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres +

| | | | | postgres=CTc/postgres

(4 行)

LPI-Japan 2 www.oss-db.jp

Page 13: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.2 psqlツールの利用

3. データベースに接続する

psqlを利用してデータベースに接続します。PostgreSQLは同時に複数のデータベースを管理で

きますが、psqlではそのうちの 1つを選んで接続して操作します。

以下のように、psqlの引数として接続したいデータベースの名前を指定して実行します。

-bash-3.2$ psql ossdbpsql (9.0.5)

"help" でヘルプを表示します.

ossdb=#

接続に成功すると、プロンプトが表示されて SQLコマンドなどの実行命令を受け付ける状態にな

ります。接続できない場合には、PostgreSQLが正しく実行されているか、ユーザ postgresで psql

を実行しているかを確認してください。

1.2.2 psqlのヘルプを表示する

psqlのヘルプを表示します。helpと入力します。

ossdb=# helpPostgreSQL へのコマンドライン・インターフェース、 psql へようこそ。

Ycopyright とタイプすると、配布条件を表示します。Yh とタイプすると、 SQL コマンドのヘルプを表示します。Y? とタイプすると、 psql コマンドのヘルプを表示します。Yg と打つかセミコロンで閉じると、クエリーを実行します。Yq で終了します。

1.2.3 メタコマンド

psql は SQL コマンドを受け付けて、PostgreSQL に対して検索などの処理を実行する他に、Y

(またはバックスラッシュ)で始まるメタコマンドを受け付けます。メタコマンドは、ヘルプを表示

したり、データベースに対する操作を行ったり、様々な種類のコマンドが用意されています。

• psqlメタコマンド Yh

利用できる SQLコマンドのヘルプが確認できます。

ossdb=# Yh利用可能なヘルプ:

ABORT DELETE

LPI-Japan 3 www.oss-db.jp

Page 14: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.2 psqlツールの利用

ALTER AGGREGATE DISCARD

ALTER CONVERSION DO

ALTER DATABASE DROP AGGREGATE

(以下略)

• psqlメタコマンド Yh SQLコマンド

psqlメタコマンド Yhの引数に SQLコマンドを指定すると、その SQLコマンドのヘルプが確認

できます。SQLコマンドの指定は大文字でも小文字でも構いません。

ossdb=# Yh DELETEコマンド: DELETE

説明: テーブルの行を削除する書式:

DELETE FROM [ ONLY ] テーブル [ [ AS ] 別名 ]

[ USING USING リスト ]

[ WHERE 条件 | WHERE CURRENT OF カーソル名 ]

[ RETURNING * | 出力表現 [ [ AS ] 出力名 ] [, ...] ]

• psqlメタコマンド Y?

psqlメタコマンド Y?で、利用できる psqlメタコマンドのヘルプが確認できます。

ossdb=# Y?一般

Ycopyright PostgreSQL の使い方と配布条件を表示Yg [ファイル] または ’;’ クエリー実行(し、結果をファイルまたは |パイプ へ書

出す)

Yh [名前] SQL コマンドの文法ヘルプ、* で全コマンドYq psql を終了する

(以下略)

1.2.4 psqlを終了する

psqlを終了するには、psqlメタコマンドの Yqを入力します。

ossdb=# Yq-bash-3.2$

LPI-Japan 4 www.oss-db.jp

Page 15: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.2 psqlツールの利用

1.2.5 表の確認

作成されている表を確認するには psqlメタコマンド Ydを利用します。

ossdb=# Ydリレーションの一覧

スキーマ | 名前 | 型 | 所有者----------+----------+----------+----------

public | customer | テーブル | postgres

public | orders | テーブル | postgres

public | prod | テーブル | postgres

(3 行)

1.2.6 表定義の確認

表がどのような項目を持っているのかを確認するには psqlメタコマンド Ydに確認したい表名を

付けて実行します。

ossdb=# Yd customerテーブル "public.customer"

カラム | 型 | 修飾語---------------+---------+--------

customer_id | integer |

customer_name | text |

ossdb=# Yd ordersテーブル "public.orders"

カラム | 型 | 修飾語-------------+-----------------------------+--------

order_id | integer |

order_date | timestamp without time zone |

customer_id | integer |

prod_id | integer |

qty | integer |

ossdb=# Yd prodテーブル "public.prod"

カラム | 型 | 修飾語-----------+---------+--------

prod_id | integer |

prod_name | text |

price | integer |

LPI-Japan 5 www.oss-db.jp

Page 16: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.3 SQLの実行方法

1.2.7 表とテーブル、リレーション

本教科書ではデータの格納先を「表」と記述していますが、psqlの実行結果には「リレーション」

や「テーブル」と表記されています。基本的に表とテーブルは同じものと考えて構いません。リレー

ションは、本来的な意味ではデータの集合を指していますが、リレーショナルデータベースではリ

レーションは表形式で表されますので、リレーションと表もほぼ同義と考えて良いでしょう。同様

に、「行」と「レコード」や「タプル」、「列」と「カラム」も同義語になります。

1.3 SQLの実行方法

psqlは、psqlメタコマンドと SQLコマンドの 2つを受け付けて実行します。psqlメタコマンド

は必ず Yから始まるので区別されます。psqlメタコマンド以外は、PostgreSQLデータベースに対

する SQL コマンドとして実行されます。psql は、SQL コマンドの実行を命令されるまで SQL コ

マンドの入力を受け付け続けます。SQLコマンドの実行は、行末に;(セミコロン)をつけて入力を

行うか、psql メタコマンド Yg を実行します。改行すれば複数行に渡って入力を受け付けるので、

SQLコマンドの入力が終わったら忘れずに実行してください。

1.3.1 複数行入力のプロンプト表示

psqlで複数行入力をした時に表示されるプロンプトは、通常のプロンプトと、複数行入力中のプ

ロンプトで異なります。

表 1.1 psqlのプロンプト

データベース名=# 通常のプロンプト

データベース名-# 2行目以降のプロンプト

プロンプトに何を表示するかは、psql の内部変数 PROMPT1、PROMPT2 で定義されていま

す。たとえば 2行目以降のプロンプトに何も表示したくない場合、psqlメタコマンドの Yunsetで

PROMPT2の変数値を解除します。

ossdb=# 1st line ← 1行目ossdb-# 2nd line ← 2行目ossdb-# 3rd line; ← 3行目ERROR: "1"またはその近辺で構文エラー行 1: 1st line

^

ossdb=# Yunset PROMPT2ossdb=# 1st line ← 1行目2nd line ← 2行目3rd line; ← 3行目ERROR: "1"またはその近辺で構文エラー行 1: 1st line

^

LPI-Japan 6 www.oss-db.jp

Page 17: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.4 データの検索(SELECT)

本教科書では、複数行に渡る SQLコマンドを電子版からのコピー&ペーストで簡単に実行できる

よう、2行目以降のプロンプトを説明した方法で表示しないようにして実行例を掲載しています。実

習時には 2行目以降のプロンプトが出ているのが正しい表示です。

1.3.2 テキストファイルからの読み込み実行

psqlはテキストファイルから読み込んだ内容を実行する機能があります。同じ処理を何度も繰り

返し実行したい場合には、あらかじめメタコマンドや SQLコマンドをファイルに記述して、psqlに

読み込ませて実行できます。

ファイルを読み込ませる場合の psqlの構文

$ psql -f ファイル名 [データベース名] [ユーザ名]

以下の例では、メタコマンド Ydを記述したファイル test.sqlを psqlに読み込ませて実行してい

ます。

-bash-3.2$ cat test.sqlYd

-bash-3.2$ psql -f test.sql ossdbリレーションの一覧

スキーマ | 名前 | 型 | 所有者----------+----------+----------+----------

public | customer | テーブル | postgres

public | orders | テーブル | postgres

public | prod | テーブル | postgres

(3 行)

1.4 データの検索(SELECT)

データの検索はデータベース利用の一番の基本です。データベースは様々な種類のデータを表形

式で保管しているので、そのデータを必要な形で取り出すのがデータの検索です。データの検索に

は SQLの SELECT文を使用します。

SELECT文の基本構文

SELECT [DISTINCT] * | SELECT項目リストFROM 表名 [,…]

[WHERE 検索条件式]

[GROUP BY グループ化式]

LPI-Japan 7 www.oss-db.jp

Page 18: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.4 データの検索(SELECT)

[HAVING 検索条件式]

[ORDER BY 並べ替え式]

1.4.1 全件全項目検索

データベースの表データを全件、全項目で取り出すのが全件全項目検索です。*(アスタリスク)

を指定することで、対象となる検索表の全項目を検索します。

全件全項目検索の SELECT文

SELECT * FROM 表

以下の例では、customer表、prod表、orders表の全件全項目検索を行っています。

ossdb=# SELECT * FROM customer;customer_id | customer_name

-------------+---------------

1 | 佐藤商事2 | 鈴木物産3 | 高橋商店

(3 行)

ossdb=# SELECT * FROM prod;prod_id | prod_name | price

---------+-----------+-------

1 | みかん | 50

2 | りんご | 70

3 | メロン | 100

(3 行)

ossdb=# SELECT * FROM orders;order_id | order_date | customer_id | prod_id | qty

----------+----------------------------+-------------+---------+-----

1 | 2011-09-18 12:21:27.791733 | 1 | 1 | 10

2 | 2011-09-18 12:21:27.807685 | 2 | 2 | 5

3 | 2011-09-18 12:21:27.81101 | 3 | 3 | 8

4 | 2011-09-18 12:21:27.813885 | 2 | 1 | 3

5 | 2011-09-18 12:21:27.816095 | 3 | 2 | 4

(5 行)

1.4.2 SELECT項目リスト

SELECT文で検索したい列名をカンマ区切りで並べて指定します。

SELECT項目リストを使った SELECT文

LPI-Japan 8 www.oss-db.jp

Page 19: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.5 WHERE句による絞り込み検索

SELECT 列名 [,列名...] FROM 表

以下の例では、prod表から prod_name列、price列のみ検索しています。

ossdb=# SELECT prod_name,price FROM prod;prod_name | price

-----------+-------

みかん | 50

りんご | 70

メロン | 100

(3 行)

1.5 WHERE句による絞り込み検索

検索で取り出すデータ行を条件で絞り込むには、WHERE句を使用します。

WHERE句の構文

WHERE 列名 条件式 条件値

表 1.2 主な条件式

条件式 意味

= 等しい

<> 等しくない

> よりも大きい

< よりも小さい(未満)

>= 以上

<= 以下

BETWEEN 範囲指定

LIKE 部分一致

1.5.1 等しい (=)、等しくない (<>)

ある列の値が指定した条件値と等しい、あるいは等しくないデータを取り出します。条件値を文

字列として指定する場合には’(シングルクォート)で括ります。

以下の例では、customer表から customer_id列の値が 2の行データを検索します。

LPI-Japan 9 www.oss-db.jp

Page 20: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.5 WHERE句による絞り込み検索

ossdb=# SELECT * FROM customer WHERE customer_id = 2;customer_id | customer_name

-------------+---------------

2 | 鈴木物産(1 行)

以下の例では、customer表から customer_id列の値が 2以外の行データを検索します。

ossdb=# SELECT * FROM customer WHERE customer_id <> 2;customer_id | customer_name

-------------+---------------

1 | 佐藤商事3 | 高橋商店

(2 行)

以下の例では、customer表から customer_name列の値が「佐藤商事」の行データを検索します。

文字列データを指定する場合、’(シングルクオート)で前後を括ります。

ossdb=# SELECT * FROM customer WHERE customer_name = ’佐藤商事’;customer_id | customer_name

-------------+---------------

1 | 佐藤商事(1 行)

1.5.2 よりも大きい (>)、よりも小さい(未満)(<)

ある列の値が指定した条件値よりも大きい、あるいは小さい(未満)データを取り出します。条

件値そのものは含まれません。

以下の例では、prod表から price列の値が 70よりも大きい行データを検索します。price列の値

が 70のりんごは含まれません。

ossdb=# SELECT * FROM prod WHERE price > 70;prod_id | prod_name | price

---------+-----------+-------

3 | メロン | 100

(1 行)

LPI-Japan 10 www.oss-db.jp

Page 21: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.6 ORDER BY句による並び替え

1.5.3 以上 (>=)、以下 (<=)

ある列の値が指定した条件値以上、あるいは以下のデータを取り出します。条件値そのものも含

まれます。

以下の例では、prod 表から price 列の値が 70 以上の行データを検索します。price 列の値が 70

のりんごも含まれます。

ossdb=# SELECT * FROM prod WHERE price >= 70;prod_id | prod_name | price

---------+-----------+-------

2 | りんご | 70

3 | メロン | 100

(2 行)

1.6 ORDER BY句による並び替え

検索結果を指定した順番に並び替えるには、ORDER BY句を使用します。リレーショナルデー

タベースではデータは集合として扱われるため、検索される行の順番は保証されません。ORDER

BY 句で並び替えを指定することで、期待した順番で行データを取り出すことができます。DESC

を指定すると、降順で並び替えが行われます。

ORDER BY句の構文

ORDER BY 列名 [DESC]

以下の例では、prod表から price列の値で昇順、降順で並び替えをしています。

ossdb=# SELECT * FROM prod ORDER BY price;prod_id | prod_name | price

---------+-----------+-------

1 | みかん | 50

2 | りんご | 70

3 | メロン | 100

(3 行)

ossdb=# SELECT * FROM prod ORDER BY price DESC;prod_id | prod_name | price

---------+-----------+-------

3 | メロン | 100

2 | りんご | 70

1 | みかん | 50

(3 行)

LPI-Japan 11 www.oss-db.jp

Page 22: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.7 表の結合

1.7 表の結合

リレーショナルデータベースでは、表と表を結びつけてデータを取り出すことができます。表を

結びつけることを「結合」と呼びます。

1.7.1 JOIN句による結合

結合を行うには JOIN 句で結合したい列を指定します。指定された列の値を比較し、同じ値の

データを結合します。

以下の例では、結合を行う元となる表である orders表の order_id列、customer_id列、prod_id

列、qty列を SELECT項目リストに指定した SELECT文です。

ossdb=# SELECT order_id,customer_id,prod_id,qty FROM orders;order_id | customer_id | prod_id | qty

----------+-------------+---------+-----

1 | 1 | 1 | 10

2 | 2 | 2 | 5

3 | 3 | 3 | 8

4 | 2 | 1 | 3

5 | 3 | 2 | 4

(5 行)

この検索結果のうち、customer_id 列と prod_id 列はそれぞれ customer 表、prod 表から別の

値を持ってきて置き換えることにします。

FROM句または JOIN句で複数の表を指定した場合には、SELECT項目リストで「表名.列名」

と指定する必要があります。

JOIN句による結合

FROM 表 1

JOIN 表 2 ON 表 1.列 = 表 2.列

まず、orders 表と customer 表の 2 つの表を JOIN 句で結合します。簡単にするために orders

表の order_id 列と customer 表の customer_name 列だけを SELECT 項目リストに指定してい

ます。

ossdb=# SELECT orders.order_id,customer.customer_nameFROM ordersJOIN customer ON orders.customer_id = customer.customer_id;order_id | customer_name

----------+---------------

1 | 佐藤商事

LPI-Japan 12 www.oss-db.jp

Page 23: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.7 表の結合

2 | 鈴木物産4 | 鈴木物産3 | 高橋商店5 | 高橋商店

(5 行)

同様に、orders表と customer表を JOIN句で結合します。

ossdb=# SELECT orders.order_id,prod.prod_nameFROM ordersJOIN prod ON orders.prod_id = prod.prod_id;order_id | prod_name

----------+-----------

1 | みかん4 | みかん2 | りんご5 | りんご3 | メロン

(5 行)

LPI-Japan 13 www.oss-db.jp

Page 24: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.7 表の結合

この 2 つの JOIN 句を 1 つの SELECT 文にまとめます。最初の SELECT 文と比較して、

SELECT項目リストの置き換わりと、JOIN句が 2つ並べて追加されている点に注目してください。

最初に実行した SELECT文

SELECT order_id,customer_id,prod_id,qty FROM orders;

ossdb=# SELECT orders.order_id,customer.customer_name,prod.prod_name,orders.qtyFROM ordersJOIN customer ON orders.customer_id = customer.customer_idJOIN prod ON orders.prod_id = prod.prod_id;order_id | customer_name | prod_name | qty

----------+---------------+-----------+-----

1 | 佐藤商事 | みかん | 10

4 | 鈴木物産 | みかん | 3

2 | 鈴木物産 | りんご | 5

5 | 高橋商店 | りんご | 4

3 | 高橋商店 | メロン | 8

(5 行)

1.7.2 表別名の利用

SQL文の中で何度も使用する表名は、FROM句、または JOIN句で別名を指定できます。短い

別名を指定すれば、SQL文を短くして見やすくすることができます。

表別名の指定方法

FROM 表名 別名JOIN 表名 別名

前の JOIN句による結合を行う SQL文に表別名を適用すると、以下のようになります。

ossdb=# SELECT o.order_id,c.customer_name,p.prod_name,o.qtyFROM orders oJOIN customer c ON o.customer_id = c.customer_idJOIN prod p ON o.prod_id = p.prod_id;order_id | customer_name | prod_name | qty

----------+---------------+-----------+-----

1 | 佐藤商事 | みかん | 10

4 | 鈴木物産 | みかん | 3

2 | 鈴木物産 | りんご | 5

5 | 高橋商店 | りんご | 4

3 | 高橋商店 | メロン | 8

(5 行)

LPI-Japan 14 www.oss-db.jp

Page 25: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.8 行データの入力(INSERT)

1.8 行データの入力(INSERT)

表に行データを入力するには、INSERT文を使用します。

INSERT文の構文

INSERT INTO 表名 (列名 [,…])

VALUES (値 [,...])

値に文字列データを指定する場合には、’(シングルクオート)で括る必要があります。

ossdb=# INSERT INTO prod(prod_id,prod_name,price) VALUES (4,’バナナ’,30);INSERT 0 1

ossdb=# SELECT * FROM prod;prod_id | prod_name | price

---------+-----------+-------

1 | みかん | 50

2 | りんご | 70

3 | メロン | 100

4 | バナナ | 30

(4 行)

1.9 データの更新(UPDATE)

行データの更新を行うには、UPDATE文を使用します。

UPDATE文の構文

UPDATE 表名SET 列名 = 値WHERE 条件式

以下の例では、prod 表の prod_id 列の値が 4 の行データを、price 列の値を 40 に更新してい

ます。

ossdb=# UPDATE prod SET price = 40 WHERE prod_id = 4;UPDATE 1

ossdb=# SELECT * FROM prod;prod_id | prod_name | price

LPI-Japan 15 www.oss-db.jp

Page 26: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.10 行データの削除(DELETE)

---------+-----------+-------

1 | みかん | 50

2 | りんご | 70

3 | メロン | 100

4 | バナナ | 40

(4 行)

更新値の設定には、既存の行データの値に対する演算で設定することもできます。

以下の例では、prod表の price列の値を一律 10増加させています(その後、元に戻しています)。

ossdb=# UPDATE prod SET price = price + 10;UPDATE 4

ossdb=# SELECT * FROM prod;prod_id | prod_name | price

---------+-----------+-------

1 | みかん | 60

2 | りんご | 80

3 | メロン | 110

4 | バナナ | 40

(4 行)

ossdb=# UPDATE prod SET price = price - 10;UPDATE 4

1.10 行データの削除(DELETE)

行データの削除を行うには、DELETE文を使用します。DELETE文はWHERE句で指定した

条件式に適合した行データをすべて削除します。WHERE句を指定しなかった場合には、指定され

た表の行データはすべて削除されます。

DELETE文の構文

DELETE FROM 表名WHERE 条件式

以下の例では、prod表から prod_id列の値が 4の行データを削除しています。

ossdb=# DELETE FROM prod WHERE prod_id = 4;DELETE 1

ossdb=# SELECT * FROM prod;prod_id | prod_name | price

---------+-----------+-------

1 | みかん | 50

LPI-Japan 16 www.oss-db.jp

Page 27: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 1章 SQLによるデータベースの操作 基礎編 1.10 行データの削除(DELETE)

2 | りんご | 70

3 | メロン | 100

(3 行)

LPI-Japan 17 www.oss-db.jp

Page 28: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第2章

データ型

PostgreSQL では、データをいくつかのデータ型に分類して保管しています。これまで利用

してきたサンプルデータベースでは、以下の 3つのデータ型を使用しています。

・数値データ型

・文字列データ型

・日付データ型

この章では、PostgreSQL が扱えるデータ型について学びます。それぞれのデータ型の特長

を理解しましょう。

2.1 数値データ型

数値データ型は、いわゆる「数字」を保管するためのデータ型です。データベースでは四則演算

をはじめ、様々な数値演算のための関数などが用意されているので、簡単に数値データを加工して

取り扱うことができます。

2.1.1 integer型

整数のデータ型です。-2147483648から +2147483647までの整数値を格納することができます。

整数値のため、小数点以下の値は格納されません。小数点以下の値は四捨五入されます。

以下の例では、値を 30.4 で INSERT すると小数点以下は四捨五入されて 30 で格納されていま

す。値を 30.5に UPDATEすると四捨五入されて 31で格納されています。

ossdb=# INSERT INTO prod(prod_id,prod_name,price) VALUES (4,’バナナ’,30.4);INSERT 0 1

ossdb=# SELECT * FROM prod WHERE prod_id = 4;prod_id | prod_name | price

---------+-----------+-------

4 | バナナ | 30

(1 行)

ossdb=# UPDATE prod SET price = 30.5 WHERE prod_id = 4;UPDATE 1

ossdb=# SELECT * FROM prod WHERE prod_id = 4;prod_id | prod_name | price

---------+-----------+-------

LPI-Japan 18 www.oss-db.jp

Page 29: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 2章データ型 2.1 数値データ型

4 | バナナ | 31

(1 行)

2.1.2 numeric型

任意の精度の数値データ型です。小数点以下の値を含む数値を格納することができます。整数部

分と小数点以下の部分を合わせて 1000桁までの値を取ることができます。桁数を指定する場合、整

数と小数点以下を合わせた桁数を「精度」、小数点以下の桁数を「位取り」と呼び、以下のように指

定します。

numeric(精度,位取り)

たとえば「numeric(6,2)」と指定すると、全体の桁数は 6桁、小数点以下は 2桁、整数部は 6-2で

4桁なので最大 9999.99までの値を格納することができます。

以下の例では、numeric型の id列を持った numeric_test表を作成しています。整数部は 4桁な

ので、5桁の値である 19999を指定した INSERT文はエラーとなっています。

ossdb=# CREATE TABLE numeric_test(id numeric(6,2));CREATE TABLE

ossdb=# Yd numeric_testテーブル "public.numeric_test"

カラム | 型 | 修飾語--------+--------------+--------

id | numeric(6,2) |

ossdb=# INSERT INTO numeric_test VALUES (9999.99);INSERT 0 1

ossdb=# INSERT INTO numeric_test VALUES (19999.99);ERROR: numericフィールドがオーバーフローしていますDETAIL: 精度 6、位取り 2を持つフィールドは、 10^4より小さな絶対値に丸められます。

2.1.3 その他の数値型

PostgreSQL は integer 型、numeric 型以外の数値型も備えています。たとえば decimal 型は

numeric型と同じ意味を持つデータ型です。これらはデータの性質に合わせたデータベースへの保

管や、互換性の維持などの目的のために用意されています。

LPI-Japan 19 www.oss-db.jp

Page 30: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 2章データ型 2.2 文字列データ型

表 2.1 数値型一覧表

データ型 サイズ 範囲

smallint 2バイト -32768から +32767integer 4バイト -2147483648から +2147483647bigint 8バイト -9223372036854775808から +9223372036854775807decimal 可変長 最大 1000桁numeric 可変長 最大 1000桁real 4バイト 6桁精度double precision 8バイト 15桁精度serial 4バイト 1から 2147483647bigserial 8バイト 1から 9223372036854775807

2.2 文字列データ型

文字列データ型は、文字のデータを保管することができます。数値型に比べて演算などを行うこ

とはできませんが、LIKE演算子のように部分一致検索などを行うことができます。

2.2.1 character varying型 (varchar型)

文字数に上限のある可変長の文字列型です。可変長ですから、文字数制限内であれば何文字の文

字データでも構いません。上限を超えた分の文字を格納しようとすると、エラーになります。

以下の例では、長さ 3の varchar型を持った varchar_test表を作成しています。文字数の長さは

半角、全角にかかわらず長さ 3(3文字)を超えるとエラーとなります。

ossdb=# CREATE TABLE varchar_test(varstring varchar(3));CREATE TABLE

ossdb=# INSERT INTO varchar_test VALUES (’ABC’);INSERT 0 1

ossdb=# INSERT INTO varchar_test VALUES (’あいうえお’);ERROR: 値は型 character varying(3)としては長すぎますossdb=# INSERT INTO varchar_test VALUES (’あいう’);INSERT 0 1

ossdb=# INSERT INTO varchar_test VALUES (’あい UE’);ERROR: 値は型 character varying(3)としては長すぎますossdb=# SELECT * FROM varchar_test;varstring

-----------

ABC

あいう(2 行)

LPI-Japan 20 www.oss-db.jp

Page 31: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 2章データ型 2.3 日付・時刻データ型

2.2.2 character型 (char型)

文字数に上限のある固定長の文字列型です。固定長のため、足りない分の文字数は空白で埋めら

れます。上限を超えた分の文字を格納しようとすると、エラーになります。

以下の例では、長さ 3の char型を持った char_test表を作成しています。文字数の長さは半角、

全角にかかわらず長さ 3(3文字)を超えるとエラーとなります。

ossdb=# create table char_test(string char(3));CREATE TABLE

ossdb=# INSERT INTO char_test VALUES (’ABC’);INSERT 0 1

ossdb=# INSERT INTO char_test VALUES (’あいうえお’);ERROR: 値は型 character(3)としては長すぎますossdb=# INSERT INTO char_test VALUES (’あいう’);INSERT 0 1

ossdb=# INSERT INTO char_test VALUES (’あい UE’);ERROR: 値は型 character(3)としては長すぎますossdb=# SELECT * FROM char_test;string

--------

ABC

あいう(2 行)

2.2.3 text型

文字数に上限のない可変長の文字列型です。文字列長の指定が必要ないため便利ですが、ANSI

SQL標準には定義されていないデータ型です。

2.3 日付・時刻データ型

日付・時刻データ型は、日付と時刻を別々に格納するデータ型と、両方を同時に格納するデータ

型の 3つが使用できます。目的に応じて使い分けるとよいでしょう。日付・時刻データ型の取り扱

い方については、後述します。

2.3.1 date型

日付だけを格納するデータ型です。時刻の情報が必要ない場合に使用します。

2.3.2 time型

時刻だけを格納するデータ型です。日付の情報が必要ない場合に使用します。

LPI-Japan 21 www.oss-db.jp

Page 32: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 2章データ型 2.3 日付・時刻データ型

2.3.3 timestamp型

日付と時刻の両方を格納するデータ型です。

LPI-Japan 22 www.oss-db.jp

Page 33: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第3章

データベース定義基礎編

この章では、データベース定義の基礎である表の作成について学びます。実際に表を作成し、

データを格納してみましょう。

3.1 表の作成(CREATE TABLE)

前の章ではすでにデータベースに作成されていた表に対して SQL文を実行していましたが、実際

のデータベースでは利用者が表の作成から行う必要があります。

3.1.1 表を作成する

表の作成は、CREATE TABLE文を使用します。

CREATE TABLE文の構文

CREATE TABLE 表名(列名 データ型 [NULL|NOT NULL]

| [UNIQUE]

| [PRIMARY KEY (列名 [,...])]

| [REFERNCES 外部参照表名 (参照列名)]

[,...])

表を作成するには、列の名前と、その列にどのようなデータが入るのかを決めなければいけませ

ん。ここでは仮に、以下のような 3つの列を持つテーブルを作成します。

表 3.1 staff表の定義

列名 データ型

社員番号 id integer型氏名 name text型誕生日 birthday date型

これを SQL 文にすると、以下のようになります。作成ができたら、表の一覧に入っていること

と、表の定義を確認しておきましょう。

LPI-Japan 23 www.oss-db.jp

Page 34: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 3章データベース定義 基礎編 3.2 表定義の修正(ALTER TABLE)

ossdb=# CREATE TABLE staff(id integer,name text,birthday date);CREATE TABLE

ossdb=# Ydリレーションの一覧

スキーマ | 名前 | 型 | 所有者----------+--------------+----------+----------

public | char_test | テーブル | postgres

public | customer | テーブル | postgres

public | numeric_test | テーブル | postgres

public | orders | テーブル | postgres

public | prod | テーブル | postgres

public | staff | テーブル | postgres

(6 行)

ossdb=# Yd staffテーブル "public.staff"

カラム | 型 | 修飾語----------+---------+--------

id | integer |

name | text |

birthday | date |

3.1.2 staff表にデータを格納する

INSERT文を使って staff表にデータを格納してみましょう。

ossdb=# INSERT INTO staff (id,name,birthday) VALUES (1,’宮原徹’,’1972-01-09’);INSERT 0 1

ossdb=# SELECT * FROM staff;id | name | birthday

----+--------+------------

1 | 宮原徹 | 1972-01-09

(1 行)

3.2 表定義の修正(ALTER TABLE)

表を作成した後から表定義を修正するには ALTER TABLE文を使用します。ここでは新たに列

を追加する ALTER TABLE文を試してみましょう。staff表に customer_id列を追加し、その列

に UPDATE文で値を格納しています。

LPI-Japan 24 www.oss-db.jp

Page 35: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 3章データベース定義 基礎編 3.3 表の削除(DROP TABLE)

ossdb=# ALTER TABLE staff ADD COLUMN customer_id integer;ALTER TABLE

ossdb=# Yd staffテーブル "public.staff"

カラム | 型 | 修飾語-------------+---------+--------

id | integer |

name | text |

birthday | date |

customer_id | integer |

ossdb=# UPDATE staff SET customer_id = 1 WHERE id = 1;UPDATE 1

ossdb=# SELECT * FROM staff;id | name | birthday | customer_id

----+--------+------------+-------------

1 | 宮原徹 | 1972-01-09 | 1

(1 行)

3.2.1 表定義の修正は原則として行わない

ALTER TABLE文で修正できる内容は様々ですが、すでにデータが格納されている状態で列の

定義を修正するのは、データの不整合などを招くことがあるため望ましくありません。

表定義の修正を行いたい時は表を作成する CREATE TABLE文を修正し、再度表を作成するこ

と。また、新たに新しいデータをデータベースに格納したい場合には、そのための表を新規に作成

し、既存の表と関連づけるのが正しいやり方です。

ただし、すでに大量の行データが格納されており、かつ新規に表を作成して結合する方法が現実

的でない場合には、やむを得ず表定義の修正を行うことがあるでしょう。

3.3 表の削除(DROP TABLE)

表を削除するには、DROP TABLE文を使用します。表を削除すると、表に格納されているデー

タも一緒に削除されて元に戻すことができません。

ossdb=# Ydリレーションの一覧

スキーマ | 名前 | 型 | 所有者----------+--------------+----------+----------

public | char_test | テーブル | postgres

public | customer | テーブル | postgres

public | numeric_test | テーブル | postgres

public | orders | テーブル | postgres

public | prod | テーブル | postgres

public | staff | テーブル | postgres

(6 行)

LPI-Japan 25 www.oss-db.jp

Page 36: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 3章データベース定義 基礎編 3.3 表の削除(DROP TABLE)

ossdb=# DROP TABLE staff;DROP TABLE

ossdb=# Ydリレーションの一覧

スキーマ | 名前 | 型 | 所有者----------+--------------+----------+----------

public | char_test | テーブル | postgres

public | customer | テーブル | postgres

public | numeric_test | テーブル | postgres

public | orders | テーブル | postgres

public | prod | テーブル | postgres

(5 行)

3.3.1 DELETE文と DROP TABLE文、TRUNCATE文の使い分け

データだけを削除したい場合には DELETE文を使用しますが、DELETE文でのデータ削除は対

象となるデータの件数が多いと時間がかかることがあります。大量のデータを削除したい場合には、

DROP TABLE文を使う方法と、TRAUNCATE文を使う方法があります。

DROP TABLE 文は表と表データだけでなく、関連するその他のものも削除してしまうため、

再作成に時間がかかるなどの問題が発生することがあります。行データだけを削除する場合には

TRUNCATE文を使用します。

TRUNCATE文の構文

TRAUNCATE 表名

以下の例では、char_test表の行データをすべて TRUNCATE文で削除しています。

ossdb=# SELECT * FROM char_test;string

--------

ABC

あいう(2 行)

ossdb=# TRUNCATE char_test;TRUNCATE TABLE

ossdb=# SELECT * FROM char_test;string

--------

(0 行)

LPI-Japan 26 www.oss-db.jp

Page 37: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 3章データベース定義 基礎編 3.4 行データのセーブ・ロード

3.4 行データのセーブ・ロード

COPY文を使用すると、行データをファイルにセーブしたり、ファイルからロードすることがで

きます。FORMAT句で csvを指定することで、CSV形式のファイルをセーブ、ロードができます。

3.4.1 行データのセーブ

COPY TO文で行データをファイルにセーブできます。

COPY文の構文

COPY 表名 TO ファイル (FORMAT 形式)

以下の例は、customer表のデータを CSV形式でファイルにセーブしています。Y!メタコマンド

は、Linuxのシェルコマンドを実行しています。

ossdb=# COPY customer TO ’/var/lib/pgsql/customer.csv’ (FORMAT csv);COPY 3

ossdb=# Y! cat /var/lib/pgsql/customer.csv1,佐藤商事2,鈴木物産3,高橋商店

3.4.2 CSVファイルのロード

COPY FROM文でファイルから行データをロードできます。

COPY文の構文

COPY 表名 FROM ファイル (FORMAT 形式)

以下の例は、customer表のデータを CSV形式のファイルからロードしています。

ossdb=# DELETE FROM customer;DELETE 3

ossdb=# SELECT * FROM customer;customer_id | customer_name

-------------+---------------

(0 行)

LPI-Japan 27 www.oss-db.jp

Page 38: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 3章データベース定義 基礎編 3.4 行データのセーブ・ロード

ossdb=# COPY customer FROM ’/var/lib/pgsql/customer.csv’ (FORMAT csv);COPY 3

ossdb=# SELECT * FROM customer;customer_id | customer_name

-------------+---------------

1 | 佐藤商事2 | 鈴木物産3 | 高橋商店

(3 行)

3.4.3 YCOPYメタコマンド

psqlは COPY文と同様の動作をする YCOPYメタコマンドが使用できます。異なるのは以下の

点です。

ファイル指定が絶対指定のほか、psql実行時のカレントディレクトリからの相対指定でも可能

形式の指定が with csv

具体的な使用例はこの後の演習で解説します。

LPI-Japan 28 www.oss-db.jp

Page 39: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第4章

基礎編演習

これまでの章で SQLを使ったデータベースの基礎について学びました。2つの演習問題で、

学習した内容を確認してみましょう。

4.1 演習 1

(1) すべての商品の価格を 10%アップします

(2) 価格が 100以上の商品の価格を元に戻します

(3) 表のデータをすべてファイルにコピーします

(4) 表をすべて削除します

(5) 表を再度作成します

(6) データをファイルからコピーします

表の定義はあらかじめ確認しておきましょう。また、巻末の付録にも表を作成するための

CREATE TABLE文の例がありますので、参考にしてください。

解答例はこの章の最後にあります。

4.2 演習 2:郵便番号データベース

郵便番号データベースを作成してみましょう。郵便番号のデータは CSV 形式で公開されていま

す。この郵便番号データを格納するデータベースを設計し、実際にデータを格納してみましょう。

4.2.1 郵便番号データのダウンロード

郵便番号データは以下のWebページからダウンロードできます。

郵便番号データダウンロード Webページ

http://www.post.japanpost.jp/zipcode/download.html

データは LHA形式と ZIP形式の 2種類があります。データ形式によってページが分かれていま

すが、デフォルトは LHA形式のダウンロードページにリンクされているので、「zip形式でのダウ

ンロードはこちら」をクリックして ZIP形式でダウンロードしてください。

以下の例は、wgetコマンドを使って郵便番号 CSVデータをダウンロードして、unzipコマンド

LPI-Japan 29 www.oss-db.jp

Page 40: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 4章基礎編 演習 4.2 演習 2:郵便番号データベース

で解凍しています。

-bash-3.2$ wget http://www.post.japanpost.jp/zipcode/dl/oogaki/zip/ken_all.zip--2011-09-18 21:32:34-- http://www.post.japanpost.jp/zipcode/dl/oogaki/zip/ken_all.zip

www.post.japanpost.jp を DNSに問いあわせています... 122.215.192.22

www.post.japanpost.jp|122.215.192.22|:80 に接続しています... 接続しました。HTTP による接続要求を送信しました、応答を待っています... 200 OK

長さ: 1836092 (1.8M) [application/zip]

‘ken_all.zip’ に保存中

100%[======================================>] 1,836,092 2.15M/s 時間 0.8s

2011-09-18 21:32:36 (2.15 MB/s) - ‘ken_all.zip’ へ保存完了 [1836092/1836092]

-bash-3.2$ unzip ken_all.zipArchive: ken_all.zip

inflating: KEN_ALL.CSV

-bash-3.2$ -bash-3.2$ls -l KEN_ALL.CSV}

-rw-r--r-- 1 postgres postgres 12156972 8月 25 16:17 KEN_ALL.CSV

4.2.2 郵便番号データベース表の作成

データの項目は以下の通りです。

• 全国地方公共団体コード (JIS X0401、X0402)……… 半角数字

• (旧)郵便番号 (5桁)……………………………………… 半角数字

• 郵便番号 (7桁)……………………………………… 半角数字

• 都道府県名 ………… 半角カタカナ (コード順に掲載)

• 市区町村名 ………… 半角カタカナ (コード順に掲載)

• 町域名 ……………… 半角カタカナ (五十音順に掲載)

• 都道府県名 ………… 漢字 (コード順に掲載)

• 市区町村名 ………… 漢字 (コード順に掲載)

• 町域名 ……………… 漢字 (五十音順に掲載)

• 一町域が二以上の郵便番号で表される場合の表示• 小字毎に番地が起番されている町域の表示• 丁目を有する町域の場合の表示• 一つの郵便番号で二以上の町域を表す場合の表示• 更新の表示• 変更理由

データは以下のような内容です。

-bash-3.2$ head -5 KEN_ALL_UTF8.CSV

LPI-Japan 30 www.oss-db.jp

Page 41: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 4章基礎編 演習 4.2 演習 2:郵便番号データベース

01101,"060 ","0600000","ホツカイドウ","サツポロシチユウオウク","イカニケイサイガナイバアイ","北海道","札幌市中央区","以下に掲載がない場合",0,0,0,0,0,0

01101,"064 ","0640941","ホツカイドウ","サツポロシチユウオウク","アサヒガオカ","北海道","札幌市中央区","旭ケ丘",0,0,1,0,0,0

01101,"060 ","0600041","ホツカイドウ","サツポロシチユウオウク","オオドオリヒガシ","北海道","札幌市中央区","大通東",0,0,1,0,0,0

01101,"060 ","0600042","ホツカイドウ","サツポロシチユウオウク","オオドオリニシ (1-19チヨウメ)","北海道","札幌市中央区","大通西(1~19丁目)",1,0,1,0,0,0

01101,"064 ","0640820","ホツカイドウ","サツポロシチユウオウク","オオドオリニシ (20-28チヨウメ)","北海道","札幌市中央区","大通西(20~28丁目)",1,0,1,0,0,0

以下の例は、文字列データを char型および text型で定義した表作成のための CREATE TABLE

文です。

ossdb=# CREATE TABLE zip (lgcode char(5),oldzip char(5),newzip char(7),prefkana text,citykana text,areakana text,pref text,city text,area text,largearea integer,koaza integer,choume integer,smallarea integer,change integer,reason integer);CREATE TABLE

4.2.3 データの文字コードについて

ダウンロードできる CSVデータは、日本語部分がシフト JISで作成されています。一方、現在使

用しているデータベースは日本語を UTF-8で格納するようにしているため、文字コードを UTF-8

に揃える必要があります。

シフト JISのデータを UTF-8に変換するには、psqlで Yencodingメタコマンドを使用する方法

と、Linuxのコマンドで文字コード変換をする方法があります。

Yencodingメタコマンドを使用する方法

Yencodingメタコマンドを使用すると、psqlが扱うデータの文字コードを変更できます。

以下の例は、Yencodingメタコマンドで psqlが扱うデータの文字コードをシフト JISに変更して

います。データベースは UTF-8で格納するので、シフト JISから UTF-8への文字コード変換が行

LPI-Japan 31 www.oss-db.jp

Page 42: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 4章基礎編 演習 4.2 演習 2:郵便番号データベース

われます。

ossdb=# Yencoding SJISossdb=# Ycopy zip from KEN_ALL.CSV with csvossdb=# Yencoding UTF-8

Linuxのコマンドを使用する方法

Linuxであれば nkfコマンドで文字コード変換が行えます。他に iconvコマンドも使用できます

が、改行コードを別途 dos2unixコマンドで変換する必要があります。Linux環境によっては nkfコ

マンドがインストールされていない場合がありますので、その場合には yumコマンドでインストー

ルしてください。

nkfコマンドで郵便番号データを UTF-8に変換

bash-3.2$ nkf -w KEN_ALL.CSV > KEN_ALL_UTF8.CSV

iconvコマンドと dos2unixコマンドで郵便番号データを UTF-8に変換

bash-3.2$ iconv -f SHIFT-JIS -t UTF-8 KEN_ALL.CSV | dos2unix > KEN_ALL_UTF8.CSV

変換後、psqlから Ycopyメタコマンドでロードします。

ossdb=# Ycopy zip from KEN_ALL_UTF8.CSV with csv

4.2.4 郵便番号データの確認

ロードされた郵便番号データを確認します。

以下の例では、現在使用されている郵便番号のデータが格納されている newzip列で絞り込み検索

を行っています。

ossdb=# SELECT * FROM zip WHERE newzip = ’1500002’;lgcode | oldzip | newzip | prefkana | citykana | areakana | pref | city | area | largearea | koaza

| choume | smallarea | change | reason

--------+--------+---------+----------+----------+----------+--------+--------+------+-----------+-------

+--------+-----------+--------+--------

LPI-Japan 32 www.oss-db.jp

Page 43: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 4章基礎編 演習 4.3 練習の解答

13113 | 150 | 1500002 | トウキヨウト | シブヤク | シブヤ | 東京都 | 渋谷区 | 渋谷 | 0 | 0

| 1 | 0 | 0 | 0

(1 行)

4.3 練習の解答

(1) すべての商品の価格を 10%アップします

ossdb=# UPDATE prod SET price = price * 1.1;

UPDATE文の SET句で指定する値は、その行データの元の値に対する演算結果を新しい値とし

て設定することができます。

(2) 価格が 100以上の商品の価格を元に戻します

ossdb=# UPDATE prod SET price = price / 11 * 10 WHERE price >= 100;

前の問題で 1.1倍にしているため、SET句で 11分の 10にするための計算を行っています。

(3) 表のデータをすべてファイルにコピーします

ossdb=# COPY prod TO ’/var/lib/pgsql/prod.csv’ (FORMAT csv);ossdb=# COPY customer TO ’/var/lib/pgsql/customer.csv’ (FORMAT csv);ossdb=# COPY orders TO ’/var/lib/pgsql/orders.csv’ (FORMAT csv);

COPY文で 3つの表のデータをファイルにコピーします。

(4) 表をすべて削除します

ossdb=# DROP TABLE prod;ossdb=# DROP TABLE customer;ossdb=# DROP TABLE orders;

DROP TABLE文で 3つの表を削除します。

LPI-Japan 33 www.oss-db.jp

Page 44: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 4章基礎編 演習 4.3 練習の解答

(5) 表を再度作成します

CREATE TABLE prod

(prod_id integer,

prod_name text,

price integer);

CREATE TABLE customer

(customer_id integer,

customer_name text);

CREATE TABLE orders

(order_id integer,

order_date timestamp,

customer_id integer,

prod_id integer,

qty integer);

3つの表を作成します。

(6) データをファイルからコピーします

ossdb=# COPY prod FROM ’/var/lib/pgsql/prod.csv’ (FORMAT csv);ossdb=# COPY customer FROM ’/var/lib/pgsql/customer.csv’ (FORMAT csv);ossdb=# COPY orders FROM ’/var/lib/pgsql/orders.csv’ (FORMAT csv);

コピーしておいたファイルから、3つの表にデータをコピーします。

LPI-Japan 34 www.oss-db.jp

Page 45: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第5章

SQLによるデータベースの操作応用編

この章では、データベース操作に使用する SQL文の様々な文法のうち、特に多用する文法に

ついて学びます。

5.1 AND/OR演算子

SELECT文に指定するWHERE句などの条件で、複数の条件を設定したい場合には AND演算

子、OR演算子が使用できます。AND演算子は指定した条件が両方満たされる場合、OR演算子は

指定した条件のいずれかが満たされる場合に SQL文の結果が表示されます。

以下の例は、prod表の price列の値が 50よりも大きく、100よりも小さい行データのみを検索し

ています。

ossdb=# SELECT * FROM prod;prod_id | prod_name | price

---------+-----------+-------

1 | みかん | 50

2 | りんご | 70

3 | メロン | 100

4 | バナナ | 31

(4 行)

ossdb=# SELECT * FROM prod WHERE price > 50 AND price < 100;prod_id | prod_name | price

---------+-----------+-------

2 | りんご | 70

(1 行)

以下の例は、customer表の customer_id列が 1または 2の行データを検索しています。

ossdb=# SELECT * FROM customer WHERE customer_id = 1 OR customer_id = 2;customer_id | customer_name

-------------+---------------

1 | 佐藤商事2 | 鈴木物産

(2 行)

LPI-Japan 35 www.oss-db.jp

Page 46: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 5章 SQLによるデータベースの操作 応用編 5.2 LIKE演算子

5.2 LIKE演算子

ある列の値が指定した条件に部分的に一致する行データを取り出します。

表 5.1 LIKE演算子で使用できるワイルドカード

_ 1文字% 0文字以上の文字列

以下の例では、customer表の customer_name列が「鈴木」で始まる行データを検索しています。

ossdb=# SELECT * FROM customer WHERE customer_name LIKE ’鈴木%’;customer_id | customer_name

-------------+---------------

2 | 鈴木物産(1 行)

以下の例では、customer表の customer_name列に「商」が含まれる行データを検索しています。

前後に %がついているので、値のどこに「商」があっても検索条件に一致します。

ossdb=# SELECT * FROM customer WHERE customer_name LIKE ’%商%’;customer_id | customer_name

-------------+---------------

1 | 佐藤商事3 | 高橋商店

(2 行)

LIKE演算子は便利な反面、性能上検索速度が遅くなる場合があるので、注意して使う必要がある

でしょう。

5.3 BETWEEN演算子

ある列の値が指定した 2つの条件値の範囲内にあるデータを取り出します。2つの条件値は AND

句で指定します。条件値そのものも含まれるので「○以上、○以下」という条件であると考えれば

よいでしょう。

以下の例では、prod表の price列が 50から 70の間の行データを検索しています。

LPI-Japan 36 www.oss-db.jp

Page 47: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 5章 SQLによるデータベースの操作 応用編 5.4 集約関数

ossdb=# SELECT * FROM prod WHERE price BETWEEN 50 AND 70;prod_id | prod_name | price

---------+-----------+-------

1 | みかん | 50

2 | りんご | 70

(2 行)

5.4 集約関数

集約関数を使用すると、データを SQL文で集計することができます。

主な集約関数

• count関数

• sum関数

• avg関数

• max関数

• min関数

5.4.1 count関数

count関数はデータの行数を数える関数です。

ossdb=# SELECT count(*) FROM orders;count

-------

5

(1 行)

5.4.2 sum関数

sum関数は指定された列の合計を計算する関数です。

ossdb=# SELECT sum(qty) FROM orders;sum

-----

30

(1 行)

LPI-Japan 37 www.oss-db.jp

Page 48: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 5章 SQLによるデータベースの操作 応用編 5.4 集約関数

5.4.3 avg関数

avg関数は指定された列の平均を計算する関数です。

ossdb=# SELECT avg(qty) FROM orders;avg

--------------------

6.0000000000000000

(1 行)

5.4.4 max関数

max関数は指定された列の最大値を計算する関数です。

ossdb=# SELECT max(qty) FROM orders;max

-----

10

(1 行)

5.4.5 min関数

min関数は指定された列の最小値を計算する関数です。

ossdb=# SELECT min(qty) FROM orders;min

-----

3

(1 行)

5.4.6 GROUP BY句と集約関数の組み合わせ

GROUP BY句を使うと、指定された列で行をグループ化し、それぞれのグループ毎に集約関数

の計算を行うことができます。

以下の例は、orders表の行データを prod_id列の値毎にグループ化し、各グループ毎に集約関数

で計算を行っています。

LPI-Japan 38 www.oss-db.jp

Page 49: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 5章 SQLによるデータベースの操作 応用編 5.4 集約関数

ossdb=# SELECT prod_id,count(qty),sum(qty),avg(qty),min(qty),max(qty) FROM ordersGROUP BY prod_id;prod_id | count | sum | avg | min | max

---------+-------+-----+--------------------+-----+-----

1 | 2 | 13 | 6.5000000000000000 | 3 | 10

3 | 1 | 8 | 8.0000000000000000 | 8 | 8

2 | 2 | 9 | 4.5000000000000000 | 4 | 5

(3 行)

5.4.7 HAVING句

HAVING句を使うと、グループ化した後のグループに対して条件による絞り込みを行うことがで

きます。HAVING句はグループに対しての絞り込みを行うため、比較対象は集約関数である必要が

あります。

以下の例では、orders 表の行データを prod_id 列の値毎にグループ化し、qty 列の合計値が 10

未満の結果のみ取得しています。

ossdb=# SELECT prod_id,sum(qty) FROM ordersGROUP BY prod_id;prod_id | sum

---------+-----

1 | 13

3 | 8

2 | 9

(3 行)

ossdb=# SELECT prod_id,sum(qty) FROM ordersGROUP BY prod_idHAVING sum(qty) < 10;prod_id | sum

---------+-----

2 | 9

3 | 8

(2 行)

5.4.8 WHERE句、GROUP BY句、HAVING句の適用順序

集約関数を使った検索では、WHERE句、GROUP BY句、HAVING句が以下の順序で適用さ

れます。

1. WHERE句による行に対する絞り込み

2. GROUP BY句によるグループ化

3. HAVING句によるグループに対する絞り込み

LPI-Japan 39 www.oss-db.jp

Page 50: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 5章 SQLによるデータベースの操作 応用編 5.5 副問い合わせ

まず WHERE 句で検索対象になる行全体に対して絞り込みが行われます。この時点で除外さ

れた行は集約関数の対象にはなりません。次に GROUP BY 句によるグループ化が行われます。

HAVING句はこのグループに対して集約関数で計算を行い、指定された演算子に基づいて絞り込み

を行います。

5.5 副問い合わせ

副問い合わせは、SELECT文の中でさらに SELECT文を実行する SQLの記述です。副問い合

わせで検索された結果に基づいて主問い合わせを実行することができるので、動的な条件での検索

が可能になります。副問い合わせは EXISTS演算子、IN演算子と組み合わせて実行されます。

5.5.1 EXISTS演算子

EXISTS演算子は、副問い合わせの結果が行を 1行以上返した場合、主問い合わせが結果を返し

ます。

EXISTS演算子では、まず主問い合わせが実行され、返された行データの値が 1行ずつ副問い合

わせに渡されて実行されます。副問い合わせが行を 1行以上返すと、主問い合わせが返した行デー

タが最終的に結果として返されます。

以下の例では、主問い合わせで prod表から 1行ずつ行データを取り出し、副問い合わせで orders

表に対して prod_id列に同じ値が存在するかを確認します。みかん、りんご、メロンは orders表に

行データが存在していますが、prod_id列の値が 4のバナナは orders表に行データが存在していな

いため、主問い合わせの結果として返されません。

ossdb=# SELECT * FROM prod;prod_id | prod_name | price

---------+--------------+-------

1 | みかん | 50

2 | りんご | 70

3 | メロン | 100

4 | バナナ | 31

(4 行)

ossdb=# SELECT * FROM orders;order_id | order_date | customer_id | prod_id | qty

----------+----------------------------+-------------+---------+-----

1 | 2011-09-18 19:24:50.102562 | 1 | 1 | 10

2 | 2011-09-18 19:24:50.104937 | 2 | 2 | 5

3 | 2011-09-18 19:24:50.107026 | 3 | 3 | 8

4 | 2011-09-18 19:24:50.109223 | 2 | 1 | 3

5 | 2011-09-18 19:24:50.111255 | 3 | 2 | 4

(5 行)

ossdb=# SELECT prod_id,prod_name FROM prodWHERE EXISTS (SELECT * FROM orders WHERE orders.prod_id = prod.prod_id);prod_id | prod_name

---------+-----------

1 | みかん

LPI-Japan 40 www.oss-db.jp

Page 51: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 5章 SQLによるデータベースの操作 応用編 5.6 日付・時刻型データの取り扱い

2 | りんご3 | メロン

(3 行)

5.5.2 IN演算子

IN演算子は、副問い合わせの結果を主問い合わせのWHERE句の条件に対する値として実行さ

れます。

以下の例では、orders表の qty列の値が 5よりも大きい行データの prod_id列の値から、prod

表の prod_id列と prod_name列の値を取得しています。

ossdb=# SELECT prod_id FROM orders WHERE qty > 5;prod_id

---------

1

3

(2 行)

ossdb=# SELECT prod_id,prod_name FROM prodWHERE prod_id IN (SELECT prod_id FROM orders WHERE qty > 5);prod_id | prod_name

---------+-----------

1 | みかん3 | メロン

(2 行)

5.6 日付・時刻型データの取り扱い

日付・時刻型データは数値型や文字列型と異なり、特別な取り扱い方が用意されています。

5.6.1 日付形式を確認・設定する

日付の形式は国や環境によって異なります。PostgreSQL がどのような日付形式に設定されてい

るかを確認するには、SHOW DATESTYLEを実行します。

以下の例では、ISO書式で YMD、つまり年月日のスタイルであることが分かります。

ossdb=# SHOW DATESTYLE;DateStyle

-----------

ISO, YMD

(1 行)

LPI-Japan 41 www.oss-db.jp

Page 52: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 5章 SQLによるデータベースの操作 応用編 5.7 複雑な結合

5.6.2 now()関数

now()関数は、現在の日付と時刻を取得する関数です。

以下の例では、SELECT文で使用していますが、INSERT文や UPDATE文でも使用できます。

ossdb=# SELECT now();now

-------------------------------

2011-06-17 00:11:30.308848+09

(1 行)

5.6.3 CURRENT_DATE/CURRENT_TIME/CURRENT_TIMESTAMP関数

CURRENT_関数は、それぞれ現在の日付、時刻、日付と時刻を取得する関数です。

ossdb=# SELECT CURRENT_DATE;date

------------

2011-09-19

(1 行)

ossdb=# SELECT CURRENT_TIME;timetz

--------------------

14:01:22.972598+09

(1 行)

ossdb=# SELECT CURRENT_TIMESTAMP;now

-------------------------------

2011-09-19 14:01:39.366867+09

(1 行)

5.7 複雑な結合

JOIN句による通常の結合の他にも、外部結合や自己結合といった結合が存在しています。

5.7.1 外部結合

JOIN句による通常の結合(等価結合)では、結合する 2つの表の両方に行データが存在しないと

結合できないので、検索結果には含まれません。外部結合は、片方の表にしか存在しないため結合

できなかった行データも検索結果に含むことができる結合方式です。LEFT OUTER JOIN句を使

LPI-Japan 42 www.oss-db.jp

Page 53: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 5章 SQLによるデータベースの操作 応用編 5.7 複雑な結合

うと、結合の左側に来た表の行データがすべて検索結果に含まれるようになります。

以下の例では、customer表に新たな行データを追加し、customer表を左側にした orders表との

左外部結合を行っています。

ossdb=# INSERT INTO customer(customer_id,customer_name) VALUES (4,’藤原流通’);INSERT 0 1

ossdb=# SELECT * FROM customer;customer_id | customer_name

-------------+---------------

1 | 佐藤商事2 | 鈴木物産3 | 高橋商店4 | 藤原流通

(4 行)

ossdb=# SELECT c.customer_name,o.prod_id,o.qty FROM customer cLEFT OUTER JOIN orders o ON (c.customer_id = o.customer_id);customer_name | prod_id | qty

---------------+---------+-----

佐藤商事 | 1 | 10

鈴木物産 | 2 | 5

鈴木物産 | 1 | 3

高橋商店 | 3 | 8

高橋商店 | 2 | 4

藤原流通 | |

(6 行)

以下の例では、さらに別の prod表を LEFT OUTER JOIN句で結合しています。

ossdb=# SELECT c.customer_name,p.prod_name,o.qty FROM customer cLEFT OUTER JOIN orders o ON (c.customer_id = o.customer_id)LEFT OUTER JOIN prod p ON (o.prod_id = p.prod_id);customer_name | prod_name | qty

---------------+-----------+-----

佐藤商事 | みかん | 10

鈴木物産 | みかん | 3

鈴木物産 | りんご | 5

高橋商店 | りんご | 4

高橋商店 | メロン | 8

藤原流通 | |

(6 行)

5.7.2 自己結合

自己結合は、1つの表を別名を使って 2つの表に見立てて結合する結合方式です。以下の例では、

すべての商品の組み合わせのうち、価格の合計が 100未満となる組み合わせのみを検索しています。

prod表は 1つしかありませんが、prod表を別名で p1表と p2表の 2つの表に見立てて、p1と p2

LPI-Japan 43 www.oss-db.jp

Page 54: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 5章 SQLによるデータベースの操作 応用編 5.8 LIMIT句による検索行数制限

を単純結合(すべての組み合わせを取り出す結合)し、価格の合計に対してWHERE句の条件で絞

り込みを行っています。

ossdb=# SELECT p1.prod_name,p2.prod_name,p1.price + p2.price AS pricesumFROM prod p1,prod p2WHERE p1.price + p2.price < 100;prod_name | prod_name | pricesum

-----------+-----------+----------

みかん | バナナ | 81

バナナ | みかん | 81

バナナ | バナナ | 62

(3 行)

5.8 LIMIT句による検索行数制限

LIMIT句を使うと、検索で取り出す行データの数を制限することができます。通常の SQL文の

検索では、条件に当てはまる行データはすべて表示されてしまいますが、LIMIT句を指定すると必

要とする行数だけを取り出せます。問い合わせの結果は順番が保証されていませんから、確実に指

定した行を取り出すには、ORDER BY句を使って行データの並びを指定する必要があります。

以下の例では、orders 表から 3 行だけ行データを取り出しています。順序を確定させるために、

order_id列で並び替えを行っています。

ossdb=# SELECT * FROM orders ORDER BY order_id;order_id | order_date | customer_id | prod_id | qty

----------+----------------------------+-------------+---------+-----

1 | 2011-09-18 19:24:50.102562 | 1 | 1 | 10

2 | 2011-09-18 19:24:50.104937 | 2 | 2 | 5

3 | 2011-09-18 19:24:50.107026 | 3 | 3 | 8

4 | 2011-09-18 19:24:50.109223 | 2 | 1 | 3

5 | 2011-09-18 19:24:50.111255 | 3 | 2 | 4

(5 行)

ossdb=# SELECT * FROM orders ORDER BY order_id LIMIT 3;order_id | order_date | customer_id | prod_id | qty

----------+----------------------------+-------------+---------+-----

1 | 2011-09-18 19:24:50.102562 | 1 | 1 | 10

2 | 2011-09-18 19:24:50.104937 | 2 | 2 | 5

3 | 2011-09-18 19:24:50.107026 | 3 | 3 | 8

(3 行)

5.8.1 OFFSET句

OFFSET句を組み合わせることで、先頭から不要な行数を飛ばしてから行データを取り出すこと

ができます。

LPI-Japan 44 www.oss-db.jp

Page 55: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 5章 SQLによるデータベースの操作 応用編 5.8 LIMIT句による検索行数制限

以下の例では、OFFSET 句の値として 1 を与えているので、1 行飛ばして 2 行目から 3 行の行

データを取り出しています。

ossdb=# SELECT * FROM orders ORDER BY order_id LIMIT 3 OFFSET 1;order_id | order_date | customer_id | prod_id | qty

----------+----------------------------+-------------+---------+-----

2 | 2011-09-18 19:24:50.104937 | 2 | 2 | 5

3 | 2011-09-18 19:24:50.107026 | 3 | 3 | 8

4 | 2011-09-18 19:24:50.109223 | 2 | 1 | 3

(3 行)

LPI-Japan 45 www.oss-db.jp

Page 56: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第6章

データベース定義の応用

データベースのデータの整合性を高め、より効率的に使うためにはデータベースの定義をしっ

かりと行う必要があります。この章では主キー、外部キーなどのデータベースの定義に必要

となる基礎知識や、シーケンスなどの便利な機能について解説します。

6.1 主キー

主キーは、表のデータを一意に識別できる 1つ以上の列のことです。「一意」(UNIQUE)とは、列

の値が重複していないことです。一意である列のことを「一意キー」とも呼びます。主キーは一意

キーである他に、必ず値が入っている必要があります。必ず値が入っていることを「NULLではな

い」(NOT NULL)と呼びます。NULLについての詳細は後述します。

以下の例では、orders 表の order_id 列を条件にすれば特定の一行だけを取り出すことができま

すが、customer_id列を条件にすると複数の行データが取り出されてしまいます。

ossdb=# SELECT * FROM orders WHERE order_id = 1;order_id | order_date | customer_id | prod_id | qty

----------+----------------------------+-------------+---------+-----

1 | 2011-09-18 19:24:50.102562 | 1 | 1 | 10

(1 行)

ossdb=# SELECT * FROM orders WHERE customer_id = 2;order_id | order_date | customer_id | prod_id | qty

----------+----------------------------+-------------+---------+-----

2 | 2011-09-18 19:24:50.104937 | 2 | 2 | 5

4 | 2011-09-18 19:24:50.109223 | 2 | 1 | 3

(2 行)

order_id列は一意の値を持つのであれば主キーとして使用できますが、customer_id列は一意の

値を持つことはできないと考えられますので、主キーにはなりません。

6.1.1 主キーを指定する

主キーを指定するには、CREATE TABLE文で表の作成時に指定するか、すでに作成されている

表に対して ALTER TABLE文で指定します。

主キーを指定する ALTER TABLE文の構文

LPI-Japan 46 www.oss-db.jp

Page 57: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 6章データベース定義の応用 6.1 主キー

ALTER TABLE 表名 ADD PRIMARY KEY(列名 [,...])

以下の例では、prod 表の prod_id 列を主キーに指定しています。主キーを指定すると、検索を

高速化するためのインデックスが自動的に(暗黙的に)作成されます。主キーに指定された列には、

NOT NULL制約が設定され、「列名_pkey」という名前の一意インデックスが作成されます。

ossdb=# ALTER TABLE prod ADD PRIMARY KEY(prod_id);NOTICE: ALTER TABLE / ADD PRIMARY KEYはテーブル"prod"に暗黙的なインデックス"prod_pkey"

を作成しますALTER TABLE

ossdb=# Yd prodテーブル "public.prod"

カラム | 型 | 修飾語-----------+---------+----------

prod_id | integer | not null

prod_name | text |

price | integer |

インデックス:

"prod_pkey" PRIMARY KEY, btree (prod_id)

orders表の order_id列、customer表の customer_id列も主キーとして指定しておきます。

ossdb=# ALTER TABLE orders ADD PRIMARY KEY(order_id);NOTICE: ALTER TABLE / ADD PRIMARY KEY は テ ー ブ ル"orders"に 暗 黙 的 な イ ン デ ッ クス"orders_pkey"を作成しますALTER TABLE

ossdb=# ALTER TABLE customer ADD PRIMARY KEY(customer_id);NOTICE: ALTER TABLE / ADD PRIMARY KEY は テ ー ブ ル"customer"に 暗 黙 的 な イ ン デ ッ クス"customer_pkey"を作成しますALTER TABLE

6.1.2 主キーの動作を確認する

主キーを指定すると、「一意」(UNIQUE)で「NULLではない」(NOT NULL)という制約が設

定されます。そのため、これまで可能であった行データの入力などができなくなります。

以下の例では、prod表の主キーである prod_idの値を指定しない(NULLになる)INSERT文

や、既に存在している値を指定している INSERT文がエラーになっています。

ossdb=# INSERT INTO prod (prod_name,price) VALUES (’すいか’,60);ERROR: 列"prod_id"内の NULL値は NOT NULL制約違反です

LPI-Japan 47 www.oss-db.jp

Page 58: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 6章データベース定義の応用 6.2 外部キー

ossdb=# INSERT INTO prod (prod_id,prod_name,price) VALUES (4,’すいか’,60);ERROR: 重複キーが一意性制約"prod_pkey"に違反していますDETAIL: キー (prod_id)=(4) はすでに存在しますossdb=# INSERT INTO prod (prod_id,prod_name,price) VALUES (5,’すいか’,60);INSERT 0 1

ossdb=# SELECT * FROM prod;prod_id | prod_name | price

---------+-----------+-------

1 | みかん | 50

2 | りんご | 70

3 | メロン | 100

4 | バナナ | 31

5 | すいか | 60

(5 行)

6.1.3 複数列からなる主キー

「主キーは一意に行データを識別する 1つ以上の列」と説明した通り、複数列からなる主キーを設

定することも可能です。これを複合主キー、または複合キーと呼びます。

たとえば「1年 2組出席番号 3番」のように、複数の要素から成り立つような場合が複合主キーの

良い例です。

6.2 外部キー

外部キーは、その列の値が他の表の主キー(または一意キー。以後省略)に存在している列のこと

です。外部キーが他の表の主キーの値を参照することを「外部キー参照」、参照している先の主キー

を「参照キー」と呼びます。

6.2.1 参照整合性制約

外部キー参照を行い、必ず参照キーに値があることを保証することを「外部キー制約」、あるいは

「参照整合性制約」と呼びます。外部キー制約が設定されると、参照キーに存在しない値を外部キー

に挿入したり、参照キーに存在しない値に外部キーの値を更新しようとするとエラーになるので、外

部キーの値が間違えた値になってしまうのを防ぐことができます。また、外部キーから参照されて

いる値を参照キーから削除することもできなくなるので、他の表の外部キーで使用されている値が

参照できなくなることもありません。

6.2.2 外部キーを指定する

外部キーを指定するには、CREATE TABLE文で表の作成時に指定するか、すでに作成されてい

る表に対して ALTER TABLE文で指定します。

外部キーを指定する ALTER TABLE文の構文

LPI-Japan 48 www.oss-db.jp

Page 59: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 6章データベース定義の応用 6.2 外部キー

ALTER TABLE 表名 ADD FOREIGN KEY (列名) REFERENCES 参照表 (参照キー名)

以下の例では、orders表の customer_id列と prod_id列に外部キーを設定しています。

ossdb=# ALTER TABLE orders ADD FOREIGN KEY (customer_id) REFER-ENCES customer(customer_id);ALTER TABLE

ossdb=# ALTER TABLE orders ADD FOREIGN KEY (prod_id) REFERENCES prod(prod_id);ALTER TABLE

ossdb=# Yd ordersテーブル "public.orders"

カラム | 型 | 修飾語-------------+-----------------------------+----------

order_id | integer | not null

order_date | timestamp without time zone |

customer_id | integer |

prod_id | integer |

qty | integer |

インデックス:

"orders_pkey" PRIMARY KEY, btree (order_id)

外部キー制約:

"orders_customer_id_fkey" FOREIGN KEY (customer_id) REFERENCES customer(customer_id)

"orders_prod_id_fkey" FOREIGN KEY (prod_id) REFERENCES prod(prod_id)

ossdb=# Yd customerテーブル "public.customer"

カラム | 型 | 修飾語---------------+---------+----------

customer_id | integer | not null

customer_name | text |

インデックス:

"customer_pkey" PRIMARY KEY, btree (customer_id)

参照元:TABLE "orders" CONSTRAINT "orders_customer_id_fkey" FOREIGN KEY (customer_id) REFERENCES customer(customer_id)

以下の例では、まず customer表に customer_id列の値が 4の行データがないため、外部キー制

約に違反してエラーになっています。次に、prod表に prod_id列の値が 6の行データがないため、

外部キー制約に違反してエラーになっています。

ossdb=# INSERT INTO orders(order_id,order_date,customer_id,prod_id,qty)VALUES (6,now(),4,6,6);ERROR: テーブル"orders"への挿入、更新は外部キー制約"orders_customer_id_fkey"に違反していますDETAIL: テーブル"customer"にキー (customer_id)=(4)がありませんossdb=# INSERT INTO orders(order_id,order_date,customer_id,prod_id,qty)VALUES (6,now(),3,6,6);①ERROR: テーブル"orders"への挿入、更新は外部キー制約"orders_prod_id_fkey"に違反していま

LPI-Japan 49 www.oss-db.jp

Page 60: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 6章データベース定義の応用 6.2 外部キー

すDETAIL: テーブル"prod"にキー (prod_id)=(6)がありません 叢ossdb=# INSERT INTO orders(order_id,order_date,customer_id,prod_id,qty)VALUES (6,now(),3,5,6);INSERT 0 1

ossdb=# SELECT * FROM orders WHERE order_id = 6;order_id | order_date | customer_id | prod_id | qty

----------+----------------------------+-------------+---------+-----

6 | 2011-09-19 15:49:35.328912 | 3 | 5 | 6

(1 行)

ossdb=# SELECT o.order_id,c.customer_name,p.prod_name,o.qtyFROM orders oJOIN customer c ON o.customer_id = c.customer_idJOIN prod p ON o.prod_id = p.prod_idWHERE order_id = 6;order_id | customer_name | prod_name | qty

----------+---------------+-----------+-----

6 | 高橋商店 | すいか | 6

(1 行)

6.2.3 CREATE TABLE文で主キー、外部キーを設定する

主キー、外部キーは CREATE TABLE文でも設定することができます。

以下の例は、prod表、customer表、orders表に主キー、外部キーを設定する CREATE TABLE

文です。外部キーを設定するには参照キーとなる他の表の主キーが必要となるため、先に参照先の

表を作成します。

LPI-Japan 50 www.oss-db.jp

Page 61: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 6章データベース定義の応用 6.2 外部キー

CREATE TABLE prod(prod_id INT PRIMARY KEY,prod_name TEXT,price INT);

CREATE TABLE customer(customer_id INT PRIMARY KEY,customer_name TEXT);

CREATE TABLE orders(order_id INT PRIMARY KEY,order_date TIMESTAMP,customer_id INT REFERENCES customer (customer_id),prod_id integer REFERENCES prod (prod_id),qty INT);

6.2.4 主キー、外部キーは必要か?

主キーや外部キーを設定することで、表に誤って重複した値を入れたり、間違えて行データを削

除してしまったりすることを防ぐことができます。反面、一時的に整合性が取れていない状態を許

容しなくなってしまうので、データをメンテナンスする際などに不便です。不便さを嫌って、デー

タの整合性チェックをデータベースの制約で行うのではなく、アプリケーション側で行うようにす

ることもあるようです。

どちらが良いかは一概には言えませんが、基本的にデータベース側で主キーや外部キーの設定を

行い、システム運用上問題がある場合には制約を取り去ると考えておけばよいでしょう。少なくと

も設計上は、主キー、外部キーの考え方は重要です。また、データベース設計の際に、後述する正規

化をきちんと行う必要があります。

6.2.5 正規化

正規化とは、リレーショナルデータベースにどのようにデータを格納するかを決めるデータベー

ス設計の手法です。リレーショナルデータベースは表の形式で行データを格納するので、実際の行

データを表形式で格納しやすいように複数の表に分解していく作業だと考えれば良いでしょう。

正規化には第 1正規形(1NF)や第 2正規形(2NF)、第 3正規形(3NF)などの形があります。

簡単に言えば、正規化が進む度に表は分割されて増えていきます。分割することでそれぞれの表は

シンプルな構造になっていくので、行データに対する修正や削除、データの追加などを行った時に

問題が発生する可能性が低くなっていきます。

本教科書では正規化について詳細には解説しませんが、データベースの設計を行うためには知っ

ておかなければならない考え方ですので、専門書などで学習してみてください。

LPI-Japan 51 www.oss-db.jp

Page 62: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 6章データベース定義の応用 6.3 NULLについて

6.3 NULLについて

NULL(ヌル)は「未知」または「未定」と定義されるもので、「ゼロ」や「空白」「空文字」とは区

別されます。数値のゼロや文字の空白、空文字はそれぞれデータが「有る」状態ですが、NULLは

データが「無い」という状態を表しています。

6.3.1 NOT NULL制約

列に NULLを許さない場合、表定義で NOT NULL制約を設定します。NOT NULL制約が設定

された列には必ず値が必要となります。主キーは必ず値を必要とするので、主キーを定義すると自

動的に NOT NULL制約が設定されます。

以下の例では、customer表の customer_id列が主キーとして設定されているため、NOT NULL

制約が設定されています。

ossdb=# Yd customerテーブル "public.customer"

カラム | 型 | 修飾語---------------+---------+----------

customer_id | integer | not null

customer_name | text |

インデックス:

"customer_pkey" PRIMARY KEY, btree (customer_id)

参照元:TABLE "orders" CONSTRAINT "orders_customer_id_fkey" FOREIGN KEY (customer_id) REFERENCES customer(customer_id)

6.3.2 NULLの判定

NULLは値を持たないため、通常の演算子を使った条件式では検索することができません。列の

値が NULLかどうかを条件判定するには、IS NULL演算子、IS NOT NULL演算子を使用します。

ossdb=# INSERT INTO prod (prod_id,prod_name) VALUES (6,’ぶどう’);INSERT 0 1

ossdb=# SELECT * FROM prod;prod_id | prod_name | price

---------+-----------+-------

1 | みかん | 50

2 | りんご | 70

3 | メロン | 100

4 | バナナ | 31

5 | すいか | 60

6 | ぶどう |

(6 行)

LPI-Japan 52 www.oss-db.jp

Page 63: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 6章データベース定義の応用 6.3 NULLについて

ossdb=# SELECT * FROM prod WHERE price IS NULL;prod_id | prod_name | price

---------+-----------+-------

6 | ぶどう |

(1 行)

6.3.3 NULLの集約関数での取り扱い

各種集約関数では NULLは無視されることがあります。たとえば、count(*)では NULLも数え

られますが、avg関数を使った平均値算出時の除数には数えられません。もちろん、合計や最大、最

小などの集約関数でも対象となりません。

以下の例では、sum(price) の値は 311、count(*) の値は 6 ですが、1 つだけ NULL があるため

avg(price)は 311÷ 5となり 62.2が結果として返っています。

ossdb=# SELECT sum(price),count(*),avg(price) FROM prod;sum | count | avg

-----+-------+---------------------

311 | 6 | 62.2000000000000000

(1 行)

6.3.4 空文字

NULLと似たものとして「空文字」があります。空文字は、INSERT文で文字列型の列データに

「”」(シングルクォートを 2つ連続)で指定できます。空文字は NULLではないので、NOT NULL

制約に違反しません。

以下の例では、prod表の prod_name列に空文字の行データを入力しています。空文字のため、

IS NULL演算子では検索されません。

ossdb=# INSERT INTO prod (prod_id,prod_name) VALUES (7,’’);INSERT 0 1

ossdb=# SELECT * FROM prod WHERE prod_id = 7;prod_id | prod_name | price

---------+-----------+-------

7 | |

(1 行)

ossdb=# SELECT * FROM prod WHERE prod_name IS NULL;prod_id | prod_name | price

---------+-----------+-------

(0 行)

LPI-Japan 53 www.oss-db.jp

Page 64: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 6章データベース定義の応用 6.4 シーケンス

6.4 シーケンス

シーケンス(順序)は、連番を生成する機能です。たとえばシーケンスを INSERT文の中で使用

すると、自動的に連番が値として挿入されるので、ID番号など重複なく一意にしたい列の値を取る

のに適しています。

6.4.1 シーケンスの作成

シーケンスを作成するには、CREATE SEQUENCE文を使用します。

以下の例は、各種パラメータはデフォルト値のまま order_id_seqシーケンスを作成しています。

デフォルト値は以下の通りです。

表 6.1 シーケンスのデフォルト値

開始値 1増加量 1最大値 2の 63乗-1(9,223,372,036,854,775,807)

ossdb=# CREATE SEQUENCE order_id_seq;CREATE SEQUENCE

6.4.2 シーケンスの操作

シーケンス操作用の関数を使うことで値を取り出したり、値を設定したりすることができます。

現在の値を返す

currval(’sequence’)

シーケンスの現在の値を返します。シーケンスの値は更新されません。

次の値を返し、値を更新する

nextval(’sequence’)

現在値の次の値を返して、シーケンスの値を次の値に更新します。デフォルトではシーケンスの

値は 1 ずつ増えていくので、現在値が 1 だった時には次の値は 2 となります。最大値に達すると、

デフォルトでは nextvalの呼び出しはエラーになります。

シーケンスの値を設定する

setval(’sequence’,value)

シーケンスの値を指定した値に設定します。

LPI-Japan 54 www.oss-db.jp

Page 65: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 6章データベース定義の応用 6.4 シーケンス

以下の例では、order_id_seqシーケンスから値を取り出しています。

ossdb=# SELECT currval(’order_id_seq’);ERROR: 本セッションでシーケンス"order_id_seq"の currvalはまだ定義されていませんossdb=# SELECT nextval(’order_id_seq’);nextval

---------

1

(1 行)

ossdb=# SELECT currval(’order_id_seq’);currval

---------

1

(1 行)

ossdb=# SELECT nextval(’order_id_seq’);nextval

---------

2

(1 行)

setval()関数を使うと、シーケンスの値を再設定できます。設定可能な値は 1からの値です。

ossdb=# SELECT setval(’order_id_seq’,0);ERROR: setval: 値 0はシーケンス"order_id_seq"の範囲 (1..9223372036854775807)外です"

ossdb=# SELECT setval(’order_id_seq’,1);setval

--------

1

(1 行)

ossdb=# SELECT currval(’order_id_seq’);currval

---------

1

(1 行)

ossdb=# SELECT nextval(’order_id_seq’);nextval

---------

2

(1 行)

6.4.3 シーケンスを SQL文で使用

シーケンスは、たとえば INSERT文に組み込んで使用します。

以下の例では、orders表へ行データを入力する INSERT文で、order_id列の値を order_id_seq

LPI-Japan 55 www.oss-db.jp

Page 66: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 6章データベース定義の応用 6.4 シーケンス

シーケンスから取得しています。

ossdb=# SELECT setval(’order_id_seq’,6);setval

--------

6

(1 行)

ossdb=# INSERT INTO orders(order_id,order_date,customer_id,prod_id,qty)VALUES (nextval(’order_id_seq’),now(),2,4,7);INSERT 0 1

ossdb=# SELECT * FROM orders;order_id | order_date | customer_id | prod_id | qty

----------+----------------------------+-------------+---------+-----

1 | 2011-09-18 19:24:50.102562 | 1 | 1 | 10

2 | 2011-09-18 19:24:50.104937 | 2 | 2 | 5

3 | 2011-09-18 19:24:50.107026 | 3 | 3 | 8

4 | 2011-09-18 19:24:50.109223 | 2 | 1 | 3

5 | 2011-09-18 19:24:50.111255 | 3 | 2 | 4

6 | 2011-09-19 15:49:35.328912 | 3 | 5 | 6

7 | 2011-09-19 17:23:06.678461 | 2 | 4 | 7

(7 行)

6.4.4 シーケンスと飛び番

シーケンスを使って簡単に連番を作ることができますが、実行した SQL 文が失敗した場合でも

シーケンスの値は進んでしまいます。この時、連番になっていない、いわゆる「飛び番」が発生しま

す。シーケンスは完全な連番を保証するものではなく、また完全な連番を作るのは困難です。たと

えば途中の行が削除されてしまえば、完全な連番ではなくなってしまいます。連番はあくまでも行

データを区別するための重複していない値と割り切る方がシステム設計上は楽になります。

以下の例では、INSERT文がエラーで失敗しても、シーケンスの値が進んでしまって次の INSERT

文で飛び番が発生しています。

ossdb=# SELECT currval(’order_id_seq’);currval

---------

7

(1 行)

ossdb=# INSERT INTO orders(order_id,order_date,customer_id,prod_id,qty)VALUES (nextval(’order_id_seq’),now(),5,4,7);ERROR: テーブル"orders"への挿入、更新は外部キー制約"orders_customer_id_fkey"に違反していますDETAIL: テーブル"customer"にキー (customer_id)=(5)がありませんossdb=# SELECT currval(’order_id_seq’);currval

---------

LPI-Japan 56 www.oss-db.jp

Page 67: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 6章データベース定義の応用 6.4 シーケンス

8

(1 行)

ossdb=# INSERT INTO orders(order_id,order_date,customer_id,prod_id,qty)VALUES (nextval(’order_id_seq’),now(),2,4,7);INSERT 0 1

ossdb=# SELECT * FROM orders WHERE order_id > 6;order_id | order_date | customer_id | prod_id | qty

----------+----------------------------+-------------+---------+-----

7 | 2011-09-19 17:23:06.678461 | 2 | 4 | 7

9 | 2011-09-19 17:24:02.741924 | 2 | 4 | 7

(2 行)

LPI-Japan 57 www.oss-db.jp

Page 68: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第7章

マルチユーザでの利用

PostgreSQL はマルチユーザのデータベースです。複数のユーザを使い分けることで、ある

ユーザは表のデータを更新でき、あるユーザは検索のみ行えるようにするなど、ユーザ毎に行

えるデータベースの操作を変えたりすることができます。この章では、ユーザの作成やネッ

トワーク経由での接続、トランザクションなど複数ユーザでの利用について学びます。

7.1 ユーザの作成

PostgreSQL のユーザを作成するには、CREATE USER 文を使用します。また、Linux のコマ

ンドラインから createuserコマンドを使用してもユーザの作成を行えます。

ユーザを確認するには Yduメタコマンドを実行します。

以下の例では、ユーザ satoを作成しています。

ossdb=# CREATE USER sato;CREATE ROLE

ossdb=# Yduロール一覧

ロール名 | 属性 | メンバー----------+----------------------------------------------------+----------

postgres | スーパーユーザ, ロールを作成できる, DBを作成できる | {}

sato | | {}

以下の例では、Linuxのコマンドラインから、createuserコマンドを使用してユーザ suzukiを作

成しています。実行時の Linuxユーザは postgresである必要があります。

-bash-3.2$ createuser suzuki新しいロールをスーパーユーザにしますか? (y/n)n

新しいロールに対してデータベースを作成する権限を与えますか? (y/n)n

新しいロールに対して別のロールを作成する権限を与えますか? (y/n)n

-bash-3.2$ psql ossdbpsql (9.0.5)

"help" でヘルプを表示します.

ossdb=# Ydu

LPI-Japan 58 www.oss-db.jp

Page 69: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.2 接続と認証

ロール一覧ロール名 | 属性 | メンバー

----------+----------------------------------------------------+----------

postgres | スーパーユーザ, ロールを作成できる, DBを作成できる | {}

sato | | {}

suzuki | | {}

7.1.1 ユーザとロール

CREATE USER 文や createuser コマンドの結果表示にはユーザではなくロール (ROLE) と表

示されています。これは PostgreSQLが以前のバージョンで、ユーザという概念をロールという概

念に置き換えたためです。ロールは、ユーザとグループの両方の概念を持ち合わせていますが、複

雑な使い方をしない限りユーザとロールは同じものと考えてよいでしょう。本教科書では、ユーザ

という概念の方が分かりやすいことから、ユーザの作成として解説しています。

7.1.2 スーパーユーザ

データベースには一番最初に初期化した際に、データベースに対するすべての権限を持ったユー

ザが作成されます。これをスーパーユーザと呼びます。Linux における root ユーザや、Windows

における Administrator ユーザのようなものと考えればよいでしょう。PostgreSQL では、Linux

上でデータベースの初期化(initdbコマンドの実行)を行った OSユーザの名前でスーパーユーザ

が作成されます。このユーザのユーザ名は習慣的に postgresとなっています。

7.2 接続と認証

マルチユーザで利用する際には、外部からネットワーク経由での PostgreSQLへの接続や、接続

時の認証が必要となります。これらはデフォルトでは設定されていないので、設定方法について解

説します。

7.2.1 接続認証の設定を確認

PostgreSQLでの接続認証の設定は、設定ファイルの一つである pg_hba.confに記述します。デ

フォルトでは、以下のように設定が記述されています。

-bash-3.2$ cat /var/lib/pgsql/9.0/data/pg_hba.conf(略)# TYPE DATABASE USER CIDR-ADDRESS METHOD

# "local" is for Unix domain socket connections only

local all all ident

# IPv4 local connections:

host all all 127.0.0.1/32 ident

LPI-Japan 59 www.oss-db.jp

Page 70: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.2 接続と認証

# IPv6 local connections:

host all all ::1/128 ident

各項目の設定は、左から順に以下のようになっています。

接続方法(TYPE)

クライアントがどのように PostgreSQLに接続するかを指定します。

表 7.1 接続方法の設定

local PostgreSQLが実行されているホストと同じホストからの接続host 外部からの TCP/IPを使った接続hostssl 外部からの SSLを使った接続

データベース(DATABASE)

接続認証の対象となるデータベースを指定します。allと記述するとすべてのデータベースが対象

となります。

ユーザ(USER)

接続認証の対象となるユーザを指定します。allと記述するとすべてのユーザが対象となります。

認証方法

認証方式を指定します。

表 7.2 認証方法の設定

trust 認証なしに接続

reject 接続拒否

md5 MD5パスワード認証password 平文パスワード認証

gss GSSAPI認証sspi SSPI(Windowsのみ)krb5 Kerberos V5認証ident IDENT認証ldap LDAP認証radius RADIUS認証cert SSLクライアント証明書認証pam PAM認証

デフォルトの設定では、すべての接続方法ですべてのデータベース、ユーザに対して IDENT認

証を行うことが設定されています。

LPI-Japan 60 www.oss-db.jp

Page 71: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.2 接続と認証

7.2.2 接続ユーザの指定

psql でデータベースに接続する際、本来はどのユーザで接続するか指定する必要がありますが、

明示的に指定されなかった場合には psqlを実行した Linuxのユーザ名が暗黙の内に指定されます。

接続ユーザは Ysetメタコマンドを実行して変数 USERの値で確認できます。

以下の例では、id コマンドの結果で Linux のユーザ名が postgres であること、接続のユーザも

postgresになっていることを確認しています。psqlにはデータベース名として ossdbのみ指定して

いるので、接続ユーザは暗黙の内に postgresが指定されているのが分かります。

-bash-3.2$ iduid=26(postgres) gid=26(postgres) 所属グループ=26(postgres)

-bash-3.2$ psql ossdbpsql (9.0.5)

"help" でヘルプを表示します.

ossdb=# YsetAUTOCOMMIT = ’on’

PROMPT1 = ’%/%R%# ’

PROMPT2 = ’%/%R%# ’

PROMPT3 = ’>> ’

VERBOSITY = ’default’

VERSION = ’PostgreSQL 9.0.5 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-50), 32-bit’

DBNAME = ’ossdb’

USER = ’postgres’

PORT = ’5432’

ENCODING = ’UTF8’

しかし、作成したユーザでデータベースに接続しようとしても、以下のように失敗します。

-bash-3.2$ iduid=26(postgres) gid=26(postgres) 所属グループ=26(postgres)

-bash-3.2$ psql ossdb satopsql: FATAL: ユーザ"sato"の Ident認証に失敗しました

IDENT 認証は、Linux 側の OS ユーザと PostgreSQL の接続ユーザが一致しているかを確認し

ます。OS側でログイン時にユーザ認証が行われているので、PostgreSQL側ではユーザ名の一致だ

けをチェックしています。前の例では Linux側の OSユーザが postgresのため、PostgreSQLの接

続ユーザが satoだと IDENT認証に失敗します。

以下のように Linux で OS ユーザ sato を作成して psql を実行すれば、IDENT 認証に成功し

ます。

LPI-Japan 61 www.oss-db.jp

Page 72: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.2 接続と認証

[root@localhost ~]# useradd sato[root@localhost ~]# su - sato[sato@localhost ~]$ psql ossdb satopsql (9.0.5)

"help" でヘルプを表示します.

ossdb=>

ユーザ satoは作成時にスーパーユーザに指定しなかったので、psqlのプロンプトが「=#」では

なく、「=>」になっています。

7.2.3 パスワード認証の設定

OS ユーザとは異なる PostgreSQL ユーザでの接続や、外部からの接続をサポートするためには

パスワード認証を設定します。パスワード認証を設定するには pg_hba.confに以下のような設定を

行います。設定の変更は OSユーザを postgresにして行います。

-bash-3.2$ vi pg_hba.conf(略)# TYPE DATABASE USER CIDR-ADDRESS METHOD

# "local" is for Unix domain socket connections only

local all all md5

#local all all ident

設定の変更は PostgreSQLを再起動(または設定の再読み込み)をするまでは有効になりません。

ユーザにパスワードの設定を行ってから再起動を行います。パスワードの設定を行わないまま再起

動を行うと、IDENT認証が無効になってしまうのでデータベースに接続できなくなります。

7.2.4 ユーザ・パスワードの設定

パスワード認証が有効になると、パスワードが設定されていないユーザはデータベースに接続

できなくなるので、パスワードを設定しておきます。パスワードは既存のユーザに対して ALTER

USER文で設定する方法と、新規ユーザ作成の際に CREATE USER文で設定する方法があります。

既存ユーザにパスワード設定

既存のユーザに対して ALTER USER文でパスワードを設定します。

ALTER USER文でパスワードを設定する構文

ALTER USER ユーザ名 WITH PASSWORD ’パスワード’

LPI-Japan 62 www.oss-db.jp

Page 73: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.2 接続と認証

以下の例では、ユーザ postgresに対してパスワードを passwordに設定しています。

-bash-3.2$ psql ossdbpsql (9.0.5)

"help" でヘルプを表示します.

ossdb=# ALTER USER postgres WITH PASSWORD ’password’;ALTER ROLE

新規ユーザの作成時にパスワードを設定

新規ユーザ作成の際に CREATE USER文でパスワードを設定します。

CREATE USER文でパスワードを設定する構文

CREATE USER ユーザ名 WITH PASSWORD ’パスワード’

以下の例では、DROP USER 文でユーザ sato と suzuki を削除した後、CREATE USER 文で

ユーザ satoを作成し、パスワードを passwordに設定しています。

ossdb=# DROP USER sato;DROP ROLE

ossdb=# DROP USER suzuki;DROP ROLE

ossdb=# CREATE USER sato WITH PASSWORD ’password’;CREATE ROLE

createuserコマンドの場合には–pwpromptオプションをつけて実行します。

以下の例では、createuserコマンドでユーザ suzukiを作成し、パスワードを passwordに設定し

ています。

ossdb=# Yq-bash-3.2$ createuser --pwprompt suzuki新しいロールのためのパスワード: password←実際には表示されませんもう一度入力してください: password←実際には表示されません新しいロールをスーパーユーザにしますか? (y/n)n

新しいロールに対してデータベースを作成する権限を与えますか? (y/n)n

新しいロールに対して別のロールを作成する権限を与えますか? (y/n)n

LPI-Japan 63 www.oss-db.jp

Page 74: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.2 接続と認証

7.2.5 PostgreSQLの再起動

設定変更後に設定を反映させるため PostgreSQL を再起動します。ユーザ root で service

postgresql-9.0 restartを実行するか、ユーザ postgresで pg_ctl restartコマンドを実行します。

以下の例は、ユーザ rootで serviceコマンドで PostgreSQLを再起動しています。

[root@localhost ~]# service postgresql-9.0 restartpostgresql-9.0 サービスを停止中: [ OK ]

postgresql-9.0 サービスを開始中: [ OK ]

以下の例は、ユーザ postgresで pg_ctlコマンドで PostgreSQLを再起動しています。

-bash-3.2$ /usr/pgsql-9.0/bin/pg_ctl restartサーバ停止処理の完了を待っています....完了サーバは停止しましたサーバは起動中です。

PostgreSQL の再起動は、他にユーザがデータベースを使用していると行えません。設定の変更

のみの場合には設定の再読み込み(reload)でもかまいません。

以下の例は、ユーザ rootで serviceコマンドで PostgreSQLの設定を再読み込み、ユーザ postgres

で pg_ctlコマンドで PostgreSQLの設定を再読み込みしています。

[root@localhost ~]# service postgresql-9.0 reload[root@localhost ~]# su - postgres-bash-3.2$ /usr/pgsql-9.0/bin/pg_ctl reloadサーバにシグナルを送信しました

7.2.6 パスワード認証による接続

パスワード認証が有効になったかどうかを確認します。

以下の例では、ユーザ postgres、ユーザ satoでの接続を確認しています。

-bash-3.2$ iduid=26(postgres) gid=26(postgres) 所属グループ=26(postgres)

-bash-3.2$ psql ossdbパスワード:password ←実際には表示されませんpsql (9.0.5)

LPI-Japan 64 www.oss-db.jp

Page 75: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.3 ネットワーク経由接続

"help" でヘルプを表示します.

ossdb=# Yq-bash-3.2$ psql ossdb satoユーザ sato のパスワード: password←実際には表示されませんpsql (9.0.5)

"help" でヘルプを表示します.

ossdb=>

ユーザ postgres は暗黙の指定で接続しています。ユーザ sato は明示的に指定して接続していま

すが、IDENT認証ではなくパスワード認証のため、OSユーザが異なっていても接続できています。

7.3 ネットワーク経由接続

PostgreSQLは、TCP/IPを利用したネットワーク経由での接続も受け付けることができます。

7.3.1 ネットワーク経由接続の設定

ネットワーク経由接続を受け付けるには、postgresql.confに listen_addressesの設定を行って、

PostgreSQLを再起動します。

以下の例では、すべてのインターフェースからの接続を受け付けるように設定しています。

-bash-3.2$ vi /var/lib/pgsql/9.0/data/postgresql.conf

#listen_addresses = ’localhost’ # what IP address(es) to listen on;

listen_addresses = ’*’ # what IP address(es) to listen on;

# comma-separated list of addresses;

# defaults to ’localhost’, ’*’ = all

# (change requires restart)

#port = 5432 # (change requires restart)

デフォルトでは、listen_addresses = ’localhost’が設定されていて、PostgreSQLが実行されて

いるホストでのローカルループバック接続のみが有効になっています。値を「*」(アスタリスク)に

設定することで、ホストが用意しているすべてのインターフェースからの接続を受け付けるように

なります。もし特定のインターフェースからのみ受け付けたい場合には、そのインターフェースに

設定された IPアドレスを記述します。

接続受付のポート番号はデフォルトで 5432に設定されています。ポート番号を変更したい場合に

は、portの設定値を変更します。

あわせて、接続認証の設定も行います。pg_hba.confの hostアクセス制御を設定します。

以下の例では、ネットワーク経由接続をパスワード認証するように設定しています。設定後、

PostgreSQLを再起動します。

LPI-Japan 65 www.oss-db.jp

Page 76: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.4 アクセス権限

-bash-3.2$ vi /var/lib/pgsql/9.0/data/pg_hba.conf

# IPv4 local connections:

host all all 127.0.0.1/32 md5

#host all all 127.0.0.1/32 ident

-bash-3.2$ /usr/pgsql-9.0/bin/pg_ctl restartサーバ停止処理の完了を待っています....完了サーバは停止しましたサーバは起動中です。

7.3.2 psqlを使ったネットワーク経由接続

psql を使って PostgreSQL にネットワーク経由接続するには–host オプションをつけて実行し

ます。

psqlでネットワーク経由接続

psql --host ホスト名 DB名 ユーザ名

以下の例では、localhost(IPアドレス 127.0.0.1)に対してネットワーク経由接続を行っています。

-bash-3.2$ psql --host localhost ossdb postgresユーザ postgres のパスワード: password←実際には表示されませんpsql (9.0.5)

"help" でヘルプを表示します.

ossdb=#

7.4 アクセス権限

1つのデータベースに複数のユーザが接続出来る場合、アクセス権限を設定することで表などに対

する操作を制御することができます。

7.4.1 アクセス権限の付与

アクセス権限を付与するには、GRANT文を使用します。

GRANT文の構文

GRANT {ALL | SELECT | INSERT | DELETE | UPDATE}

LPI-Japan 66 www.oss-db.jp

Page 77: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.4 アクセス権限

ON object TO {user | PUBLIC}

以下の例は、ユーザ satoに対して prod表に対するすべての権限を付与しています。

ossdb=# GRANT all ON prod TO sato;GRANT

7.4.2 アクセス権限の確認

アクセス権限を確認するには、Ydpメタコマンドを使用します。

ossdb=# Ydp prodアクセス権

スキーマ | 名前 | 型 | アクセス権 | アクセス権限を剥奪する----------+------+----------+---------------------------+------------------------

public | prod | テーブル | postgres=arwdDxt/postgres+|

| | | sato=arwdDxt/postgres |

(1 行)

a INSERT(Appendの意)

r SELECT(Readの意)

w UPDATE(Writeの意)

d DELETE

D TRUNCATE

x REFERENCES

t TRIGGER

REFERENCES権限は、外部キー制約を作成する両方の表に権限を持っている必要があります。

TRIGGER 権限は、表に対する操作をトリガー(引き金)にして別の処理を行う「トリガー機能」

を表に対して作成できる権限です。

アクセス権限の後ろにある「/posgres」は、この権限を与えたユーザを表しています。

7.4.3 アクセス権限の取り消し

与えたアクセス権限を取り消すには、REVOKE文を使用します。

REVOKE文の構文

LPI-Japan 67 www.oss-db.jp

Page 78: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.5 トランザクション

REVOKE {ALL | SELECT | INSERT | DELETE | UPDATE}

ON object FROM {user|PUBLIC}

以下の例では、ユーザ satoから prod表に対するすべての権限を取り消しています。

ossdb=# REVOKE all ON prod FROM sato;REVOKE

ossdb=# Ydp prodアクセス権

スキーマ | 名前 | 型 | アクセス権 | アクセス権限を剥奪する----------+------+----------+---------------------------+------------------------

public | prod | テーブル | postgres=arwdDxt/postgres |

(1 行)

7.5 トランザクション

トランザクションとは、データベースに対する 1 つ以上の処理のまとまりのことです。データ

ベースに対する処理が開始されると同時にトランザクションが開始 (BEGIN)され、まとまった処

理の結果を確定するコミット (COMMIT)、あるいは処理を破棄するロールバック (ROLLBACK)

が行われるまでが 1つのトランザクションです。

これまで PostgreSQLの操作に使用してきた SQL文は、自動コミット(AUTOCOMMIT)がデ

フォルト有効になっていたため、すべての操作が成功すると自動的に COMMITが発行されていま

した。自動コミットを無効にするには、psqlメタコマンドの Yset AUTOCOMMIT=offを実行す

るか、BEGINを実行して明示的にトランザクションを開始する必要があります。

ossdb=# BEGIN;BEGIN

ossdb=# INSERT INTO customer VALUES (5,’田中産業’);INSERT 0 1

ossdb=# SELECT * FROM customer;customer_id | customer_name

-------------+---------------

1 | 佐藤商事2 | 鈴木物産3 | 高橋商店4 | 藤原流通5 | 田中産業

(5 行)

ossdb=# ROLLBACK;ROLLBACK

ossdb=# SELECT * FROM customer;customer_id | customer_name

LPI-Japan 68 www.oss-db.jp

Page 79: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.5 トランザクション

-------------+---------------

1 | 佐藤商事2 | 鈴木物産3 | 高橋商店4 | 藤原流通

(4 行)

7.5.1 読み取り一貫性

読み取り一貫性とは、あるトランザクション内で行われているデータ更新はコミットして確定さ

れない限り、他の検索トランザクションに対して影響を及ぼさないことです。

以下の例では、まず 1つのデータベース接続でトランザクションを開始します。

ossdb=# BEGIN; ①BEGIN

ossdb=# INSERT INTO customer VALUES (5,’田中産業’); ②INSERT 0 1

ossdb=# SELECT * FROM customer;customer_id | customer_name

-------------+---------------

1 | 佐藤商事2 | 鈴木物産3 | 高橋商店4 | 藤原流通5 | 田中産業

(5 行)

ossdb=#

別のターミナルを立ち上げて、別の psqlを実行します。

-bash-3.2$ psql ossdbパスワード: password←実際には表示されませんpsql (9.0.5)

"help" でヘルプを表示します.

ossdb=# SELECT * FROM customer; ③customer_id | customer_name

-------------+---------------

1 | 佐藤商事2 | 鈴木物産3 | 高橋商店4 | 藤原流通

(4 行)

LPI-Japan 69 www.oss-db.jp

Page 80: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.5 トランザクション

このように、最初のトランザクションが行データを追加していても、そのトランザクションがコ

ミットされる前では、別のトランザクションからはその行データ追加は見えません。もし見えてし

まうと、その後ロールバックされて追加が取り消された時、結局存在しないことになった行データ

を読んでしまうことになるからです。このようにコミットされる前の行データを読んでしまうこと

を「ダーティーリード」と呼びます。PostgreSQLはダーティーリードが発生しないよう、読み取り

一貫性を維持しています。

7.5.2 ロック機構と更新の競合

データベースは、先に行われたトランザクションの対象をロックし、他のトランザクションが書

き換えないように保護します。ロックされているデータ行を他のトランザクションが更新しようと

すると更新の競合が発生し、コミットまたはロールバックでロックが解除されるまで処理が待たさ

れます。

以下の例では、まず一つのトランザクションが prod表の行データを更新します。

ossdb=# BEGIN; ①BEGIN

ossdb=# UPDATE prod SET price = price * 1.1 WHERE prod_id = 1; ②UPDATE 1

ossdb=# SELECT * FROM prod WHERE prod_id = 1;prod_id | prod_name | price

---------+-----------+-------

1 | みかん | 55

(1 行)

別のターミナルを立ち上げて、別の psql を実行します。前のトランザクションが更新している

prod表の同じ行データを更新します。

LPI-Japan 70 www.oss-db.jp

Page 81: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.5 トランザクション

-bash-3.2$ psql ossdbパスワード: password←実際には表示されませんpsql (9.0.5)

"help" でヘルプを表示します.

ossdb=# BEGIN; ③BEGIN

ossdb=# UPDATE prod SET price = price * 1.2 WHERE prod_id = 1; ④

2つめの UPDATE文が実行されたところで更新の競合が発生し、前のトランザクションが完了

するまで待たされます。

以下のように、前のトランザクションをコミットかロールバックするとロックが解除され、後か

ら実行された UPDATE文の更新が完了します。

ossdb=# BEGIN;BEGIN

ossdb=# UPDATE prod SET price = price * 1.1 WHERE prod_id = 1;UPDATE 1

ossdb=# SELECT * FROM prod WHERE prod_id = 1;prod_id | prod_name | price

---------+-----------+-------

1 | みかん | 55

(1 行)

※この時点で更新の競合が発生ossdb=# ROLLBACK;ROLLBACK

前のトランザクションがロールバックされると、後から実行された UPDATE文の更新が完了す

LPI-Japan 71 www.oss-db.jp

Page 82: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.5 トランザクション

ることを確認します。

ossdb=# BEGIN;BEGIN

ossdb=# UPDATE prod SET price = price * 1.2 WHERE prod_id = 1;※この時点で更新の競合が発生※前のトランザクションがロールバックされて UPDATE文の更新が完了UPDATE 1

ossdb=# SELECT * FROM prod WHERE prod_id = 1;prod_id | prod_name | price

---------+-----------+-------

1 | みかん | 60

(1 行)

後から実行された UPDATE文の実行時の price列の値は 50だったため、1.2倍の 60に更新され

ています。

7.5.3 デッドロック

もし、2つのトランザクションがお互いに相手のロックしているデータ行を更新しようとして、更

新の競合が同時に発生したらどうなるでしょうか。トランザクションが互いに相手のロック解除待

ちで止まってしまう状態になることを「デッドロック」と呼びます。

PostgreSQLではデッドロックが発生すると、後から更新の競合を発生させた側のトランザクショ

ン全体を失敗させて強制的にロールバックさせます。後のトランザクションが行っていたロックは

解除されるので、先のトランザクションは正常に終了することができます。

まず、一方のトランザクションが price表の prod_id列の値が 1の行データを更新します。

ossdb=# BEGIN; ①BEGIN

ossdb=# UPDATE prod set price = price * 1.1 WHERE prod_id = 1; ②UPDATE 1

次に、もう一方のトランザクションが price表の prod_id列の値が 2の行データを更新します。

ossdb=# BEGIN; ③BEGIN

ossdb=# UPDATE prod set price = price * 1.1 WHERE prod_id = 2; ④UPDATE 1

さらに、前のトランザクションが price表の prod_id列の値が 2の行データを更新します。この

更新はもう一方のトランザクションが更新してロックしている行データなので、更新の競合が発生

します。

LPI-Japan 72 www.oss-db.jp

Page 83: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 7章マルチユーザでの利用 7.5 トランザクション

ossdb=# UPDATE prod SET price = price * 1.2 WHERE prod_id = 2; ⑤※更新の競合が発生

もう一方のトランザクションが、前のトランザクションが更新している price表の prod_id列の

値が 1の行データを更新しようとすると、デッドロックが発生し、トランザクションはロールバッ

クされます。結果前のトランザクションのロック待ちが解除され、更新が実行されます。

ossdb=# UPDATE prod SET price = price * 1.2 WHERE prod_id = 1; ⑥ERROR: デッドロックを検出しましたDETAIL: プロセス 11862は ShareLockをトランザクション 844で待機しています。これはプロセス 11547でブロックされています。プロセス 11547は ShareLockをトランザクション 845で待機しています。これはプロセス 11862

でブロックされています。HINT: クエリーの詳細はサーバログを参照してくださいossdb=#

デッドロックが発生しないようにするには、更新の対象となる行データの決め方を一定の順番に

することです。例のように対象となる行データの決め方を交差させてしまうとデッドロックが発生

しやすくなります。すべてのトランザクションで更新対象行を同じ順番で決定すれば、後からのト

ランザクションは競合が発生した時点で一時停止するので、デッドロックが発生しません。そして

トランザクションがデータ行をロックしている時間を短くするために、できるだけ早くトランザク

ションを終了することです。トランザクションの時間を短くすればするほど、デッドロックが発生

しにくくなります。

LPI-Japan 73 www.oss-db.jp

Page 84: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第8章

パフォーマンスチューニング

データベースの性能を高めるためには、様々な性能向上のための仕組みやパフォーマンス

チューニングの方法について理解しておく必要があります。この章では、データベースのパ

フォーマンスチューニングの手法について学びます。

8.1 インデックス

インデックスは、検索の際に目的となる行データを素早く見つけるための仕組みです。その名の

通り、本の索引のようにデータがどこにあるかを直接指し示してくれます。インデックスが無いと、

検索する度に表全体を検索する必要があります。行データが多いと検索対象のデータが増えるため、

性能が大幅に劣化して遅くなります。このように表全体を検索することを「シーケンシャルスキャ

ン」や「フルスキャン」、インデックスから検索することを「インデックススキャン」と呼びます。

8.1.1 主キーのインデックス

インデックスが最も有効に働くのは、主キーに対して作成したインデックスです。主キーは検索

の条件検索や表の結合などで検索されることが多いので、インデックスを作成しておくとインデッ

クススキャンで高速に必要な行データを見つけ出すことができます。

以下の例のように、主キーを定義すると自動的にインデックスが作成されます。

ossdb=# Yd prodテーブル "public.prod"

カラム | 型 | 修飾語-----------+---------+----------

prod_id | integer | not null

prod_name | text |

price | integer |

インデックス:

"prod_pkey" PRIMARY KEY, btree (prod_id)

参照元:TABLE "orders" CONSTRAINT "orders_prod_id_fkey" FOREIGN KEY (prod_id) REFERENCES prod(prod_id)

LPI-Japan 74 www.oss-db.jp

Page 85: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 8章パフォーマンスチューニング 8.1 インデックス

8.1.2 インデックスの作成

インデックスを作成するには、CREATE INDEX文を使用します。インデックスを作成したい表

の列を指定します。列は 1列でも良いですし、複数列を指定することもできます。複数列を指定し

たインデックスを「複合インデックス」と呼びます。複合インデックスは指定された列がすべて同

時に検索の対象にならないと有効にならないので、検索時の SQL文がどのような検索条件となるか

を考慮して作成する必要があります。

以下の例では、orders表の customer_id列にインデックスを作成しています。

ossdb=# CREATE INDEX orders_customer_id_idxON orders(customer_id);CREATE INDEX

ossdb=# Yd ordersテーブル "public.orders"

カラム | 型 | 修飾語-------------+-----------------------------+----------

order_id | integer | not null

order_date | timestamp without time zone |

customer_id | integer |

prod_id | integer |

qty | integer |

インデックス:

"orders_pkey" PRIMARY KEY, btree (order_id)

"orders_customer_id_idx" btree (customer_id)

外部キー制約:

"orders_customer_id_fkey" FOREIGN KEY (customer_id) REFERENCES customer(customer_id)

"orders_prod_id_fkey" FOREIGN KEY (prod_id) REFERENCES prod(prod_id)

8.1.3 インデックスを削除する

インデックスを削除するには DROP INDEX文を使用します。

以下の例では、orders_customer_id_idxインデックスを削除しています。

ossdb=# DROP INDEX orders_customer_id_idx;DROP INDEX

ossdb=# Yd ordersテーブル "public.orders"

カラム | 型 | 修飾語-------------+-----------------------------+----------

order_id | integer | not null

order_date | timestamp without time zone |

customer_id | integer |

prod_id | integer |

qty | integer |

インデックス:

LPI-Japan 75 www.oss-db.jp

Page 86: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 8章パフォーマンスチューニング 8.2 SQL実行プランの分析

"orders_pkey" PRIMARY KEY, btree (order_id)

外部キー制約:

"orders_customer_id_fkey" FOREIGN KEY (customer_id) REFERENCES customer(customer_id)

"orders_prod_id_fkey" FOREIGN KEY (prod_id) REFERENCES prod(prod_id)

8.1.4 インデックスは万能ではない

インデックスは検索を高速化する手段ですが、万能ではありません。まず、インデックスの対象と

なる列の値が頻繁に書き換わる場合、インデックスも頻繁に更新する必要があります。行データが

増えればそれだけインデックス更新の負荷も高くなるため、あまり書き換わることのない列の方が

インデックスに向いているということになります。また、列の値が適度にばらついていないと、イ

ンデックススキャンよりもシーケンシャルスキャンの方が効率が良い場合があります。インデック

スが有効に働いているかどうかは、次に説明する分析などを行って確認する必要があるでしょう。

8.2 SQL実行プランの分析

SQLが実際にどのようにデータベース内部で実行されているかを確認するには、SQL実行プラン

を分析します。分析を行うには、分析したい SQL文の前に EXPLAIN文をつけて実行します。

8.2.1 インデックスが存在しない場合の SQL実行プラン

インデックスが存在しない表に対する検索は、フルスキャンになることが分かります。

以下の例では、郵便番号データベースの検索を行う SELECT文を分析しています。

ossdb=# EXPLAIN SELECT * FROM zip WHERE newzip = ’1500002’;QUERY PLAN

----------------------------------------------------------

Seq Scan on zip (cost=0.00..3525.38 rows=336 width=296)

Filter: (newzip = ’1500002’::bpchar)

(2 行)

インデックスは存在しないのでシーケンシャルスキャン(Seq Scan)になっています。また、イ

ンデックスが存在しないため、検索対象となる行データの推定行数が 336行となっています。

8.2.2 インデックスが存在する場合の SQL実行プラン

インデックスが存在していて、インデックスを利用した方が良いと判断される場合には、インデッ

クススキャンが行われることが分かります。

LPI-Japan 76 www.oss-db.jp

Page 87: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 8章パフォーマンスチューニング 8.2 SQL実行プランの分析

ossdb=# CREATE INDEX zip_newzip_idx ON zip(newzip);CREATE INDEX

ossdb=# EXPLAIN SELECT * FROM zip WHERE newzip = ’1500002’;QUERY PLAN

----------------------------------------------------------------------------

Index Scan using zip_newzip_idx on zip (cost=0.00..8.28 rows=1 width=145)

Index Cond: (newzip = ’1500002’::bpchar)

(2 行)

インデックスが存在しているので、検索対象となる行データの推定行数が正しく 1行となってい

ます。

8.2.3 インデックスが存在しても必ず使われるわけではない

インデックスが存在していても、検索条件によってはインデックスを使う必要は無いと判断され

ます。

以下の例では、zip 表の largearea 列にインデックスを作成していますが、largearea 列は 0 か 1

といずれかの値しか持たない列のため、必ずインデックスが使われるとは限らなくなっています。

ossdb=# CREATE INDEX zip_largearea ON zip(largearea);CREATE INDEX

ossdb=# EXPLAIN SELECT * FROM zip WHERE largearea = 0;QUERY PLAN

-------------------------------------------------------------

Seq Scan on zip (cost=0.00..4223.57 rows=120263 width=145)

Filter: (largearea = 0)

(2 行)

ossdb=# SELECT COUNT(*) FROM zip WHERE largearea = 0;count

--------

120192

(1 行)

largearea列の値はほとんどが 0のため、インデックスを利用しても性能が出ないと判断してフル

スキャンを選択しています。

ossdb=# EXPLAIN SELECT * FROM zip WHERE largearea = 1;QUERY PLAN

--------------------------------------------------------------------------------

Index Scan using zip_largearea on zip (cost=0.00..694.80 rows=2743 width=145)

Index Cond: (largearea = 1)

(2 行)

ossdb=# SELECT COUNT(*) FROM zip WHERE largearea = 1;

LPI-Japan 77 www.oss-db.jp

Page 88: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 8章パフォーマンスチューニング 8.3 バキューム処理

count

-------

2814

(1 行)

largearea列の値が 1の行データは比較的少ないため、インデックススキャンが選択されています。

8.3 バキューム処理

PostgreSQL を継続して利用していくには、バキューム処理が必要になってきます。バキューム

処理は、必要の無くなった行データが格納されている領域を回収して、再度利用可能な状態にする

処理です。バキューム処理は、PostgreSQLのデータ管理方式に密接に関わっています。

8.3.1 PostgreSQLのデータ管理方式

PostgreSQL では、行データが更新されたり削除されたりした時に、実際の行データは消しませ

ん。それまでの行データに削除されて使用されなくなった印をつけて検索の対象から外すようにし

ます。バキューム処理は、これらの不要な行データを回収する処理を行います。この方式の利点は、

更新や削除の段階で物理的に行データを削除せず印を付けておくだけなので、性能面では有利とな

ります。反面、更新処理が多くなると、不要になった行データの量が増えすぎて物理的なデータ量

が大きくなってしまうので、ディスク容量を圧迫したり、シーケンシャルスキャンの性能が劣化し

てしまいます。

8.3.2 VACUUMと VACUUM FULL

バキューム処理を行うには、VACUUM 文と VACUUM FULL 文を使用します。VACUUM

文は、不要な行データを回収して再利用可能な状態にします。ファイルサイズは変わりません。

VACUUM FULL文はさらに行データの物理的な配置を移動させてファイルサイズを縮小すること

ができます。VACUUM FULL 文は行データの移動を伴うため、実行するとロックが取得されて、

他のユーザが処理を行えなくなります。VACUUM FULL文は副作用が大きいので、大量にデータ

を削除した後、ファイルサイズを縮小してディスクの空き容量を増やしたい場合などに使用すると

良いでしょう。

8.3.3 VACUUM ANALYZE

VACUUM文は、データの分布を調査して SQL実行プランの決定に役立てる統計情報を再作成す

る ANALYZE文と同時実行できます。

以下の例は、データベースに対して VACUUM ANALYZEを実行しています。

ossdb=# VACUUM ANALYZE;

LPI-Japan 78 www.oss-db.jp

Page 89: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 8章パフォーマンスチューニング 8.4 クラスタ

VACUUM

8.3.4 自動バキュームデーモン

自動バキュームデーモンは、VACUUMと ANALYZEを自動的に実行してくれる仕組みです。こ

の機能が PostgreSQL に標準で装備される前は管理者が VACUUM を手動で実行するか、cron を

使って定期的に実行する必要がありました。自動バキュームデーモンはデフォルトで動作しており、

バキューム処理、統計情報再作成処理が必要になるタイミングを監視しています。

自動バキュームデーモンが動作しているかどうかを確認してみましょう。Linux上の動作してい

る autovacuumという名前のプロセスが自動バキュームデーモンです。

ossdb=# Y! ps ax | grep autovacuum11543 ? Ss 0:00 postgres: autovacuum launcher process

13742 pts/1 R+ 0:00 sh -c ps ax | grep autovacuum

8.4 クラスタ

クラスタ化は、物理的なデータの配置をインデックスに従って再配置します。再配置により、イ

ンデックスを使って検索される行データが物理ディスク上でまとめられるため、ディスクアクセス

が減り性能が向上することが期待できます。

クラスタ化を行うには CLUSTER文を使用します。初めてクラスタ化を行う場合にはインデック

スを USING句で明示的に指定する必要がありますが、2回目以降はクラスタ化するために使用した

インデックスが記録されているのでインデックスを指定しないで CLUSTER文を実行しても大丈夫

です。

以下の例では、orders表の orders_pkeyインデックスを使用してクラスタ化を行っています。

ossdb=# CLUSTER orders;ERROR: テーブル"orders"には事前にクラスタ化されたインデックスはありませんossdb=# CLUSTER orders USING orders_pkey;CLUSTER

ossdb=# Yd ordersテーブル "public.orders"

カラム | 型 | 修飾語-------------+-----------------------------+----------

order_id | integer | not null

order_date | timestamp without time zone |

customer_id | integer |

prod_id | integer |

qty | integer |

インデックス:

LPI-Japan 79 www.oss-db.jp

Page 90: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 8章パフォーマンスチューニング 8.4 クラスタ

"orders_pkey" PRIMARY KEY, btree (order_id) CLUSTER

外部キー制約:

"orders_customer_id_fkey" FOREIGN KEY (customer_id) REFERENCES customer(customer_id)

"orders_prod_id_fkey" FOREIGN KEY (prod_id) REFERENCES prod(prod_id)

ossdb=# CLUSTER orders;CLUSTER

クラスタ化に使用したインデックスは、情報の後ろに CLUSTERと表示されます。

LPI-Japan 80 www.oss-db.jp

Page 91: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第9章

バックアップとリストア

データベースのバックアップとリストアは、重要なデータを扱うデータベースにとって重要

な作業です。ハードディスクの障害などでデータが失われた時、あらかじめ取得しておいた

バックアップから確実にリストアが行えるようにしておく必要があります。この章では、デー

タベースのバックアップとリストアの方法について学びます。

9.1 ファイルのコピー

最も確実で簡単なバックアップは、ファイルレベルでのバックアップです。必要となるファイ

ルをすべてコピーすることでバックアップができます。ただし、ファイルのコピーを行うには

PostgreSQLを完全に停止する必要があります。

以下の例では、tarコマンドを使用して PostgreSQLの関連ファイルが格納されているディレクト

リ/var/lib/pgsql/9.0/data以下をアーカイブしています。

-bash-3.2$ /usr/pgsql-9.0/bin/pg_ctl stopサーバ停止処理の完了を待っています....完了サーバは停止しました-bash-3.2$ tar cf backup.tar /var/lib/pgsql/9.0/datatar: メンバ名から先頭の ‘/’ を取り除きます-bash-3.2$ ls -l backup.tar-rw-r--r-- 1 postgres postgres 119336960 8月 28 19:59 backup.tar

-bash-3.2$ /usr/pgsql-9.0/bin/pg_ctl startサーバは起動中です。

9.2 pg_dumpコマンドによるバックアップ

pg_dumpコマンドは、データベースを SQL文としてバックアップするコマンドです。ファイル

のコピーと違い、データベースを停止することなくバックアップすることができます。pg_dump

コマンドを実行すると、データベースに格納されている表や行データが SQL文として標準出力に出

力されるので、リダイレクトでファイルに保存します。保存したファイルは psqlコマンドを使って

リストアすることができます。

pg_dump コマンドは指定したデータベースだけをバックアップするコマンドですが、

LPI-Japan 81 www.oss-db.jp

Page 92: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 9章バックアップとリストア 9.3 psqlによるリストア

pg_dumpall コマンドを使うと、すべてのデータベース、作成したユーザなどの情報をまとめ

てバックアップすることができます。

以下の例では、pg_dumpコマンドでデータベース ossdbをバックアップしています。

-bash-3.2$ pg_dump ossdb > backup.sqlパスワード:

-bash-3.2$ cat backup.sql--

-- PostgreSQL database dump

--

SET statement_timeout = 0;

SET client_encoding = ’UTF8’;

(略)

--

-- Name: customer; Type: TABLE; Schema: public; Owner: postgres; Tablespace:

--

CREATE TABLE customer (

customer_id integer NOT NULL,

customer_name text

);

ALTER TABLE public.customer OWNER TO postgres;

(略)

9.3 psqlによるリストア

pg_dumpコマンドを使ってバックアップしたファイルは、psqlコマンドにリダイレクトで読み

込ませることでリストアすることができます。リストアをするには、テンプレートデータベース

template0から新しいデータベースを作成し、そのデータベースにリストアを行います。テンプレー

トデータベースは新規にデータベースを作成する際に雛形となるデータベースです。通常のデータ

ベース作成では template1が雛形して使用されますが、pg_dumpコマンドのバックアップからの

リストアの際には template0を使用します。

以下の例では、バックアップ用に新たにデータベース ossdb2を作成し、リストアを行っています。

-bash-3.2$ createdb -T template0 ossdb2パスワード:

-bash-3.2$ psql ossdb2 < backup.sqlパスワード:

SET

SET

SET

LPI-Japan 82 www.oss-db.jp

Page 93: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 9章バックアップとリストア 9.3 psqlによるリストア

(略)

CREATE TABLE

ALTER TABLE

CREATE TABLE

ALTER TABLE

CREATE TABLE

ALTER TABLE

CREATE SEQUENCE

ALTER TABLE

setval

--------

9

(1 行)

(略)

リストアできたデータベースに接続して、リストアされたことを確認します。

-bash-3.2$ psql ossdb2パスワード:

psql (9.0.5)

"help" でヘルプを表示します.

ossdb2=# Ydリレーションの一覧

スキーマ | 名前 | 型 | 所有者----------+--------------+------------+----------

public | char_test | テーブル | postgres

public | customer | テーブル | postgres

public | numeric_test | テーブル | postgres

public | order_id_seq | シーケンス | postgres

public | orders | テーブル | postgres

public | prod | テーブル | postgres

public | zip | テーブル | postgres

(7 行)

ossdb2=# SELECT count(*) FROM zip;count

--------

123006

(1 行)

LPI-Japan 83 www.oss-db.jp

Page 94: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第10章

Webアプリケーションとの連携

データベースの一般的な利用方法として、Webアプリケーションと連携してデータベースは

データの管理を行う形があります。このようにWebアプリケーションの背後で動作するデー

タベースを「バックエンドデータベース」と呼びます。この章では、Webアプリケーション

開発でよく利用されている言語「PHP」との組み合わせでのバックエンドデータベースとし

ての利用方法を学びます。

10.1 PHPとは?

PHPとは、Webサーバ上で動作するWebアプリケーション開発用の言語です。HTMLファイ

ルにアプリケーションのコードを埋め込むことができるので、Web ページの一部分にアプリケー

ションの動作を組み込んだりすることができます。

10.1.1 PHPの動作イメージ

PHP は Apache HTTP Server(以下 Apache)に組み込んで利用するモジュールとして提供さ

れており、Webサーバの Apacheと組み合わせて動作します。Webブラウザから拡張子が.phpに

なっているファイルを要求されると、そのファイル内に含まれている PHPのコードが実行され、最

終的な結果は HTMLとしてWebブラウザに渡されます。

10.2 Apacheと PHP環境の設定

Apache と PHP を利用できるようにインストールと設定を行います。インストールするのは

PostgreSQL が動作しているマシン上でも、別々のマシンでも構いません。別々のマシンにインス

トールした場合、PHP と PostgreSQL の間はネットワークで接続することになります。ここでは

PostgreSQLが動作している同じマシンに Apacheと PHPをインストールします。

10.2.1 Apacheと PHPをパッケージでインストール

CentOSでは Apacheと PHPが RPMパッケージで提供されているので、yumコマンドを使っ

てインストールします。yumコマンドでインストールが行えない場合には、インストールメディア

から rpmコマンドを使って必要なパッケージをインストールします。インストールするパッケージ

は phpと php-pgsqlです。

LPI-Japan 84 www.oss-db.jp

Page 95: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 10章Webアプリケーションとの連携 10.2 Apacheと PHP環境の設定

[root@localhost html]# yum install php php-pgsqlLoaded plugins: fastestmirror

Loading mirror speeds from cached hostfile

* base: ftp.riken.jp

* extras: ftp.riken.jp

* updates: ftp.riken.jp

Excluding Packages from CentOS-5 - Base

Finished

Excluding Packages from CentOS-5 - Updates

Finished

Setting up Install Process

Resolving Dependencies

--> Running transaction check

---> Package php.i386 0:5.1.6-27.el5_5.3 set to be updated

--> Processing Dependency: php-common = 5.1.6-27.el5_5.3 for package: php

--> Processing Dependency: php-cli = 5.1.6-27.el5_5.3 for package: php

--> Processing Dependency: libgmp.so.3 for package: php

---> Package php-pgsql.i386 0:5.1.6-27.el5_5.3 set to be updated

--> Processing Dependency: php-pdo for package: php-pgsql

--> Running transaction check

---> Package gmp.i386 0:4.1.4-10.el5 set to be updated

---> Package php-cli.i386 0:5.1.6-27.el5_5.3 set to be updated

---> Package php-common.i386 0:5.1.6-27.el5_5.3 set to be updated

---> Package php-pdo.i386 0:5.1.6-27.el5_5.3 set to be updated

--> Finished Dependency Resolution

Dependencies Resolved

================================================================================

Package Arch Version Repository Size

================================================================================

Installing:

php i386 5.1.6-27.el5_5.3 base 2.3 M

php-pgsql i386 5.1.6-27.el5_5.3 base 68 k

Installing for dependencies:

gmp i386 4.1.4-10.el5 base 664 k

php-cli i386 5.1.6-27.el5_5.3 base 2.1 M

php-common i386 5.1.6-27.el5_5.3 base 153 k

php-pdo i386 5.1.6-27.el5_5.3 base 65 k

Transaction Summary

================================================================================

Install 6 Package(s)

Upgrade 0 Package(s)

Total download size: 5.3 M

Is this ok [y/N]: yDownloading Packages:

(1/6): php-pdo-5.1.6-27.el5_5.3.i386.rpm | 65 kB 00:00

(2/6): php-pgsql-5.1.6-27.el5_5.3.i386.rpm | 68 kB 00:00

(3/6): php-common-5.1.6-27.el5_5.3.i386.rpm | 153 kB 00:00

(4/6): gmp-4.1.4-10.el5.i386.rpm | 664 kB 00:00

(5/6): php-cli-5.1.6-27.el5_5.3.i386.rpm | 2.1 MB 00:01

(6/6): php-5.1.6-27.el5_5.3.i386.rpm | 2.3 MB 00:01

--------------------------------------------------------------------------------

Total 1.5 MB/s | 5.3 MB 00:03

LPI-Japan 85 www.oss-db.jp

Page 96: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 10章Webアプリケーションとの連携 10.2 Apacheと PHP環境の設定

Running rpm_check_debug

Running Transaction Test

Finished Transaction Test

Transaction Test Succeeded

Running Transaction

Installing : php-common 1/6

Installing : gmp 2/6

Installing : php-cli 3/6

Installing : php-pdo 4/6

Installing : php-pgsql 5/6

Installing : php 6/6

Installed:

php.i386 0:5.1.6-27.el5_5.3 php-pgsql.i386 0:5.1.6-27.el5_5.3

Dependency Installed:

gmp.i386 0:4.1.4-10.el5 php-cli.i386 0:5.1.6-27.el5_5.3

php-common.i386 0:5.1.6-27.el5_5.3 php-pdo.i386 0:5.1.6-27.el5_5.3

Complete!

10.2.2 Apache+PHPの設定とテスト

インストールが終わったら、動作テストを行います。テスト用の PHP を埋め込んだファイル

test.phpを、Apacheが HTMLファイルを参照する/var/www/htmlディレクトリに作成します。

[root@localhost html]# echo "<?php phpinfo(); ?>" > /var/www/html/index.php[root@localhost html]# cat /var/www/html/index.php<?php phpinfo(); ?>

Webサーバを起動します。

[root@localhost html]# service httpd starthttpd を起動中: [ OK ]

ブラウザでWebサーバに接続します。Apacheや PHP、PostgreSQLが動作しているマシン上で

FirefoxなどのWebブラウザを起動し、以下のアドレスを入力してアクセスします。

http://localhost/

同じマシンでWebブラウザを実行できない場合には、別のマシンからWebサーバに接続してく

LPI-Japan 86 www.oss-db.jp

Page 97: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 10章Webアプリケーションとの連携 10.3 PHPと PostgreSQLの連携

ださい。

phpinfo()関数が実行され、インストールされている PHPの詳細な情報がWebページで表示さ

れます。

10.3 PHPと PostgreSQLの連携

PHP から PostgreSQL に接続し、データを取得して HTML ファイルに組み込む簡単なアプリ

ケーションを作成します。サンプルアプリケーションを作成して、実行してみましょう。サンプル

で使用している PHPで用意された PostgreSQL用の関数は以下の通りです。

pg_connect()関数

PostgreSQLに接続します。

pg_query()関数

SQLを実行します。

pg_last_error()関数

エラーを取得します。

LPI-Japan 87 www.oss-db.jp

Page 98: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 10章Webアプリケーションとの連携 10.3 PHPと PostgreSQLの連携

pg_num_rows()関数

行数を取得します。

pg_num_fields()関数

列数を取得します。

pg_field_name()関数

列名を取得します。

pg_fetch_object()関数

行データを取得します。

pg_close()関数

PostgreSQLとの接続を終了します。

また、使用しているいくつかの関数は以下の通りです。

htmlspecialchars()関数

引数の文字列の中から HTML で特別な意味を持つ文字を正しく表示可能な形式に変換します。

変換されるのは&や<>といった文字です。

strtoupper()関数

引数の文字列をすべて大文字にします。

10.3.1 データ検索ページの作成

サンプルアプリケーションを作成します。ossdbデータベースに PostgreSQLユーザ postgresで

接続し、SQL文「SELECT * FROM prod」を実行します。実行した結果は HTMLのテーブルと

して加工し、Webブラウザで表示します。

以下のサンプルを適当なファイル名(例 selectProd.php)でディレクトリ/var/www/htmlに保

存します。作業はユーザ rootで行うか、ディレクトリ/var/www/htmlのパーミッションを変更し

てその他のユーザで行ってください。

selectProd.php

<html>

<body>

<?php

$dbcon = pg_connect("dbname=ossdb user=postgres password=password");

if (!$dbcon) {

die("<hr>pg_connect 失敗<hr>");

}

$sql = "SELECT * FROM prod";

echo "SQL=$sql<br>Yn";

LPI-Japan 88 www.oss-db.jp

Page 99: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 10章Webアプリケーションとの連携 10.3 PHPと PostgreSQLの連携

$result = pg_query ($dbcon, $sql);

if (!$result) {

pg_last_error($dbcon);

die( "pg_exec 失敗<hr>");

}

$numrows = pg_num_rows($result);

$fnum = pg_num_fields($result);

echo "<table border>";

echo "<tr>";

for ($x = 0; $x < $fnum; $x++) {

echo "<td><b>";

echo htmlspecialchars(strtoupper(pg_field_name($result, $x)));

echo "</b></td>";

}

echo "</tr>";

for ($i = 0; $i < $numrows; $i++) {

$row = pg_fetch_object($result, $i);

echo "<tr align=’center’>";

for ($x = 0; $x < $fnum; $x++) {

$fieldname = pg_field_name($result, $x);

echo "<td>";

echo htmlspecialchars($row->$fieldname);

echo "</td>";

}

echo"</tr>";

}

echo "</table>";

pg_close($dbcon);

?>

</body>

</html>

ファイルを作成したら、Webブラウザからアクセスして結果を確認します。

http://localhost/selectProd.php

LPI-Japan 89 www.oss-db.jp

Page 100: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 10章Webアプリケーションとの連携 10.3 PHPと PostgreSQLの連携

10.3.2 フォームからのデータの取得方法

HTML フォームに入力されたデータを PHP で取得するには、$_POST 変数を使用します。

HTML フォームから ACTION として呼び出された PHP は POST メソッドで送信された値を連

想配列として保持しています。$_POST変数はこの連想配列にアクセスするための変数です。動作

を確認するために、HTMLフォームの test.htmlと PHPプログラム test.phpを/var/www/html

ディレクトリに作成します。

test.html

<html>

<body>

<form action="test.php" method="post">

<input type=text name="foo">

<input type=submit>

</form>

</body>

</html>

test.php

LPI-Japan 90 www.oss-db.jp

Page 101: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 10章Webアプリケーションとの連携 10.3 PHPと PostgreSQLの連携

<?php

echo htmlspecialchars($_POST[’foo’]);

?>

Web ブラウザから test.html を呼び出し、フォームに値を入力して実行ボタンをクリックしま

す。PHPの echoは変数の値を表示する命令ですので、フォームからの値をWebブラウザに表示し

ます。

http://localhost/test.html

LPI-Japan 91 www.oss-db.jp

Page 102: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 10章Webアプリケーションとの連携 10.3 PHPと PostgreSQLの連携

10.3.3 フォームからの入力を SQL文に組み込む

PHPで SQL文を実行するには、一度 SQL文を文字列変数に代入し、その変数を pg_query関

数に渡しています。文字列変数に代入する際にフォームからの入力を SQL文に組み込めば、フォー

ム入力に応じて動作を変更することができます。

selectForm.html

<html>

<body>

検索したいテーブル名を入力して下さい。<form action="selectForm.php" method="post">

<input type=text name="table">

<input type=submit>

</form>

</body>

</html>

selectForm.php

LPI-Japan 92 www.oss-db.jp

Page 103: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 10章Webアプリケーションとの連携 10.3 PHPと PostgreSQLの連携

<html>

<body>

<?php

$dbcon = pg_connect("dbname=ossdb user=postgres password=password");

if (!$dbcon) {

die("<hr>pg_connect 失敗<hr>");

}

$table = $_POST[’table’];

$sql = "SELECT * FROM $table";

echo "SQL=$sql<br>Yn";

$result = pg_query ($dbcon, $sql);

if (!$result) {

pg_last_error($dbcon);

die( "pg_exec 失敗<hr>");

}

$numrows = pg_num_rows($result);

$fnum = pg_num_fields($result);

echo "<table border>";

echo "<tr>";

for ($x = 0; $x < $fnum; $x++) {

echo "<td><b>";

echo htmlspecialchars(strtoupper(pg_field_name($result, $x)));

echo "</b></td>";

}

echo "</tr>";

for ($i = 0; $i < $numrows; $i++) {

$row = pg_fetch_object($result, $i);

echo "<tr align=’center’>";

for ($x = 0; $x < $fnum; $x++) {

$fieldname = pg_field_name($result, $x);

echo "<td>";

echo htmlspecialchars($row->$fieldname);

echo "</td>";

}

echo"</tr>";

}

echo "</table>";

pg_close($dbcon);

?>

</body>

</html>

作成したフォームにアクセスし、検索したい表の名前を入力します。

http://localhost/selectForm.html

LPI-Japan 93 www.oss-db.jp

Page 104: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 10章Webアプリケーションとの連携 10.3 PHPと PostgreSQLの連携

LPI-Japan 94 www.oss-db.jp

Page 105: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 10章Webアプリケーションとの連携 10.3 PHPと PostgreSQLの連携

LPI-Japan 95 www.oss-db.jp

Page 106: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第11章

実習環境の構築方法

この章では、本教科書の実習環境の構築法法として、OSのインストール、PostgreSQLのイ

ンストール、データベースの作成について解説しています。

11.1 OSのインストール

本教科書では Linux ディストリビューションは CentOS 5.7 32 ビット版を使用しています。イ

ンストールは特別なところはありませんので、インストーラーのデフォルト設定でインストールし

ます。

11.1.1 セキュリティの設定

セキュリティの設定では、外部からの攻撃などを受けない環境であることを確認した上で、ファ

イアーウォールや SELinuxは無効にしていることを想定しています。

11.2 RPMパッケージのダウンロードとインストール

以下のWeb サイトから PostgreSQL バージョン.9.0 の RPM パッケージをダウンロードして、

RPMコマンドでインストールしてください。

ダウンロードWebページ

http://yum.pgrpms.org/packages.php

LPI-Japan 96 www.oss-db.jp

Page 107: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 11章実習環境の構築方法 11.2 RPMパッケージのダウンロードとインストール

PostgreSQLのバージョンと、インストールした Linuxディストリビューションのバージョンや

種類(32ビットか 64ビットか)などから適切なものを選択します。今回は CentOS 5.7 32ビットを

インストールしているので、PostgreSQL 9.0のリストの中から「RHEL/CentOS/Scientific Linux

5 - i386」を選択します。様々なパッケージの更新履歴が表示されますが、最低限必要なパッケージ

は「PostgreSQL Database Server PGDG」に集められています。

CentOS 5 32ビット版用 PostgreSQL 9/0 ダウンロードWebページ

http://yum.pgrpms.org/9.0/redhat/rhel-5-i386/repoview/postgresqldbserver.group.html

LPI-Japan 97 www.oss-db.jp

Page 108: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 11章実習環境の構築方法 11.2 RPMパッケージのダウンロードとインストール

ダウンロードしてインストールするパッケージは以下の 3種類です。

• postgresql90

• postgresql90-libs

• postgresql90-server

各パッケージ毎のダウンロードページでいくつかのバージョンのパッケージが用意されている場

合がありますが、メジャーリリース番号が同じものであれば構いません。

以下の例では、wgetコマンドを使ってバージョン 9.0.5の RPMパッケージをダウンロードして

います。

○ wgetコマンドを使ったダウンロード

[root@localhost ~]# wget http://yum.pgrpms.org/9.0/redhat/rhel-5-i386/postgresql90-9.0.5-1PGDG.rhel5.i386.rpm[root@localhost ~]# wget http://yum.pgrpms.org/9.0/redhat/rhel-5-i386/postgresql90-libs-9.0.5-1PGDG.rhel5.i386.rpm[root@localhost ~]# wget http://yum.pgrpms.org/9.0/redhat/rhel-5-i386/postgresql90-server-9.0.5-1PGDG.rhel5.i386.rpm

LPI-Japan 98 www.oss-db.jp

Page 109: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 11章実習環境の構築方法 11.3 データベースの初期化

rpmコマンドでインストールします。以下の例では、カレントディレクトリにあるすべての RPM

パッケージをインストールしています。

○ rpmコマンドを使ったインストール

[root@localhost ~]# rpm -ivh *.rpm準備中... ########################################### [100%]

1:postgresql90-libs ########################################### [ 33%]

2:postgresql90 ########################################### [ 67%]

3:postgresql90-server ########################################### [100%]

11.2.1 バージョン表記

メジャーリリース番号は、バージョン表記の最初のドットの後の番号です。たとえばバージョン

9.0.4 と 9.0.5 は同じメジャーリリース番号です。バージョン 9.1.1 は同じバージョン 9 系ですが、

メジャーリリース番号が異なります。本教科書は可能な限り標準的な SQL で説明を行っているた

め、PostgreSQLのバージョンの違いにはほとんど影響を受けませんが、できるだけ同じメジャーリ

リース番号、つまりバージョン 9.0系のパッケージをインストールしてください。

11.3 データベースの初期化

データベースを初期化し、初期データベース(データベースクラスタ)を作成します。インストー

ル後に 1回だけ行います。

[root@localhost ~]# service postgresql-9.0 initdbデータベースを初期化中: [ OK ]

11.4 データベースを起動

データベースを起動し、使用可能な状態にします。

[root@localhost ~]# service postgresql-9.0 startpostgresql-9.0 サービスを開始中: [ OK ]

デフォルトでは手動起動になっているので、システムの起動毎に自動的に起動したい場合には

chkconfigコマンドを実行しておきます。

LPI-Japan 99 www.oss-db.jp

Page 110: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 11章実習環境の構築方法 11.5 動作の確認

[root@localhost ~]# chkconfig postgresql-9.0 on[root@localhost ~]# chkconfig --list postgresql-9.0postgresql-9.0 0:off 1:off 2:on 3:on 4:on 5:on 6:off

11.5 動作の確認

データベースの動作の確認を行います。インストールした PostgreSQLは、OSユーザ postgres

が初期化ユーザとして管理権限を持っているので、suコマンドでユーザ postgresに変更して操作を

行います。

[root@localhost ~]# su - postgres-bash-3.2$

psqlに-lオプションを付けて実行し、作成されているデータベースを確認します。

-bash-3.2$ psql -lデータベース一覧

名前 | 所有者 | エンコーディング | 照合順序 | Ctype(変換演算子) |

アクセス権-----------+----------+------------------+-------------+-------------------+-----------------------

postgres | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 |

template0 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres +

| | | | | postgres=CTc/postgres

template1 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres +

| | | | | postgres=CTc/postgres

(3 行)

11.6 RPMからインストールした場合の各種ディレクトリ

RPMからインストールした場合、各種ディレクトリは以下のように設定されています。

ユーザ postgresのホームディレクトリ

• /var/lib/pgsql

PostgreSQL関係のファイルがインストールされるディレクトリ

• /usr/pgsql-9.0/

LPI-Japan 100 www.oss-db.jp

Page 111: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 11章実習環境の構築方法 11.7 データベースの作成

-bash-3.2$ ls -l /usr/pgsql-9.0/合計 12

drwxr-xr-x 2 root root 4096 9月 18 11:21 bin

drwxr-xr-x 2 root root 4096 9月 18 11:21 lib

drwxr-xr-x 6 root root 4096 9月 18 11:21 share

データベースの作成されるディレクトリ

• /var/lib/pgsql/9.0/data

このディレクトリにデータベースの他、各種設定ファイルが作成されます。

ライブラリへのリンク

/etc/ld.so.conf.dディレクトリに postgresql-9.0-libs.confファイルが作成されています。

[root@localhost ~]# cat /etc/ld.so.conf.d/postgresql-9.0-libs.conf/usr/pgsql-9.0/lib/

11.7 データベースの作成

実習用のデータベース ossdbを作成します。データベースの作成は OSユーザ postgresで行いま

す。作成後、接続出来ることを確認しておきます。

[root@localhost ~]# su - postgres-bash-3.2$ createdb ossdb-bash-3.2$ psql ossdbpsql (9.0.5)

"help" でヘルプを表示します.

ossdb=#

11.8 表の作成

表を作成します。prod表、customer表、orders表の 3つを作成します。

 

以下の SQL文を psqlを実行している端末にコピー&ペーストすれば、必要な表が作成されます。

LPI-Japan 101 www.oss-db.jp

Page 112: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 11章実習環境の構築方法 11.9 データの入力

CREATE TABLE prod

(prod_id integer,

prod_name text,

price integer);

CREATE TABLE customer

(customer_id integer,

customer_name text);

CREATE TABLE orders

(order_id integer,

order_date timestamp,

customer_id integer,

prod_id integer,

qty integer);

以下は実行例です。

ossdb=# CREATE TABLE prod(prod_id integer,prod_name text,price integer);CREATE TABLE

(略)

11.9 データの入力

作成した表に初期データを入力します。以下の SQL 文を psql を実行している端末にコピー

&ペーストすれば、初期データがそれぞれの表に入力されます。

INSERT INTO customer(customer_id,customer_name) VALUES (1,’佐藤商事’);

INSERT INTO customer(customer_id,customer_name) VALUES (2,’鈴木物産’);

INSERT INTO customer(customer_id,customer_name) VALUES (3,’高橋商店’);

INSERT INTO prod(prod_id,prod_name,price) VALUES (1,’みかん’,50);

INSERT INTO prod(prod_id,prod_name,price) VALUES (2,’りんご’,70);

INSERT INTO prod(prod_id,prod_name,price) VALUES (3,’メロン’,100);

INSERT INTO orders(order_id,order_date,customer_id,prod_id,qty) VALUES (1,now(),1,1,10);

INSERT INTO orders(order_id,order_date,customer_id,prod_id,qty) VALUES (2,now(),2,2,5);

INSERT INTO orders(order_id,order_date,customer_id,prod_id,qty) VALUES (3,now(),3,3,8);

INSERT INTO orders(order_id,order_date,customer_id,prod_id,qty) VALUES (4,now(),2,1,3);

INSERT INTO orders(order_id,order_date,customer_id,prod_id,qty) VALUES (5,now(),3,2,4);

以下は実行例です。

LPI-Japan 102 www.oss-db.jp

Page 113: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

第 11章実習環境の構築方法 11.9 データの入力

ossdb=# INSERT INTO customer(customer_id,customer_name) VALUES (1,’佐藤商事’);INSERT 0 1

ossdb=# INSERT INTO customer(customer_id,customer_name) VALUES (2,’鈴木物産’);INSERT 0 1

ossdb=# INSERT INTO customer(customer_id,customer_name) VALUES (3,’高橋商店’);INSERT 0 1

(略)

LPI-Japan 103 www.oss-db.jp

Page 114: オープンソースデータベース標準教科書 ― PostgreSQL ― (Ver1.0.0)

オープンソースデータベース標準教科書 ― PostgreSQL ―(Ver1.0.0)

2011年 10月 05日 v1.0.0版発行

発行所 LPI-Japan  

(C) 2011 LPI-Japan