...

IBM Informix SQL チュートリアル・ガイド バージョン 5.2

by user

on
Category: Documents
227

views

Report

Comments

Transcript

IBM Informix SQL チュートリアル・ガイド バージョン 5.2
D:\JPN\0403\sqlt.f\title.fm
January 23, 2003 3:21 pm
Beta Beta Beta Beta Beta Beta Beta Beta Beta Beta Beta Beta Beta Beta Beta
IBM Informix
SQL
チュートリアル・ガイド
バージョン 5.2
Part No. CT1VZJA
GB88-8615-00
( 英文原典 : G251-0403-00)
V:\Infomix\G251040300_book\sqlt.f\title.fm
February 6, 2003 3:24 pm
Beta Beta Beta Beta Beta Beta Beta Beta Beta Beta Beta Beta Beta Beta
お願い
本書および本書で紹介する製品をご使用になる前に、特記事項に記載されている情報をお読
みください。
本マニュアルに関するご意見やご感想は、次の URL からお送りください。今後の参考にさせていただきま
す。
http://www.ibm.com/jp/manuals/main/mail.html
なお、日本 IBM 発行のマニュアルはインターネット経由でもご購入いただけます。詳しくは
http://www.ibm.com/jp/manuals/ の「ご注文について」をご覧ください。
(URL は、変更になる場合があります )
原典 :
G251-0403-00
IBM Informix Guide to SQL
Tutorial
発行 :
日本アイ・ビー・エム株式会社
担当 :
ナショナル・ランゲージ・サポート
第 1 刷 2002.12
© Copyright International Business Machines Corporation 1996,2002. All rights reserved.
© Copyright IBM Japan 2002
目次
目次
序
概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
本書について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
本書の構成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
SQL を使用する IBM Informix 製品 . . . . . . . . . . . . . . . . . 5
本書で取り上げる製品 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
デモンストレーション・データベース . . . . . . . . . . . . . . 6
IBM Informix OnLine でのデモンストレーション・
データベースの作成. . . . . . . . . . . . . . . . . . . . 7
IBM Informix SE でのデモンストレーション・
データベースの作成. . . . . . . . . . . . . . . . . . . . . 8
IBM Informix サーバー製品 バージョン 5.x の新機能 . . 9
ドキュメントの規則 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
文字の表記 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
構文の規則 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
サンプル・コードの規則 . . . . . . . . . . . . . . . . . . . . . . 16
関連マニュアル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
オンライン・マニュアル . . . . . . . . . . . . . . . . . . . . . . 17
エラー・メッセージ・ファイル . . . . . . . . . . . . . . . . 18
ドキュメント・ノート、リリース・ノート、
マシン・ノート. . . . . . . . . . . . . . . . . . . . . . . . 21
業界標準準拠 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
資料・製品についてのご意見 . . . . . . . . . . . . . . . . . . . . . 22
第 1 章
データベースの基本
本章の概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-3
データベース : 概要および価値. . . . . . . . . . . . . . . . . . . .1-3
データ・モデル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-3
並行使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-9
集中管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-11
重要なデータベース用語 . . . . . . . . . . . . . . . . . . . . . . . .1-12
関係モデル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-12
Bookname
February 6, 2003 3:24 pm
構造化問合せ言語 (SQL). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-15
標準 SQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-16
Informix SQL および ANSI SQL. . . . . . . . . . . . . . . . . . . . . . . . . .1-16
ANSI 準拠データベース . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-17
データベース・ソフトウェア . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1-17
データベース・サーバー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-17
アプリケーション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-18
対話型 SQL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-18
レポートおよびフォーム . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-18
一般的なプログラミング . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-19
アプリケーションおよびデータベース・サーバー . . . . . . . . .1-19
サマリー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1-20
第 2 章
単純な SELECT 文
概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-3
SELECT 文について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-3
基本的な概念 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-4
本章の構成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-11
単一表 SELECT 文 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-12
すべての列と行の選択 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-12
特定の列の選択 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-19
WHERE 節の使用方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-26
比較条件の作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-27
式と導出値 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-41
SELECT 文の関数の使用方法 . . . . . . . . . . . . . . . . . . . . . . . . . . .2-47
複数表 SELECT 文 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-60
デカルト積の作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-60
結合の作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-62
問合せのショートカット . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-70
サマリー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2-74
第 3 章
高度な SELECT 文
概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-3
GROUP BY および HAVING 節の使用法 . . . . . . . . . . . . . . . . . . . . . .3-4
GROUP BY 節の使用法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-4
HAVING 節の使用法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-8
高度な結合の作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-10
自己結合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-11
外部結合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-19
SELECT 文内の副問合せ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-29
ALL の使用法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-30
ANY の使用法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-31
一価副問合せ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3-32
4
目次
Bookname
February 6, 2003 3:24 pm
相関副問合せ. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-33
EXISTS の使用法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-34
集合演算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-37
和. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-37
積. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-45
差. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3-47
サマリー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2-48
第 4 章
問合せの最適化
概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-3
最適化手法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-4
問題の検査. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-5
トータル・システムの考慮. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-5
アプリケーションについて. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-5
アプリケーションの測定. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-6
ギルティー関数の検索. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-7
広範囲な検査. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-7
問合せオプティマイザー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-8
表の順序の重要性. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-8
オプティマイザーの機能. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-14
予定の読取り. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-19
問合せの時間コスト . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-21
メモリー内の動作. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-21
ディスク・アクセス管理. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-21
行の読取りのコスト. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-24
順次アクセスのコスト. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-25
非順次アクセスのコスト. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-26
行 ID アクセスのコスト . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-26
インデックス・アクセスのコスト. . . . . . . . . . . . . . . . . . . . . . . 4-26
小さな表のコスト. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-27
ネットワーク・アクセスのコスト. . . . . . . . . . . . . . . . . . . . . . . 4-28
問合せの高速化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-30
テスト環境の準備. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-31
データ・モデルの理解. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-32
問合せ予定の理解. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-32
問合せの再考. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-33
問合せの速度を上げるための一時表の使用. . . . . . . . . . . . . . . 4-39
サマリー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4-45
第 5 章
データを修正する文
概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-3
データを修正する文 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-4
行の削除. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5-4
目次 5
Bookname
February 6, 2003 3:24 pm
行数が既知の行の削除 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-5
行の挿入 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-7
行の更新 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-11
データベースのアクセス権 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-15
表アクセス権の表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-16
データ整合性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-17
実体整合性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-18
意味整合性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-18
参照整合性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-19
中断された修正 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-21
トランザクション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-22
トランザクション・ログ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-22
トランザクションの指定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-23
アーカイブおよびログ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-24
単純なデータベースのアーカイブ (IBM Informix SE) . . . . . . .5-24
IBM Informix OnLine のアーカイブ . . . . . . . . . . . . . . . . . . . . . .5-25
同時実行性およびロック . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-26
サマリー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5-26
第 6 章
6
プログラム内の SQL
概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-3
プログラム内の SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-4
静的埋込み . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-5
動的文 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-5
プログラム変数とホスト変数 . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-5
データベース・サーバーの呼出し . . . . . . . . . . . . . . . . . . . . . . . . . . .6-7
SQL 通信領域. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-8
SQLCODE フィールド . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-11
SQLERRD 配列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-12
SQLAWARN 配列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-12
単一行の抽出 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-13
データ型の変換 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-14
NULL データの処理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-15
エラーの処理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-16
複数行の抽出 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-19
カーソルの宣言 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-20
カーソルのオープン . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-20
行の取出し . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-21
カーソル入力モード . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-23
カーソルのアクティブ・セット . . . . . . . . . . . . . . . . . . . . . . . . .6-24
カーソルの使用 : 部品展開 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-26
動的 SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-29
PREPARE 文での処理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6-29
目次
Bookname
February 6, 2003 3:24 pm
PREPARE 文で処理された SQL の実行. . . . . . . . . . . . . . . . . . . 6-32
動的ホスト変数. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-34
PREPARE 文で処理された文の解放 . . . . . . . . . . . . . . . . . . . . . 6-34
高速実行. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-35
埋込みデータ定義 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-35
GRANT 文と REVOKE 文のアクセス権の埋込み . . . . . . . . . . 6-35
サマリー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6-38
第 7 章
データを修正するプログラム
概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-3
DELETE の使用方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-3
直接削除. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-4
カーソルを使用した削除. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-7
INSERT の使用. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-8
INSERT カーソルの使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-9
定数行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-12
挿入の例. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-12
UPDATE の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-15
UPDATE カーソルの使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-16
表のクリーンアップ. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-18
同時実行性およびロック . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-18
同時実行性およびパフォーマンス. . . . . . . . . . . . . . . . . . . . . . . 7-19
ロックおよび整合性. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-19
ロックおよびパフォーマンス. . . . . . . . . . . . . . . . . . . . . . . . . . . 7-19
同時実行性の問題. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-20
ロックの動作. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-21
排他レベルの設定. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-26
ロック・モードの設定. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-30
単純な同時実行性. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-32
他のデータベース・サーバーを使用したロック. . . . . . . . . . . 7-33
HOLD カーソル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-35
サマリー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7-37
第 8 章
データ・モデルの作成
概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-3
データ・モデルを作成する理由 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-3
拡張された関係分析. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-3
基本的な考え方 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-6
表、行、列. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-6
主キー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-7
候補キー. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-7
外部キー ( 結合列 ). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-8
手順 1:エンティティーの命名 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-8
目次 7
Bookname
February 6, 2003 3:24 pm
エンティティー・キー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-9
エンティティー表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-11
住所録の例 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8-11
手順 2:関係の定義 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-14
関係の発見 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-14
表への関係の追加 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-19
手順 3:属性のリスト化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-22
属性の選択 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-22
属性表の選択 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-22
サマリー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .8-24
第 9 章
モデルの実装
概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-3
ドメインの定義 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-3
データ型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-4
デフォルト値 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-21
チェック制約 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-21
ドメインの指定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-22
データベースの作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-24
CREATE DATABASE の使用方法 . . . . . . . . . . . . . . . . . . . . . . . .9-24
CREATE TABLE の使用方法 . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-28
コマンド・スクリプトの使用方法 . . . . . . . . . . . . . . . . . . . . . . .9-30
表の構築 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-31
サマリー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9-32
第 10 章
モデルの調整
概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-3
IBM Informix OnLine ディスク装置 . . . . . . . . . . . . . . . . . . . . . . . . . .10-4
チャンクおよびページ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-4
DB 領域および BLOB 領域 . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-5
ディスクのミラーリング . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-5
データベース . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-6
表および領域 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-6
表領域 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-8
エクステント . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-9
表のフラグメント化をなくす . . . . . . . . . . . . . . . . . . . . . . . . . .10-12
表サイズの計算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-14
固定長の行の見積り . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-14
可変長の行の見積り . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-16
インデックス・ページの見積り . . . . . . . . . . . . . . . . . . . . . . . .10-17
BLOB ページの見積り . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-19
BLOB データの格納 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-20
インデックスの管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10-21
8
目次
Bookname
February 6, 2003 3:24 pm
インデックスによって消費される領域. . . . . . . . . . . . . . . . . . 10-22
インデックスによって消費される時間. . . . . . . . . . . . . . . . . . 10-22
インデックスの選択. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-23
インデックスの修正を遅らせる重複キー. . . . . . . . . . . . . . . . 10-25
インデックスの削除. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-26
クラスター・インデックス. . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-27
逆正規化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-29
問合せを高速化するための行の短縮. . . . . . . . . . . . . . . . . . . . 10-29
長い文字列の排除. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-29
ワイド表の分割. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-31
トール表の分割. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-32
冗長データおよび導出データ. . . . . . . . . . . . . . . . . . . . . . . . . . 10-33
同時実行性の最大化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-35
競合の緩和. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-35
修正のスケジュール変更. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-36
更新の分離および分散. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-37
サマリー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10-38
第 11 章
セキュリティー、ストアード・プロシージャー、およびビュー
概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-3
データベースへのアクセスの制御 . . . . . . . . . . . . . . . . . . . . . . . . . . 11-4
データベース・ファイルの保護. . . . . . . . . . . . . . . . . . . . . . . . . 11-4
機密データの保護. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-5
アクセス権の付与 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-6
データベース・レベル・アクセス権. . . . . . . . . . . . . . . . . . . . . 11-6
所有権 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-8
表レベル・アクセス権. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-9
プロシージャー・レベル・アクセス権. . . . . . . . . . . . . . . . . . 11-14
アクセス権の自動化. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-14
ストアード・プロシージャーの使用 . . . . . . . . . . . . . . . . . . . . . . . 11-17
ストアード・プロシージャーの作成および実行. . . . . . . . . . 11-17
データの読込みの制約. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-19
データの変更の制約. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-20
データの変更の監視. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-20
オブジェクト作成の制約. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-22
ビューの使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-23
ビューの作成. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-24
ビュー全体を通した修正. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-27
アクセス権およびビュー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-30
ビュー作成時のアクセス権. . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-31
ビュー使用時のアクセス権. . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-31
サマリー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11-34
目次 9
Bookname
February 6, 2003 3:24 pm
第 12 章
ネットワークと分散
概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12-3
ネットワークの構成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12-3
ローカル・エリア・ネットワーク . . . . . . . . . . . . . . . . . . . . . . .12-4
データベース・サーバーのネットワーキング . . . . . . . . . . . . .12-6
ネットワークの透過性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12-8
データへの接続 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12-8
LAN での接続 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12-8
IBM Informix NET を介した接続. . . . . . . . . . . . . . . . . . . . . . . . .12-9
分散型データ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12-13
外部表の命名 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12-13
外部表を使用したシノニムの使用 . . . . . . . . . . . . . . . . . . . . . .12-14
シノニム連鎖 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12-15
外部表の修正 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12-16
サマリー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .12-17
付録 A
特記事項
索引
10
目次
Bookname
February 6, 2003 3:24 pm
序
序
概要 3
本書について 3
本書の構成 4
SQL を使用する IBM Informix 製品 5
本書で取り上げる製品 5
デモンストレーション・データベース 6
IBM Informix OnLine でのデモンストレーション・
データベースの作成 7
IBM Informix SE でのデモンストレーション・
データベースの作成 8
IBM Informix サーバー製品 バージョン 5.x の新機能 9
ドキュメントの規則 10
文字の表記 11
構文の規則 11
サンプル・コードの規則 16
関連マニュアル 17
オンライン・マニュアル 17
エラー・メッセージ・ファイル 18
finderr スクリプト 19
rofferr スクリプト 20
ドキュメント・ノート、リリース・ノート、
マシン・ノート 21
業界標準準拠 21
資料・製品についてのご意見 22
ブック名
February 6, 2003 3:24 pm
2
序
ブック名
February 6, 2003 3:24 pm
概要
この章では、本書の情報の概要を提供し、使用する規則について説明しま
す。
本書について
本書は、IBM Informix 製品によって実装される構造化問合せ言語 (SQL) につ
いてのチュートリアルです。IBM Informix SQL チュートリアル・ガイド とそ
の姉妹編 IBM Informix SQL リファレンス・ガイド では、IBM Informix ソフト
ウェア・ツールを使用して、リレーショナル・データベースを作成、管理、
および使用する方法について説明します。
IBM Informix SQL チュートリアル・ガイド は、コンピューターの使用方法を
すでに知っているユーザーを対象にしています。本書を効率的に使用する
には、デスクトップ・ワークステーションか、または大きなマシンに接続
されている端末などのコンピューターを、日常業務の過程で定期的に使用
している必要があります。プログラムを開始し、ファイルを作成してコ
ピーし、使用するコンピューター・オペレーティング・システムの他の共
通コマンドを実行する方法を認識しておく必要があります。
また、次の IBM Informix ソフトウェアも必要です。
•
IBM Informix OnLine データベース・サーバーまたは IBM Informix SE デー
タベース・サーバー
データベース・サーバーは、ユーザーのマシンにインストールされてい
るか、またはネットワーク上でユーザーのマシンに接続されている他の
マシンにインストールされている必要があります。
•
IBM Informix SQL、IBM Informix 4GL、または DB-Access などの
IBM Informix アプリケーション開発支援ツール
アプリケーション開発支援ツールを使用して問合せを構成し、データベー
ス・サーバーに送信し、データベース・サーバーが戻す結果を表示するこ
とができます。DB-Access を使用すると、本書で説明するすべての SQL 文を
試行することができます。
序 3
本書の構成
本書の構成
IBM Informix SQL チュートリアル・ガイド には、次の章が含まれています。
• 序章では、IBM Informix ファミリー製品における SQL の位置付け、本書
の使用方法、製品の使用例が描かれているデモンストレーション・デー
タベースについて説明します。また、IBM Informix のメッセージおよび
修正情報 について説明し、IBM Informix サーバー製品のバージョン 5.x
の新機能もリストします。
• 第 1 章、『データベースの基礎』では、データベース用語の概要など、本
書を通じて使用されるいくつかの重要な用語と概念を定義します。
• 第 2 章、『単純 SELECT 文』では、データベースのデータを取り出して
表示するための簡単な問合せの作成について説明します。
• 第 3 章、『拡張 SELECT 文』では、データベースのデータを取り出して
表示するための拡張された問合せの作成について説明します。
• 第 4 章、『問合せの最適化』では、問合せを定義して最適化する技法を
定義し、問合せオプティマイザーを紹介し、さまざまな操作の時間コス
トについて説明します。
• 第 5 章、『データを修正する文』では、データの挿入、削除、または更
新に使用する文について説明し、データベース・アクセス権、データ整
合性の管理、データのアーカイブの概念について紹介します。
• 第 6 章、『プログラム内の SQL』では、データベース・サーバーの呼出
し、行の抽出、およびデータの埋込みについて説明します。
• 第 7 章、『データを修正するプログラム』では、同時実行性およびデー
タのロックについての詳細な検討と共に、INSERT 文、DELETE 文、およ
び UPDATE 文の詳細について説明します。
• 第 8 章、『データ・モデルの作成』では、データ・モデルのコンポーネ
ントについて説明し、データ・モデルの作成のための段階的なプロシー
ジャーを提供します。
• 第 9 章、『モデルの実装』では、データベース定義域を定義してデータ
ベースを作成する方法について説明します。
• 第 10 章、『モデルの調整』では、ディスク装置を含め、テーブル・サイ
ズを計算し、索引を管理して、同時実行性を最大化する効率的なデータ
ベース・モデルの設定に役立つ多くの詳細な情報を説明します。
• 第 11 章、『セキュリティーとビュー』では、アクセス権を付与してスト
アード・プロシージャーとビューを使用することによって、データ・セ
キュリティーを確実に実施する方法の詳細について説明します。
• 第 12 章、『ネットワークと分散』では、ネットワーク、およびネット
ワーク上で最高のパフォーマンスを得られるようにデータベースをセッ
トアップする方法を検討します。
4 序
Bookname
February 6, 2003 3:24 pm
SQL を使用する IBM Informix 製品
• 付録の『特記事項』では、IBM の製品、機能、およびサービスについ
て説明します。
SQL を使用する IBM Informix 製品
IBM では、SQL を使用する多くのアプリケーション開発支援ツールおよび
CASE ツールを提供しています。現在使用可能なアプリケーション開発支援
ツールには、IBM Informix SQL、IBM Informix 4GL や IBM Informix 4GL Interactive Debugger などの製品、および IBM Informix ESQL/C などの埋込み言語製
品が含まれています。
IBM Informix UNIX 製品は、IBM Informix OnLine データベース・サーバーま
たは IBM Informix SE データベース・サーバーのいずれかと連動して稼働し
ます。ネットワーク上でアプリケーションを実行している場合、
IBM Informix NET または IBM Informix STAR などの IBM Informix クライアン
ト / サーバー製品を使用することができます。IBM Informix NET には、複数
の IBM Informix SE データベース・サーバー用の通信機能があります。
IBM Informix STAR によって、複数の IBM Informix OnLine データベース・
サーバーへの分散データベース・アクセスが可能になります。
本書で取り上げる製品
本書で表示される情報は、次の製品とバージョンに有効です。SQL の使用
方法に相違がある場合は、詳しく説明します。
•
4GL (C コンパイラー 版 および Rapid Development System 版 )
•
•
•
•
•
•
•
IBM Informix SQL バージョン 4.1
バージョン 4.1
IBM Informix ESQL/C バージョン 5.0
IBM Informix ESQL/COBOL バージョン 5.0
IBM Informix SE バージョン 5.0
IBM Informix NET バージョン 5.0
IBM Informix OnLine バージョン 5.2
IBM Informix STAR バージョン 5.0
「IBM Informix TP/XA User Manual」では、SQL 文を IBM Informix TP/XA で使用
するときに注意しておかなければならない特別な考慮事項について説明し
ます。
序 5
Bookname
February 6, 2003 3:24 pm
デモンストレーション・データベース
デモンストレーション・データベース
IBM Informix データベース・サーバー製品に付属の DB-Access ユーティリ
ティーには、仮想のスポーツ用品卸売業者についての情報を含む stores5 と
呼ばれるデモンストレーション・データベースが含まれます。また、デモ
ンストレーション・アプリケーションを構成するサンプル・コマンド・
ファイルも含まれています。
本書のサンプルのほとんどは、stores5 デモンストレーション・データベー
スを基にしています。「IBM Informix SQL リファレンス・ガイド」に、stores5
データベースが詳細に説明され、その内容がリストされています。
デモンストレーション・データベースのインストールに使用するスクリプ
トは、dbaccessdemo5 と呼ばれ、$INFORMIXDIR/bin ディレクトリーに配置
されます。提供するデータベース名は、デモンストレーション・データ
ベースに与えられた名前です。データベース名を指定しない場合、名前は
stores5 にデフォルト設定されます。データベースの命名には、次のルール
に従ってください。
•
•
•
•
•
データベース名は、10 文字長までが可能である。
名前の先頭文字は、英字である必要がある。
名前の他の文字に、英数字、記号、アンダースコア (_) を使用できる。
DB-Access は、大文字と小文字を区別しない。
データベース名は、一意である必要がある。
dbaccessdemo5 を実行すると、ユーザーは、データベースの作成者として、
そのデータベースの所有者とデータベース管理者 (DBA) になります。
IBM Informix データベース・サーバーを、インストール指示に従ってイン
ストールした場合、デモンストレーション・データベースを構成するファ
イルは、既存のデータベースに変更を加えることができないように保護さ
れています。
dbaccessdemo5 スクリプトは、新しいデモンストレーション・データベー
スと連動する場合に、常に再実行できます。スクリプトは、データベース
の作成が完了した後、それを伝えるプロンプトを出し、サンプル・コマン
ド・ファイルをカレント・ディレクトリーにコピーするかどうかを尋ねま
す。サンプル・ファイルに変更を加えたために既存のバージョンに置き換
えない場合は、プロンプトに対して “N” と応答します。サンプル・コマン
ド・ファイルをコピーする場合は、プロンプトに対して “Y” と応答します。
6 序
Bookname
February 6, 2003 3:24 pm
デモンストレーション・データベース
IBM Informix OnLine でのデモンストレーション・
データベースの作成
IBM Informix OnLine 環境にデモンストレーション・データベースを構築す
るには、次のステップに従います。
1. IBM Informix 製品がインストールされているディレクトリーの名前を含
むように、INFORMIXDIR 環境を設定します。SQLEXEC を $INFORMIXDIR/lib/sqlturbo に設定します。( 環境変数の完全な説明については、
IBM Informix SQL リファレンス・ガイド を参照してください。)
2. SQL コマンド・ファイル用に新規ディレクトリーを作成します。ディレ
クトリーの作成には、次のコマンドを入力します。
mkdir dirname
3. 次のコマンドを入力して、新規ディレクトリーをカレント・ディレクト
リーに変更します。
cd dirname
4. 次のコマンドを入力して、デモンストレーション・データベースを作成
し、サンプル・コマンド・ファイルをコピーします。
dbaccessdemo5 dbname
データベース用のデータが、ルート DB 領域に書き込まれます。
データにアクセスする SQL アクセス権を他のユーザーに与えるには、
GRANT 文および REVOKE 文を使用します。GRANT 文および REVOKE 文は、
IBM Informix SQL リファレンス・ガイド に記載されています。
ユーザーのディレクトリーにコピーされたコマンド・ファイルを使用する
には、dbaccessdemo5 スクリプトの実行元であるディレクトリーのパス名
にある各ディレクトリー用に UNIX 読込み権限および実行権限を持つ必要
があります。他のユーザーに、自分のディレクトリー内のコマンド・ファ
イルにアクセスする許可を与えるには、UNIX chmod コマンドを使用しま
す。
序 7
Bookname
February 6, 2003 3:24 pm
デモンストレーション・データベース
IBM Informix SE でのデモンストレーション・
データベースの作成
IBM Informix SE 環境にデモンストレーション・データベースを構築するに
は、次のステップを実行します。
1. IBM Informix 製品がインストールされているディレクトリーの名前を含
むように、INFORMIXDIR 環境を設定します。SQLEXEC を $INFORMIXDIR/lib/sqlexec に設定します。( 環境変数の完全な説明については、
IBM Informix SQL リファレンス・ガイド を参照してください。)
2. デモンストレーション・データベース用に新規ディレクトリーを作成し
ます。このディレクトリーには、デモンストレーション・データベース
に含まれるサンプル・コマンド・ファイルを含めます。ディレクトリー
の作成には、次のコマンドを入力します。
mkdir dirname
3. 次のコマンドを入力して、新規ディレクトリーをカレント・ディレクト
リーに変更します。
cd dirname
4. 次のコマンドを入力して、デモンストレーション・データベースを作成
し、サンプル・コマンド・ファイルをコピーします。
dbaccessdemo5 dbname
dbaccessdemo5 スクリプトを実行すると、カレント・ディレクトリー内に
dbname.dbs と呼ばれるサブディレクトリーが作成され、そこに stores5 と関
連付けられたデータベース・ファイルが配置されます。データとインデッ
クスのファイルの両方は、dbname.dbs ディレクトリーにあります。
データベースおよびユーザーのディレクトリーにコピーされたコマンド・
ファイルを使用するには、dbaccessdemo5 スクリプトの実行元であるディ
レクトリーのパス名にある各ディレクトリー用に、UNIX 読込み権限および
実行権限を持つ必要があります。他のユーザーに、自分のディレクトリー
内のコマンド・ファイルにアクセスする許可を与えるには、UNIX chmod コ
マンドを使用します。オペレーティング・システム・ファイルおよびディ
レクトリー権限の詳細については、システム管理者にお問い合わせくださ
い。UNIX 権限については、IBM Informix SE Administrator’s Guide に記載され
ています。
作成したデータベースへのアクセスを他のユーザーに与えるには、
DB-Access で GRANT 文を使用して、適切なアクセス権を付与します。アク
セス権を削除するには、REVOKE 文を使用します。GRANT 文および
REVOKE 文は、IBM Informix SQL リファレンス・ガイド に記載されています。
8 序
Bookname
February 6, 2003 3:24 pm
IBM Informix サーバー製品 バージョン 5.x の新機能
IBM Informix サーバー製品 バージョン 5.x の新機能
このセクションでは、IBM Informix サーバー製品のバージョン 5.x に実装さ
れた主な新機能について説明します。
• 拡張接続 (IBM Informix OnLine のみ )
バージョン 5.2 の IBM Informix OnLine データベース・サーバーを使用す
ると、サーバーとクライアントの両方が同じマシンにインストールされ
ている場合に、バージョン 7.x クライアント・アプリケーション・ツー
ルに接続できます。
• チャンク・オフセット用の拡張サポート (IBM Informix OnLine のみ )
バージョン 5.2 の IBM Informix OnLine データベース・サーバーは、2 テ
ラバイトまでのチャンク・オフセット値をサポートします。
• 参照および実体整合性
新規データ整合性制約によって、作成時に表の主キー または外部キー
を表すように 1 つまたは複数の列を指定し、それらの表間で依存関係を
確立できます。一度指定されると、2 つの表間の親子関係がデータベー
ス・サーバーによって強制されます。その他の制約では、列にデフォル
ト値を指定し、挿入した値が合う必要がある列の条件を指定することが
できます。
• ストアード・プロシージャー
ストアード・プロシージャーは、SQL 文とストアード・プロシージャー
言語 (SPL) の組合せを使用して、ユーザーによって書き込まれた関数で
す。プロシージャーが一度作成されると、コンパイルされて最適化され
たフォームでデータベース内のオブジェクトとして格納され、適切なア
クセス権を持つその他のユーザーが使用できるようになります。クライ
アント / サーバー環境では、ストアード・プロシージャーの使用によっ
てネットワーク・トラフィックが大幅に削減される可能性があります。
• 動的 SQL
システム記述子領域を使用する動的 SQL の X/Open インプリメンテー
ション用のサポートが提供されます。このサポートには、既存の動的管
理文の構文における変更と共に、新規の SQL 文 ALLOCATE
DESCRIPTOR、DEALLOCATE DESCRIPTOR、GET DESCRIPTOR、および
SET DESCRIPTOR が含まれます。
• オプティマイザー機能強化
新規の SET OPTIMIZATION 文を使用して、データベース・サーバーに、
問合せ最適化の高レベルか低レベルかを選択するように指示できます。
デフォルトの高レベルでは、データベース・サーバーは、可能なすべて
の最適化ストラテジーのうちの最善のものを検証して選択します。この
序 9
Bookname
February 6, 2003 3:24 pm
ドキュメントの規則
レベルの最適化は、問合せによっては予想以上に最適化の時間がかかる
結果になるため、最適化レベルを低に設定するオプションがあります。
• リレー・モジュール (IBM Informix NET のみ )
IBM Informix NET のリレー・モジュール・コンポーネントは、
分散型データ処理環境のクライアント・マシン上に常駐し、relays メッ
セージは、アプリケーション開発支援ツールと IBM Informix OnLine また
は IBM Informix SE データベース・サーバーとの間でネットワーク・イ
ンターフェースを介して常駐します。リレー・モジュールによって、ク
ライアント上で IBM Informix データベース・サーバー処理を実行せず
に、バージョン 5.0 のアプリケーション開発ツールをリモート・データ
ベース・サーバーに接続することができます。
• 2 相コミット (IBM Informix STAR のみ )
新規の 2 相コミット・プロトコルによって、単一トランザクション内で
複数の OnLine データベース・サーバー上の複数のデータベース内の
データを取り扱うことができます。これにより、複数の OnLine データ
ベース・サーバーにわたるトランザクションが絶対的な基準でコミット
されることが保証されます。
• XA 環境のトランザクション処理のサポート
(IBM Informix TP/XA のみ )
IBM Informix TP/XA によって、IBM Informix OnLine データベース・サー
バーを、X/Open 仮仕様 (1990 年 4 月 )、分散トランザクション処理 : XA
インターフェースに準拠したリソース・マネージャー として使用する
ことができます。IBM Informix TP/XA User Manual では、X/Open 環境でトラ
ンザクションを管理する既存の SQL 文の動作における変更について説
明します。
ドキュメントの規則
本書は、ユーザーが IBM Informix OnLine をデータベース・サーバーとして
使用することを想定しています。IBM Informix SE に特有の機能と動作は、
本書全体にわたって記載されています。
10 序
Bookname
February 6, 2003 3:24 pm
ドキュメントの規則
文字の表記
IBM Informix 製品マニュアルでは、新規用語の紹介、画面表示の描写、コ
マンド構文の説明などのために標準セットの規則を使用します。次の文字
の表記が、本書を通じて使用されます。
規則
意味
KEYWORD
プログラム言語文 ( キーワード ) 内のすべての主エレメント
は、セリフ・フォントの大文字で表示されます。
イタリック体
イタリック体
テキスト内において、新規用語と強調された単語はイタリッ
ク体で表示されます。
< 可変値 >
構文とコードの例では、ユーザーが指定する可変値は、山形
かっこ (< >)で囲んで表示されます。
ボールド体
プログラム・エンティティーの名前 ( クラス、イベント、表な
ど )、環境変数、ファイルやパス名、およびインターフェー
ス・エレメント ( アイコン、メニュー項目、およびボタンな
ど ) がボールド体で表示されます。
ボールド体
モノスペース
モノスペース
製品によって表示される情報およびユーザーが入力した情報
は、モノスペース・タイプフェースで表示されます。
KEYSTROKE
ユーザーが押すキーは、大文字のサンセリフ・フォントで表
示されます。
®
このシンボルは、製品固有の情報またはプラットフォーム固
有の情報の終了を表します。
表ごとの固有 ID (UID) ( 主キー ) を表します。
文字を “ 入力 ” またはコマンドを “ 実行 ” するように指示するときは、入力の
後に即時に RETURN を押します。
テキストを “ 入力 ” または他のキーを “ 押す ”
ように指示するときは、RETURN を押す必要はありません。
構文の規則
構文図は、文の代替フォーム、文の必須またはオプションのパーツなどを
含む、SQL 文またはコマンドのフォーマットについて説明します。構文図
は、独自の規則を持ちます。このセクションでは、この規則を詳細に定義
し、説明します。SQL 文は、他のマニュアルに記載される文もありますが、
IBM Informix SQL リファレンス・ガイド にすべてリストされています。
序 11
Bookname
February 6, 2003 3:24 pm
ドキュメントの規則
それぞれの構文図は、文において有効な一連の必須およびオプションのエ
レメントを表示します。つまり、次のとおりです。
• すべてのキーワードは、大文字で入力する必要がなくても、識別しやす
いように大文字で表示されます。
• ユーザーが指定する必要がある語句は、山形かっこ (< >) で囲んで示さ
れます。
ダイアグラムは、キーワードを使用する左上から始まります。次に、縦線
が使用される右上で終了します。これらのポイント間で、停止またはバッ
クアップしない任意のパスをトレースできます。それぞれのパスは、文の
有効なフォームについて説明します。
パスに沿って次のエレメントが表示されます。
エレメント
説明
KEYWORD
表示されるとおりにそのまま入力します。ただし、入力
時は大文字も小文字も使用できます。
(.,;+*-/)
句読点と数学的表記は、表示されるとおりに入力する必
要があるリテラル記号です。
" "
二重引用符は、表示されるとおりに入力する必要がある
リテラル記号です。必要に応じて、二重引用符のペアを
一重引用符のペアに置き換えることもできます。二重引
用符と一重引用符を組み合わせることはできません。
< 変数 >
山形かっこ (< >) で囲まれた語句は、ユーザーが指定する
必要がある値を表します。値の種類は、値がボックスに
表示されていなければ、ダイアグラムの直後に説明され
ます。この場合、詳細説明のページ番号が変数名の後に
続きます。
ADD 節
関係演算子
SQLR を参照
12 序
Bookname
February 6, 2003 3:24 pm
ボックス内の表示は、同じページまたは別のページのサ
ブダイアグラムを表します。サブダイアグラムが、この
ポイントでメインのダイアグラムに接合されています。
別のマニュアルにおける SQLR への参照は、第 7 章 『構
文』で説明する SQL 文またはセグメントを表します。文
またはセグメントが、このポイントでメインのダイアグ
ラムに接合されています。
ドキュメントの規則
エレメント
I4GL
I4GL
説明
アイコン内のコードは、このパスが、ある製品用または
ある特定の条件の下でのみ有効であると警告するシグナ
ルです。コードは、パスをサポートする製品または条件
を示します。この場合、次のコードが使用されます。
SE
このパスは、IBM Informix SE にのみ有効です。
OL
このパスは、IBM Informix OnLine にのみ有効で
す。
STAR
STAR
このパスは、IBM Informix STAR にのみ有効で
す。
INET
STAR
このパスは、IBM Informix NET にのみ有効です。
I4GL
I4GL
このパスは、IBM Informix 4GL にのみ有効です。
ISQL
このパスは、IBM Informix SQL にのみ有効です。
ESQL
ESQL
このパスは、埋込み言語製品である
IBM Informix ESQL/C、または IBM Informix ESQL/
COBOL の SQL 文に有効です。
E/C
E/C
このパスは、IBM Informix ESQL/C にのみ有効で
す。
E/CO
E/C
このパスは、IBM Informix ESQL/COBOL にのみ有
効です。
DB
E/C
このパスは、DB-Access にのみ有効です。
SPL
STAR
このパスは、Informix ストアード・プロシー
ジャー言語 ( SPL) を使用している場合にのみ有
効です。
++
このパスは、ANSI 標準準拠 SQL の Informix の拡
張機能です。Informix の拡張機能検査を開始し
てこの構文ブランチを含める場合は、警告を受
け取ります。DBANSIWARN 環境変数を設定する
場合には、実行時に警告を受け取ります。コン
パイル時に警告を受け取るには、-ansi フラグを
使用してコンパイルしてください。
序 13
Bookname
February 6, 2003 3:24 pm
ドキュメントの規則
エレメント
説明
網掛けオプションはデフォルトです。このオプションを
明示的に入力しない場合でも、別のオプションを選択し
ない限り、これが有効になります。
ALL
矢印のペアで囲まれた構文は、サブダイアグラムである
ことを示します。
縦線は終端記号で、文の完了を示します。
メインの行の下の分岐は、オプションのパスを示します。
IN
NOT
,
ループは、パスが反復可能であることを示します。
< 変数 >
オプション内のゲート ( 1 ) は、大きなループ内でもそ
のオプションを 1 回しか使用できないことを示します。
1
列
キー
14 序
Bookname
February 6, 2003 3:24 pm
ドキュメントの規則
図 1 には、CREATE DATABASE 文の構文図のエレメントが示されています。
参照ボックス
終端記号
シグナル
CREATE DATABASE< データベース名 >
OL
キーワード
IN <DB 領域 >
変数
SE
SE ログ節
OL
OL ログ節
引用符
SE ログ節
WITH LOG IN "< パス名 >"
MODE ANSI
サブダイアグラム
OL ログ節
WITH
LOG
BUFFERED
LOG MODE ANSI
図 1
構文図のエレメント
このダイアグラムを使用して文を構築するには、キーワード CREATE
DATABASE で始まる左上から開始します。次に、右方向にダイアグラムを
読み、必要なオプションを使用して進みます。ダイアグラムには、次の情
報が含まれています。
1. CREATE DATABASE を入力する必要があります。
2. データベース名 を指定する必要があります。
3. 終端記号に向かって真っすぐ進んで停止します。または、1 つ以上のオ
プションのパスを取ることができます。
4. 必要であれば、IN と入力して、その後に DB 領域名を指定できます。
5. 必要な場合は、ロギングを指定できます。ここでは、作業しているデー
タベース・サーバーによって制約されます。
•
IBM Informix OnLine を使用している場合は、OL ログ節 という名前の
サブダイアグラムに移動します。キーワード WITH を入力し、次に、
LOG、BUFFEREDLOG、または LOG MODE ANSI のいずれかを選択し
序 15
Bookname
February 6, 2003 3:24 pm
ドキュメントの規則
て入力することによって、サブダイアグラムを進みます。最後に、
メインのダイアグラムに戻る矢印に従います。
•
IBM Informix SE を使用している場合は、SE ログ 節 という名前のサブ
ダイアグラムに移動します。キーワード WITHLOG IN を入力し、二
重引用符を入力し、パス名を指定して、引用符をクローズし、サブ
ダイアグラムを進みます。次に、行より下にある MODEANSI オプ
ションを選択するか、そのまま続けて行の反対側まで進みます。
6. メインのダイアグラムに戻ると、終端記号にたどり着きます。これで、
CREATE DATABASE 文は完了です。
サンプル・コードの規則
本書を通じて、SQL コードのサンプルが示されます。明記されている箇所
を除き、コードは単一の IBM Informix アプリケーション開発支援ツールに
特有ではありません。SQL 文のみがリストされる場合、これらはセミコロ
ン (;) では描かれません。特定の製品にこの SQL コードを使用する場合は、
その製品の構文ルールを適用する必要があります。例えば、DB-Access また
は IBM Informix SQL を使用している場合、文をセミコロン (;) を使用して描
く必要があります。埋め込み言語を使用している場合、EXEC SQL とセミコ
ロン ( または他の区切り記号 ) を、それぞれ各文の最初と最後に使用する必
要があります。
例えば、次のようなサンプル・コードがあります。
DATABASE stores
DELETE FROM customer
WHERE customer_num = 121
COMMIT WORK
CLOSE DATABASE
DB-Access または IBM Informix SQL を使用している場合は、セミコロン (;) を
各文の最後に追加します。IBM Informix 4GL を使用している場合は、表示さ
れるとおりにコードを使用します。IBM Informix ESQL/C を使用している場
合は、EXEC SQL またはドル記号 ($) を各行の最初に追加し、セミコロン (;)
で各行を終了します。特定のアプリケーション開発支援ツール用に SQL 文
を使用する詳しい説明については、ご使用の製品のマニュアルを参照して
ください。
16 序
Bookname
February 6, 2003 3:24 pm
関連マニュアル
また、サンプルにおけるピリオドは、フル・アプリケーションではそこに
コードが追加されることを示しますが、概念説明においては表示する必要
がないということに注意してください。
関連マニュアル
詳細については、次のタイプのマニュアルを参照してください。
• オンライン・マニュアル
• エラー・メッセージ・ファイル
• ドキュメント・ノート、リリース・ノート、およびマシン・ノート
オンライン・マニュアル
電子フォーマットのマニュアルが含まれた CD が、ご使用の IBM Informix 製
品に付属しています。このマニュアルは、インストールするか、または CD
から直接アクセスできます。オンライン・マニュアルのインストール、読
込み、および出力方法については、CD に付属のインストール説明書を参照
してください。また、同じオンライン・マニュアルは、IBM Informix オン
ライン・マニュアル・サイト (http://www-3.ibm.com/software/data/informix/
pubs/library/) からも入手できます。
「IBM Informix SQL チュートリアル・ガイド」を補足する多くの関連ドキュメ
ントも参照することができます。
• チュートリアルの姉妹編「IBM Informix SQL リファレンス・ガイド 」では、
すべての IBM Informix アプリケーション開発ツールと共に提供されるデ
モンストレーション・データベースの構造と内容についての詳細な情報
を提供します。これは、システム・カタログの詳細を含み、設定しなけ
ればならない UNIX 環境変数について説明し、IBM Informix 製品によっ
てサポートされる列データ型を定義します。さらに、IBM Informix 製品
によってサポートされるすべての SQL 文が詳細に記載されています。ま
た、役に立つ用語を解説した用語集も含まれています。
序 17
Bookname
February 6, 2003 3:24 pm
関連マニュアル
• 読者、または IBM Informix 製品をインストールするユーザーは、
IBM Informix 製品を使用する前にこの製品が適切にセットアップされて
いることを、ご使用の特定リリース用の 「UNIX Products インストー
ル・ガイド」を参照して確かめるようにしてください。
• ネットワークを介して IBM Informix 製品を使用する場合、適切な
「IBM Informix NET and IBM Informix STAR インストールおよび構成のガイド」
も参照するようにしてください。
• 使用しているデータベース・サーバーによって、ユーザーまたはユー
ザーのシステム管理者は、「IBM Informix OnLine 管理者 ガイド 」または
「IBM Informix SE Administrator’s Guide」のいずれかを必要とする場合があ
ります。
• エラーが生じた場合は、「IBM Informix Error Messages」マニュアルで、そ
れらのエラーを番号で調べ、原因と解決策を見つけることができます。
または、この序章の後の『エラー・メッセージ・ファイル』のセクショ
ンで説明するオンライン・メッセージ・ファイルで、エラー・メッセー
ジを調べることもできます。
エラー・メッセージ・ファイル
IBM Informix ソフトウェア・プロダクトは、すべてのエラー・メッセージ
とそれらの修正処置が含まれる ASCII ファイルを提供します。これらのエ
ラー・メッセージの詳細については、IBM Informix オンライン・マニュア
ル・サイト (http://www-3.ibm.com/software/data/informix/pubs/library/) にある
「IBM Informix Error Messages」マニュアルを参照してください。
また、次の 2 つの方法で、ASCII エラー・メッセージ・ファイルから直接エ
ラー・メッセージにアクセスできます。
• finderr スクリプトを使用して、端末画面で 1 つまたは複数のエラー・
メッセージを表示する。
• rofferr スクリプトを使用して、1 つのエラー・メッセージまたは一連の
エラー・メッセージを出力する。
これらのスクリプトは、$INFORMIXDIR/bin ディレクトリーにあります。
ASCII ファイルは、次のパスにあります。
$INFORMIXDIR/msg/errmsg.txt
エラー・メッセージ番号は、-1 から -33000 までの範囲です。これらの番号
を finderr スクリプトまたは rofferr スクリプト用に指定すると、負符号 (-)
を省略できます。正の数を持つメッセージは少ししかありません。これら
のメッセージは、アプリケーション開発支援ツール内でのみ使用されます。
その場合、メッセージ番号の先頭に正符号 (+) を付ける必要があります。
18 序
Bookname
February 6, 2003 3:24 pm
関連マニュアル
-1 から -100 までの番号のメッセージは、プラットフォーム依存型の可能性
があります。この範囲のメッセージのメッセージ・テキストが、使用して
いるプラットフォームに適用されない場合、オペレーティング・システム
のマニュアルをチェックして、メッセージ番号の正確な意味を調べてくだ
さい。
finderr スクリプト
finderr スクリプトを使用して、端末画面で 1 つまたは複数のエラー・メッ
セージとその修正処置を表示します。finderr スクリプトの構文は、次のと
おりです。
finderr
<msg_num>
+
<msg_num>
表示するエラー・メッセージの番号。
finderr コマンドごとにエラー・メッセージの任意の番号を指定できます。
finderr コマンドは、すべての指定されたメッセージおよびそれらの修正処
置を標準出力にコピーします。
例えば、エラー・メッセージ -359 を表示するには、次のコマンドを入力し
ます。
finderr -359
次の例で、エラー・メッセージのリストの指定方法について説明します。こ
の例でも、出力を UNIX more コマンドにパイピングして、表示を制御しま
す。また、出力を別のファイルにリダイレクトして、エラー・メッセージ
を保存または出力することもできます。
finderr 233 107 113 134 143 144 154 | more
序 19
Bookname
February 6, 2003 3:24 pm
関連マニュアル
rofferr スクリプト
rofferr スクリプトを使用して、1 つのエラー・メッセージまたは一連のエ
ラー・メッセージをフォーマットして出力します。デフォルトでは、rofferr は画面上に出力を表示します。その出力を、フォーマット設定コマン
ドを解釈するために nroff に送信し、プリンターに送信するか、または出力
が作動可能になるまで nroff 出力が格納されるファイルに送信する必要があ
ります。送信すると、そのファイルを出力できます。nroff の使用とファイ
ルの出力の詳細については、UNIX マニュアルを参照してください。
rofferr スクリプトの構文は、次のとおりです。
rofferr
<start_msg>
<end_msg>
+
+
<start_msg>
フォーマットする最初のエラー・メッセージの番号。この
エラー・メッセージ番号は必須です。
<end_msg>
フォーマットする最後のエラー・メッセージの番号。この
エラー・メッセージ番号はオプションです。end_msg を省
略する場合、start_msg のみがフォーマットされます。
次の例は、エラー・メッセージ -359 をフォーマットします。これは、
フォーマット済みのエラー・メッセージを nroff にパイピングして、nroff
の出力をデフォルト・プリンターに送信します。
rofferr 359 | nroff -man | lpr
次の例は、-1300 から -4999 までのすべてのエラー・メッセージをフォー
マットしてから出力します。
rofferr -1300 -4999 | nroff -man | lpr
20 序
Bookname
February 6, 2003 3:24 pm
業界標準準拠
ドキュメント・ノート、リリース・ノート、
マシン・ノート
マニュアルのセットに加えて、$INFORMIXDIR/release ディレクトリーに配
置されている次のオンライン・ファイルが、IBM Informix SQL チュートリア
ル・ガイド の情報を補足する場合があります。
Online ファイル
目的
SQLTDOC_5.txt
ドキュメント・ノート・ファイルでは、マニュアル
に記載されていない機能、および発行後に変更され
た 機能について説明します。
ENGREL_5.txt
リリース・ノート・ファイルでは、IBM Informix 製
品の以前のバージョンとの機能の違いと、それらの
違いが現行の製品に及ぼす影響について説明します。
このファイルには、既知の問題とそれらの解決法に
ついての情報も含まれています。
ONLINE_5.txt
マシン・ノート・ファイルでは、ユーザーのコン
ピューター上で IBM Informix 製品を構成して使用す
るために実行する必要がある特別なアクションにつ
いて説明します。マシン・ノートは、説明される製
品に応じて名前が付けられています。
これらのファイルにはアプリケーションとパフォーマンス上の問題につい
て重要な情報が含まれているため、必ず参照してください。
多くの IBM Informix 製品でも、各メニュー・オプションを使用して説明す
るオンライン・ヘルプ・ファイルが提供されています。ヘルプ機能は、
IBM Informix 製品のどの過程においても、CTRL-W を押すだけで起動できま
す。
業界標準準拠 米国規格協会 (ANSI) は、SQL 用の業界標準のセットを確立しました。
IBM Informix SQL 系製品は、ISO 9075:1992 と同一である、SQL-92 エント
リー・レベル (ANSI X3.135-1992 として発行 ) に完全準拠しています。さら
に、Informix データベース・サーバーの多くの機能が、SQL-92 中間および
全レベル、および X/Open SQL CAE ( 共通アプリケーション環境 ) 標準に対
応しています。
序 21
Bookname
February 6, 2003 3:24 pm
資料・製品についてのご意見
資料・製品についてのご意見
本マニュアルに関するご意見やご感想は、次の URL からお送りください。
今後の参考にさせていただきます。
http://www.ibm.com/jp/manuals/main/mail.html
製品に関する情報などについては、日本アイ・ビー・エムの担当者に
ご連絡ください。
22 序
Bookname
February 6, 2003 3:24 pm
1 データベースの基本
0
第
データベースの基本
概要 3
データベース : 概要および価値 3
データ・モデル 3
データの格納 6
データの問合せ 6
データの修正 8
並行使用 9
集中管理 11
グループ・データベースおよびプライベート・
データベース 11
基本的なデータベース 12
重要なデータベース用語 12
関係モデル 12
表 13
列 13
行 13
表、行、列 14
表の操作 14
構造化問合せ言語 (SQL) 15
標準 SQL 16
InformixSQL および ANSI SQL 16
ANSI 準拠データベース 17
データベース・ソフトウェア 17
データベース・サーバー 17
アプリケーション 18
対話型 SQL 18
レポートおよびフォーム 18
1
章
一般的なプログラミング 19
アプリケーションおよびデータベース・サーバー 19
サマリー 20
1-2 データベースの基本
Bookname
February 6, 2003 3:24 pm
1 データベースの基本
0
本章の概要
本章では、データベースの基本的な概念、およびこのマニュアル全体で使
用される用語の一部の定義について説明します。また、主に次のトピック
について説明します。
•
•
•
•
データベースとファイルの集合との違い
データベースの主なコンポーネントを示すために使用される用語
データベースの作成、問合せ、および修正に使用される言語
データベースを管理するソフトウェアの主なパーツ、およびこれらの
パーツの連携
データベース : 概要および価値
データベースは情報の集合 であり、単純なコンピューター・ファイルで
す。データベースが他と異なる理由は何でしょうか。データベースとその
他のファイルには、いくつかの違いがあります。特に違いがない場合、
ユーザーは、データベースに資金、労力、コンピューター処理時間をつぎ
込むことはありません。基本的な違いは 2 つあります。まず、データベー
スには、データだけではなくプラン、つまりデータのモデル も含まれてい
ます。また、データベースは、多くのユーザーが並行使用する共通資源で
もあります。
データ・モデル
データベースに集められた情報とファイル内の情報の主な違いとしては、
主にデータの編成方法が異なっている点を挙げることができます。ファイ
ルは物理的に編成されています。ファイルは、特定の項目が他の項目より
先または後に配置されています。ただし、データベースは、データ・モデ
ル に従って編成されます。データ・モデルとは、データ単位を定義し、各
単位間の相互関係を指定するプラン ( マップ ) のことです。
データベースの基本 1-3
データベース : 概要および価値
例えば、ファイルまたはデータベースに数値が格納される場合があります。
ファイルでは、数値はファイル内の特定の場所に現れる単なる数字です。
一方、データベースでは、数値にはデータ・モデルによって役割が割り当
てられています。例えば、数値は、顧客 から注文を受けて販売された品目
の製品 に付けられた価格 になります。これらの各項目 ( カスタマー、注
文、品目、製品、価格 ) には、データ・モデルによって指定された役割が
あります ( 図 1-1 を参照 )。
データ・モデルは、データベースを作成するときに設計されます。次に、
モデル内のプランに従って、データ単位が挿入されます。いくつかのマ
ニュアルでは、データ・モデル の代わりにスキーマ という用語が使用され
ています。
1-4 データベースの基本
Bookname
February 6, 2003 3:24 pm
データベース : 概要および価値
1015 06/27/91 1 case baseball gloves 450.00
1014 06/25/91 1 case footballs
960.00
1013 06/22/91 1 each tennis racquet 19.80
1012 06/18/91 1 case volleyballs 840.00
1011 06/18/91 5 each tennis racquet 99.00
1010 06/17/91 1 case tennis balls
36.00
ORDERS
order
1003
10/12/91
order
1001
01/20/91
customer
Anthony Higgins
item
tennis
racquet
order
1013
09/01/91
19.80
item
2
volleyball
nets
図 1-1
order
1011
03/23/91
item
1 case
tennis
balls
データ・モデルの図
データベースの基本 1-5
Bookname
February 6, 2003 3:24 pm
データベース : 概要および価値
データの格納
データベースとファイルでは、データベースの構成がデータベースに保管
される点も異なります。
ファイルは内部構造が複雑な場合がありますが、構成の定義はファイル内
には保管されません。構成の定義は、ファイルを作成または使用するプロ
グラム内に保管されます。例えば、ワード処理プログラムによって保管さ
れるドキュメント・ファイルには、ドキュメントのフォーマットが記述さ
れている詳細な構造が格納される場合があります。ただし、この構造は
ファイル内ではなくワード処理プログラム内で定義されているため、ファ
イルの概念を解読できるのはワード処理プログラムのみです。
一方、データ・モデルは、データ・モデルによって記述されるデータベー
ス内に格納されます。データ・モデルは、データベースと共に移動し、
データベースを使用するどのプログラムでも使用することができます。
データ・モデルでは、データ項目の名前だけでなくデータ型も定義される
ため、プログラムは、データベースに自動的に適合することができます。
例えば、プログラムでは、現在のデータベース内にある価格 項目が 8 桁の
10 進数で、小数点以下が 2 桁であることが検出されます。次に、プログラ
ムでは、この型の数値用に格納領域が割り当てられます。プログラムと
データベースの連動方法については、このマニュアルの第 6 章および第 7
章で説明します。
データの問合せ
データベースとファイルでは、問合せ方法も異なります。ファイルでは、
順に検索して、各レコードの特定の物理位置にある特定の値を参照できま
す。ファイルに対しては、“ 各レコードの 5 番目のフィールドの数値が 20
未満であるレコード ” を問い合わせることができます。図 1-2 に、このタ
イプの検索を示します。
1-6 データベースの基本
Bookname
February 6, 2003 3:24 pm
データベース : 概要および価値
1015 06/27/91 1 case baseball
t 19.80450.00
uegloves
nis racq
n
te
1014 06/25/91
1
case
footballs
6.00
h
c
s 3960.00
1 ea
nnis ball
6/22/91
te
0
8.00
e
3
4
s
1
a
0
c
1
balls
/91 1
is
2
n
/2
n
6
te
0
13
ase
10121006/18/91
1 casecvolleyballs
840.00
2/91 1
13 06/2
0
1
1011 06/18/91 5 each tennis racquet 99.00
1010 06/17/91 1 case tennis balls
36.00
ORDERS
図 1-2
ファイルの順次検索
一方で、データベースに問い合わせる場合は、モデルによって定義された
用語を使用します。データベースに対しては、“ 第 2 四半期の出荷日 に、
ニュー・ジャージー州のカスタマー である Shimara Corporation から製品 に
対して行われた注文 ” などの問合せを行うことができます。図 1-3 に、こ
のタイプの問合せを示します。
ファイル内に格納されたデータを問い合わせる場合は、ファイルの物理的
な配置に関して問い合わせる必要があります。データベースに問い合わせ
る場合は、コンピューターの記憶域の難解な内容を無視して、データ・モ
デル自体が使用できる範囲内で、少なくとも現実の世界を反映した用語で
問合せを行うことができます。
このマニュアルの第 2 章および第 3 章では、問合せの作成に使用する言語
について説明します。第 8 章から第 11 章では、他のユーザーが問い合わせ
ることができる、正確で強固なデータ・モデルの設計方法について説明し
ます。
データベースの基本 1-7
Bookname
February 6, 2003 3:24 pm
データベース : 概要および価値
manufacturer
Shimara
order
1019
07/16/91
state
New Jersey
order
1016
06/29/91
customer
Cathy
O'Brian
customer
Bob
Shorter
order
1023
07/24/91
RUN:
Next
Restart
Exit
Display the next page of query results
stores5
---------new
demo------------Press CTRL-W for Help--------
1019
図 1-3
Bob Shorter
SHM
swim cap
07/16/91
データベースの問合せ
データの修正
データ・モデルを使用すると、データベースの内容を修正するときのエ
ラー発生確率が低くなります。“Presta や Schraeder などのメーカー の在庫
品 をすべて検索して、その価格 を 13% だけ上げる ” などのコマンドを使用
して、データベースに問い合わせることができます。このためには、デー
タの意味を反映する用語で変更を指定します。ファイル内にあるレコード
のフィールドの詳細を検討することに時間や労力を割く必要がなくなり、
エラーの確率が低くなります。
保管データを修正するために使用する文については、このマニュアルの第
5 章で説明します。
1-8 データベースの基本
Bookname
February 6, 2003 3:24 pm
データベース : 概要および価値
並行使用
データベースは、数多くのコンピューター・ユーザーの共通資源として使
用できます。複数のユーザーがデータベースに同時に問合せおよび修正を
行うことができます。データベース・サーバー ( すべてのデータベースの
内容を管理するプログラム ) では、問合せおよび修正は競合することなく
順に実行されます。
データベースをユーザーが同時に使用することには大きな利点があります
が、セキュリティーおよびプライバシーという新しい問題も生じます。
一部のデータベースはプライベートであり、個人が独自に使用するために
セットアップされています。特定のグループ間でのみ共有する必要がある
機密事項を格納するデータベースもあります。また、一般にアクセスでき
るデータベースもあります。
IBM Informix データベース・ソフトウェアでは、データベースの使用を制
御するための手段が提供されています ( 図 1-4 を参照 )。データベースを設
計する場合は、以下の機能を実行できます。
• データベースを完全にプライベートな状態に保つ。
• データベースの内容全体をすべてのユーザーまたは特定のユーザーに公
開する。
• 一部のユーザーに対して、表示できるデータを制限する。( 実際、ユー
ザー・グループごとにまったく別のデータを表示することができます )。
• 指定したユーザーに特定の項目の表示を許可し、その修正を禁止する。
• 指定したユーザーに新規データの追加を許可し、古いデータの修正を禁
止する。
• 指定したユーザーにすべての既存データ、または既存データ内の指定項
目の修正を許可する。
• 追加または修正されたデータがデータ・モデルに準拠していることを確
認する。
上記またはそれ以外の機能については、このマニュアルの第 11 章で説明し
ます。
データベースの基本 1-9
Bookname
February 6, 2003 3:24 pm
データベース : 概要および価値
;
;
Update TABLE C Only
Query TABLE A and
TABLE B only
TABLE A
Modify and Update
TABLES A and B only
TABLE C
TABLE B
;
;;;
;;
TABLE B,C
View Column 3, TABLE B and
Columns 1 and 2, TABLE C only
図 1-4
データベースの共有
1-10 データベースの基本
Bookname
February 6, 2003 3:24 pm
データベース : 概要および価値
集中管理
数多くのユーザーが使用するデータベースは価値が高いため、重要なビジ
ネス資産として保護する必要があります。これにより、アーカイブおよび
管理の 2 つの重要な問題が生じます。IBM Informix OnLine データベース・
サーバーによって、これらのタスクを中央で処理できるようになります。
データベースは、消失や損傷から保護する必要があります。ソフトウェア
およびハードウェアの障害、火災や洪水といった自然災害のリスクなど、
数多くの危険があります。重要なデータベースが消失すると、かなりの確
率で損害が発生します。損害が発生すると、消失したデータの再作成に費
用および労力が発生するだけでなく、データベース・ユーザーの生産時間
が奪われ、ユーザーが作業できない間に取引や信用が失われることがあり
ます。重要なデータベースを定期的にアーカイブする計画を立てることに
よって、これらの災害を回避したり、影響を緩和することができます。
数多くのユーザーが使用する大規模なデータベースは、管理および調整を
行う必要があります。システム・リソースの使用率をモニターし、データ
増加をグラフにし、障害を予測し、拡張計画を立てる担当者が必要となり
ます。ユーザーからアプリケーション・プログラムの問題が報告されるた
め、これらの問題を診断および修正する担当者も必要です。迅速に応答す
る必要がある場合は、システムのパフォーマンスを調査および分析し、応
答時間が遅い原因を見つける必要があります。
グループ・データベースおよびプライベート・データベース
一部の IBM Informix データベース・サーバーは、個人が専用に使用するか、
または小さなユーザー・グループ間で共有する比較的小規模なデータベー
スを管理するように設計されています。
これらのデータベース・サーバー (UNIX オペレーティング・システム用の
IBM Informix SE など ) では、ホスト・オペレーティング・システムで管理
されるファイル内にデータベースが格納されます。これらのデータベース
は、他のコンピューター・ファイルと連動するファイルのバックアップ手
順と同じ手順を使用してアーカイブすることができます。これらのデータ
ベースが使用されていない場合は、他のメディアにコピーすることができ
ます。ただし、この場合、データベースをアーカイブするときに、トラン
ザクション・ログ・ファイルを空にリセットする必要がある点が唯一異な
ります。( トランザクション・ログの使用方法については、第 7 章で説明し
ます。第 10 章には、アーカイブの詳細が記載されています )。
グループ・データベースおよびプライベート・データベースで発生するパ
フォーマンスの問題は、通常、特定の問合せ時間が長すぎることと関連し
ています。第 4 章では、問合せに時間がかかる理由について詳細に説明し
データベースの基本 1-11
Bookname
February 6, 2003 3:24 pm
重要なデータベース用語
ます。SELECT 文の機能、および問合せを開始する別の方法をすべて理解す
ると、( 第 2 章および第 3 章を参照 )、第 4 章の説明に従って、本来は非常に
時間がかかる問合せのパフォーマンスを改善することができます。
基本的なデータベース
IBM Informix OnLine データベース・サーバーは、高い信頼性、可用性、お
よびパフォーマンスを備えた大規模なデータベースを管理するために設計
されています。プライベート・データベースおよびグループ・データベー
スを十分にサポートし、組織が作業を正常に実行する場合に必要となる優
れたデータベース管理機能を備えています。
IBM Informix OnLine を使用すると、オペレーターは、データベースの使用
中にアーカイブのコピーを作成することができます。また、差分アーカイ
ブ機能 ( 修正されたデータのみをアーカイブする機能 ) も組み込まれてお
り、完全にコピーするためにはテープが何本も必要になる場合に役立ちま
す。
IBM Informix OnLine には、オペレーター ( または任意のユーザー ) がデータ
ベース・サーバー内の動作をモニターし、障害の発生時期を確認するため
に使用できる対話型のモニター・プログラムが組み込まれています。また、
ディスク記憶装置の使用を分析するためのユーティリティー・プログラム
も付属しています。
第 10 章では、メイン・トピックに必要な背景情報である IBM Informix
OnLine ディスク記憶方式の概要について説明します。ただし、IBM Informix
OnLine の使用方法および管理方法の詳細については、
「IBM Informix OnLine
管理者ガイド」で説明します。
重要なデータベース用語
次の章に進む前に、2 組の用語について理解する必要があります。1 組は
データベースおよびデータ・モデルに関する用語であり、もう 1 組はデー
タベースを管理するコンピューター・プログラムに関する用語です。
関係モデル
IBM Informix データベースは、リレーショナル・データベースです。この
用語は、技術的には、IBM Informix データベースの元となるデータ・モデ
ルが E.F. Codd が考案した関係計算法に基づいていることを意味します。実
際は、すべてのデータは行 および列 で構成される表 形式で格納されます。
1-12 データベースの基本
Bookname
February 6, 2003 3:24 pm
重要なデータベース用語
表
データベースは 1 つ以上の表にまとめられた情報の集合です。表は、行お
よび列に編成されたデータ項目 の配列です。すべての IBM Informix 製品に
は、デモンストレーション・データベースが付属しています。図 1-5 に、
デモンストレーション・データベースの表を示します。
stock Table
stock_num
1
1
1
2
3
4
4
5
...
313
図 1-5
manu_code
HRO
HSK
SMT
HRO
HSK
HSK
HRO
NRG
....
ANZ
description
baseball gloves
baseball gloves
baseball gloves
baseball
baseball bat
football
football
tennis racquet
.........
swim cap
unit_price
250.00
800.00
450.00
126.00
240.00
960.00
480.00
28.00
...
60.00
unit
case
case
case
case
case
case
case
each
...
box
unit_descr
10 gloves/case
10 gloves/case
10 gloves/case
24/case
12/case
24/case
24/case
each
......
12/box
すべての IBM Informix 製品に付属している
デモンストレーション・データベースの stock 表
表には、1 つのエンティティー ( データベースが記述する特定のタイプの内
容 ) に関するすべての情報が表示されます。サンプルの stock 表には、ある
スポーツ用品店の在庫商品に関するすべての情報が表示されています。デ
モンストレーション・データベース内のその他の表には、カスタマーや注
文などのエンティティーが表示されます。
データベースは表の集合です。データベースを作成するということは、す
なわち表集合を作成することです。表に対して問合せまたは修正を行う権
利は表単位で制御できるため、表を表示または修正できるユーザーとでき
ないユーザーがいます。
列
表の各列は、1 つの属性、つまり 1 つの特性、特長、または表の主題に関し
て真であるファクトを表します。stock 表には、在庫番号、製造コード、説
明、価格、および測定単位などの項目を表す列があります。
行
表の各行は、表の主題のインスタンス ( エンティティーに関する特定の個
別の例 ) を表します。stock 表の各行は、スポーツ用品店で販売される品物
の特定の項目を表します。
データベースの基本 1-13
Bookname
February 6, 2003 3:24 pm
重要なデータベース用語
表、行、列
データの関係モデルでは、次に示す単純な対応関係を使用して、現実の世
界を反映するデータを簡単に編成することができます。
表 = エンティティー 表は、特定の主題または特定の種類の項目に関して
データベースに格納されている情報をすべて表しま
す。
列 = 属性
列は、特定の特長、特性、表の主題に関して真であ
るファクトを表します。
行 = インスタンス
行は、表の主題の各インスタンスを表します。
エンティティーおよび属性の選択方法にはいくつかのルールがありますが、
これらの規則は、データベースを新規に作成する場合にのみ重要となりま
す ( データベースの設計については、このマニュアルの第 8 章~第 11 章で
説明します )。既存のデータベースでは、データ・モデルがすでに設定され
ています。データベースを使用するには、表と列の名前、およびこれらと
現実の世界との対応関係を理解することが必要となります。
表の操作
データベースは表の集合であるため、データベースを操作することは、表
を操作することを意味します。関係モデルでは 3 つの基本的な操作がサ
ポートされていますが、そのうちの 2 つについては、図 1-6 に示します
( これらの操作については、すべてこのマニュアルの第 2 章および 第 3 章
で、多数の例を挙げて詳細に定義されています )。
表から選択 することは、他の行をそのまま残して特定の行を選択すること
を意味します。例えば、stock 表に対して、“ 製造コードが HRO、単価が
100.00 ~ 200.00 であるすべての行を選択 ” することができます。
表から射影 することは、他の列をそのまま残して特定の行を選択すること
を意味します。例えば、stock 表に対して、“stock_num、unit_descr、およ
び unit_price 列のみを表示 ” するように射影することができます。
表には 1 つのエンティティーに関する情報のみが格納されています。複数
のエンティティーに関する情報が必要な場合は、表を結合 する必要があり
ます。表はさまざまな方法で結合することができます ( 結合操作について
は、このマニュアルの第 3 章で説明します )。
1-14 データベースの基本
Bookname
February 6, 2003 3:24 pm
構造化問合せ言語 (SQL)
stock Table
stock_num
1
1
1
2
3
4
4
5
manu_code
HRO
HSK
SMT
HRO
HSK
HSK
HRO
NRG
description
baseball gloves
baseball gloves
baseball gloves
baseball
baseball bat
football
football
tennis racquet
射影
図 1-6
unit_price
250.00
800.00
450.00
126.00
240.00
960.00
480.00
28.00
射影
unit
case
case
case
case
case
case
case
each
unit_descr
10 gloves/case
10 gloves/case
10 gloves/case
24/case
12/case
24/case
24/case
each
選択
射影
選択および射影
構造化問合せ言語 (SQL)
コンピューター・ソフトウェアには、“ 第 2 四半期に出荷日を指定して
ニュー・ジャージー州のカスタマーから行われた注文 ” のように、実際の言
葉でデータベースに問い合わせることができる機能が備わっていません。
ユーザーは、ソフトウェアが容易に構文解析できる制限付きの構文を使用
して、質問を表現する必要があります。次の用語を使用して、デモンスト
レーション・データベースに同じ問合せを行うことができます。
SELECT * FROM customer, orders
WHERE customer.customer_num = orders.customer_num
AND customer.state = "NJ"
AND orders.ship_date
BETWEEN DATE("7/1/91") AND DATE("7/30/91")
この問合せは、構造化問合せ言語 (SQL) の例です。SQL とは、データベー
スに関するすべての操作を指示するために使用する言語です。SQL は文で
構成され、各文は、機能を指定する 1 つ以上のキーワードで開始します。
SQL には、ALLOCATE DESCRIPTOR から WHENEVER まで、67 個の文があり
ます。
データベースの基本 1-15
Bookname
February 6, 2003 3:24 pm
構造化問合せ言語 (SQL)
すべての SQL 文の詳細については、「IBM Informix SQL リファレンス・ガイド」
を参照してください。ほとんどの文は、データベースのセットアップまた
は調整中は、頻繁には使用しません。— 通常、使用する文は多くても 3 ~ 4
つです。
SELECT 文は、ほとんどの場合に使用します。この文は、データベースから
データを検索できる唯一の文です。また、この文は最も複雑な文であるた
め、このマニュアルの次の 2 つの章で、使用方法について詳細に説明しま
す。
標準 SQL
SQL および関係モデルは、1970 年代のはじめから半ばにかけて、IBM で発
明および開発されました。IBM によって、実用的なリレーショナル・デー
タベースの実装が可能であること、および SQL がこれらを制御できる便利
な言語であることが証明されてから、他のベンダーが IBM 以外のコン
ピューターを対象とした類似製品の提供を開始しました。
パフォーマンスや競争力を高め、またはローカルなハードウェアやソフト
ウェア機能を使用するために実装されるこれらの SQL は、インプリメン
テーションごとに異なっており、IBM バージョンの言語と微妙に異なって
います。この違いが大きくならないように、1980 年代はじめに標準化委員
会が設立されました。
米国規格協会 (ANSI) がスポンサーである委員会 X3H2 は、1986 年に SQL1 規
格を発行しました。この規格では、SQL 機能のコア・セット、および
SELECT などの文の構文が定義されています。
Informix SQL および ANSI SQL
IBM Informix 製品でサポートされている SQL バージョンには、SQL との優
れた互換性があります (IBM バージョンの言語とも互換性があります )。た
だし、標準に対して拡張機能 が装備されているため、特定の文に対するオ
プションまたは機能、およびその他の広範なルールが追加されています。
多くの場合、この違いは、通常使用しない文に対して発生します。例えば、
通常使用する SQL の 90% を占める SELECT 文には、ほとんど違いがありま
せん。
ただし、拡張機能が存在するため、矛盾が発生します。Informix の数多く
のカスタマーは、プログラム内に Informix スタイルの SQL および保管照会
文を埋め込んでいます。これらのカスタマーは、言語が常に同じであるこ
とを要求します。また、ANSI 標準に完全に準拠する方法でデータベースを
使用する機能が必要なカスタマーもあります。これらのカスタマーは、標
準に準拠するよう言語を変更することを要求します。
1-16 データベースの基本
Bookname
February 6, 2003 3:24 pm
データベース・ソフトウェア
Informix では、このような矛盾が次の方法で解決されました。
• 標準に対する拡張機能を備えた SQL の Informix バージョンをデフォルト
で使用できる。
• InformixSQL 言語処理プログラムに対して、SQL の使用をチェックし、
Informix の拡張機能が使用されている場合は常に警告フラグを立てるよ
うに要求できる。
この解決方法は適切ですが、SQL マニュアルがより複雑になります。Informix と ANSISQL が異なる場合は、
「IBM Informix SQL リファレンス・ガイド」に
両方の説明が記載されています。通常、ユーザーが使用するバージョンは
1 つであるため、不要なバージョンは無視する必要があります。
ANSI 準拠データベース
データベースを ANSI 準拠として指定するには、作成時に MODE ANSI キー
ワードを使用します。このようなデータベースには、ANSI 標準の特定の特
性を適用することができます。例えば、データを自動変更するすべてのア
クションはトランザクション内で発生するため、変更は完全に実行される
か、またはまったく実行されないかのいずれかとなります。ANSI 準拠デー
タベース間の違いは、
「IBM Informix SQL リファレンス・ガイド」に記載され
ています。
データベース・ソフトウェア
データベースにアクセスするには、2 つの高度なソフトウェア層を使用す
る必要があります。上位層で直接作業すると、上位層では、下位層を使用
してデータにアクセスできます。両方の層に指示するには、構造化照会言
語を使用します。
データベース・サーバー
データベース・サーバー は、ディスク内に格納されているデータベースの
内容を管理するプログラムです。データベース・サーバーは、物理的なコ
ンピューター・ストレージ内での表、行、列の実際の編成方法を認識しま
す。データベース・サーバーは、すべての SQL コマンドを解釈および実行
します。
データベースの基本 1-17
Bookname
February 6, 2003 3:24 pm
データベース・ソフトウェア
アプリケーション
単純なアプリケーション であるデータベース・アプリケーション は、デー
タベースを使用するプログラムです。このアプリケーションでは、データ
ベース・サーバーが呼び出されてデータベースが使用されます。機能は非
常に単純で、このアプリケーションによって SQL コマンドがデータベー
ス・サーバーに送信されると、データベース・サーバーからアプリケー
ションにデータ行が戻されます。その後、アプリケーションによって、戻
されたデータ行が表示されます。
また、データベース・アプリケーションに対して、データベースに新規
データを追加するように指示することもできます。データベース・アプリ
ケーションでは、行を挿入する SQL コマンドに新規データが組み込まれ、
このコマンドがデータベース・サーバーに渡されて実行されます。
データベース・アプリケーションには、いくつかのタイプがあります。
SQL を使用して対話式にデータベースにアクセスできるアプリケーション、
およびその使用方法に応じて、格納されたデータをさまざまなフォームで
表示して使用できるアプリケーションがあります。
対話型 SQL
このマニュアルの例を実行したり、SQL および独自のデータベース設計を
実験するには、SQL 文を対話式に実行できるプログラムが必要です。
DB-Access および IBM Informix SQL は、これらのプログラムに該当します。
これらのプログラムを使用すると、SQL 文を構成してから、SQL をデータ
ベース・サーバーに渡して実行し、結果をユーザーに表示することができ
ます。
レポートおよびフォーム
目的のデータを正確に戻すための問合せを完了した後に、データをレポー
トまたはフォームとして端末画面に表示するには、フォーマットを行う必
要があります。ACE は、IBM Informix SQL のレポート生成プログラムです。
このプログラムには、データ行を戻す SELECT 文、およびレポートのペー
ジ・レイアウト方法を示すレポート仕様を設定します。ACE では、この情
報が、レポートを生成するときにいつでも実行できるプログラムにコンパ
イルされます。
PERFORM は、対話型スクリーン・フォームを生成する IBM Informix SQL
のモジュールです。データベースの表内の列に画面の表示フィールドを関
係付けるフォーム仕様を準備します。PERFORM では、この仕様が、いつ
でも実行できるプログラムにコンパイルされます。フォーム・プログラム
は、実行時に画面のデータ行を指定フォーマットで表示するようにデータ
1-18 データベースの基本
Bookname
February 6, 2003 3:24 pm
データベース・ソフトウェア
ベースに問合せを行います。ユーザーがサンプル値を入力したり、データ
ベースから戻された一致行を表示 (query-by-example 機能 ) できるように、
フォームを編成することができます。
この製品の詳細については、付属マニュアルを参照してください。
一般的なプログラミング
ユーザーが作成したプログラムを SQL 文に組み込み、データベース・サー
バーとの間でデータを交換することができます。これにより、データベー
スからデータを抽出したり、目的の方法でフォーマットするプログラムを
作成することができます。任意のソースのデータを任意のフォーマットで
抽出したり、データを準備したり、データをデータベースに挿入するプロ
グラムを作成することもできます。
この作業に最も便利なプログラミング言語は、データベース・アプリケー
ションの作成専用に設計された非プロシージャー型言語である
IBM Informix 4GL です。ただし、C および COBOL で作成されたプログラムか
ら、Informix データベース・サーバーと通信することもできます。
呼び出されたストアード・プロシージャーがデータベースのデータおよび
オブジェクトと連動するようなプログラムを作成することができます。作
成したストアード・プロシージャーは、データベースの表に直接格納され
ます。その後、DB-Access または埋め込み言語プログラムでストアード・プ
ロシージャーを実行することができます。
このマニュアルの第 6 章および第 7 章には、プログラム内での SQL の使用
方法の概要について記載されています。
アプリケーションおよびデータベース・サーバー
データベース内のデータを使用するすべてのプログラムは、同じ方法で動
作します。IBM Informix SQL のようにパッケージされたプログラム、ACE
によってコンパイルされたレポート・プログラム、IBM Informix 4GL または
埋め込まれた SQL を使用して作成されたプログラムなどには、プログラム
に関係なく、それぞれ同じ 2 つの層があります。
1. ユーザーと対話したり、データの準備やフォーマットを行ったり、SQL
文をセットアップするアプリケーション
2. データベースを管理し、SQL を解釈するデータベース・サーバー
すべてのアプリケーションはデータベース・サーバー上で集中的に実行さ
れ、ディスク上のデータベース・ファイルはデータベース・サーバーに
よってのみ操作されます。この概念を図 1-7 に示します。
データベースの基本 1-19
Bookname
February 6, 2003 3:24 pm
サマリー
図 1-7
データベース・サーバー上で集中的に実行されるアプリケーション
サマリー
データベースには一連の関連情報が格納されますが、データを格納する他
の方法とは基本的な方法が異なります。データベースには、データだけで
なく、各データ項目を定義したり、その意味を他の項目や現実の世界と対
比して指定するデータ・モデルが格納されます。
データベースは、並行作業する多数のコンピューター・ユーザーが使用す
ることも、修正することもできます。ユーザーごとに、データベースの内
容が異なるビューで表示され、これらの内容へのアクセスはさまざまな方
法で制限することができます。
1-20 データベースの基本
Bookname
February 6, 2003 3:24 pm
サマリー
組織の成功にとってデータベースは非常に重要であり、集中的に管理およ
びモニターする必要があります。IBM Informix OnLine データベース・サー
バーは、重要な アプリケーションの要求を満足させます。IBM Informix
OnLine と IBM Informix SE の両方で、プライベートまたはグループ用の小規
模データベースがサポートされています。
データベースの制御および問合せを行うには、IBM によって開発され、
ANSI によって標準化された構造化問合せ言語を使用します。通常は、ANSI
で定義された言語に Informix の拡張機能を追加して使用しますが、
IBM Informix ツールを使用すると、ANSI 標準に厳密に準拠させることもで
きます。
2 つのソフトウェア層では、データベースを使用するすべての作業が調停
されます。下位層はデータベース・サーバーであり、常に SQL 文が実行さ
れ、ディスク内およびコンピューター・メモリー内のデータが管理されま
す。上位層は、Informix のアプリケーション、ユーザーが独自に作成した
アプリケーション、他のベンダーや組織が提供するアプリケーションなど、
多数のアプリケーションのいずれかになります。
データベースの基本 1-21
Bookname
February 6, 2003 3:24 pm
2 単純な SELECT 文
0
単純な SELECT 文
概要 3
SELECT 文について 3
基本的な概念 4
アクセス権 4
関係演算 5
選択と射影 5
結合 9
本章の構成 11
SELECT 文のフォーム 11
特殊なデータ型 11
単一表 SELECT 文 12
すべての列と行の選択 12
アスタリスクの使用方法 12
列の再順序付け 13
行のソート 14
特定の列の選択 19
サブ文字列の選択 25
WHERE 節の使用方法 26
比較条件の作成 27
変数テキスト検索の使用方法 34
正確なテキスト比較の使用方法 35
単一文字ワイルドカードの使用方法 35
特殊文字の比較 39
式と導出値 41
算術式 41
導出列のソート 46
SELECT 文の関数の使用方法 47
集計関数 47
時刻関数 49
その他の関数とキーワード 55
第
2
章
複数表 SELECT 文 60
デカルト積の作成 60
結合の作成 62
等価結合 62
自然結合 65
複数表結合 68
問合せのショートカット 70
別名の使用方法 70
INTO TEMP 節 73
サマリー 74
2-2 単純な SELECT 文
Bookname
February 6, 2003 3:24 pm
概要
SELECT は、最も重要かつ複雑な SQL 文です。この文は、SQL 文 INSERT、
UPDATE、および DELETE と共にデータを操作するために使用します。
SELECT 文は、次の処理に使用します。
• 単独でデータベースからデータを抽出する。
• INSERT 文の一部として新規行を作成する。
• UPDATE 文の一部として情報を更新する。
SELECT 文は、データベース内の情報を問い合わせるための主要な方法で
す。この文は、プログラム、レポート、スクリーン・フォーム、またはス
プレッドシートのデータを抽出する場合に非常に重要です。
本章では、SELECT 文を使用して、リレーショナル・データベースからデー
タをさまざまな方法で問い合わせて抽出する方法について説明します。1
つまたは複数の表から列または行の情報を選択するために文を目的に合わ
せて構成する方法、SELECT 文に式と関数を含める方法、およびリレーショ
ナル・データベースの表間の様々な結合条件を作成する方法について説明
します。
SELECT 文について
SELECT 文は、リレーショナル・データベースのデータを表示するための節
で構成されています。これらの節を使用すると、1 つまたは複数のデータ
ベース表またはビューから列と行を選択し、1 つまたは複数の条件を指定
して、データの順序付けおよび要約を行い、選択したデータを一時表に格
納することができます。
本章では、SELECT 文の 5 つの節の使用方法について説明します。これらの
節は、SELECT 文に次の順序で含める必要があります。
1. SELECT 節
2. FROM 節
3. WHERE 節
単純な SELECT 文 2-3
SELECT 文について
4. ORDER BY 節
5. INTO TEMP 節
SELECT 節および FROM 節のみが必須です。これらの 2 つの節は、抽出する
表と列を指定し、すべてのデータベース問合せの基礎となります。
• 特定の行を選択したり、join 条件を作成する場合は、WHERE 節を追加
する。
• データを作成する順序を変更する場合は、ORDER BY 節を追加する。
• さらに問合せを行うために結果を表として保存する場合は、INTO TEMP
節を追加する。
SELECT 文の 2 つの節 GROUP BY および HAVING をさらに使用すると、より
複雑なデータ抽出を行うことができます。これらの節については、第 3 章
に記載されています。もう 1 つの節 INTO は、IBM Informix 4GL および
IBM Informix ESQL 製品において SELECT 文からデータを受け取るために、
プログラムまたはホスト変数を指定する場合に使用します。SELECT 文を使
用するための完全な構文およびルールについては、「 IBM Informix SQL リ
ファレンス・ガイド」の第 7 章に記載されています。
基本的な概念
SELECT 文は、INSERT、UPDATE、および DELETE 文とは異なり、データ
ベース内のデータを変更しません。SELECT 文は、データを問い合わせる
ために使用します。データを変更できるのは一度に 1 人のユーザーのみで
すが、データの問合せおよび選択は複数のユーザーが同時に行うことがで
きます。データを変更する文については、第 5 章に記載されています。
INSERT、UPDATE、DELETE 文については、
「IBM Informix SQL リファレン
ス・ガイド」の第 7 章に記載されています。
アクセス権
データの問合せを行う場合は、データベースに対する CONNECT アクセス
権およびデータベース内の表に対する SELECT アクセス権を持っている必
要があります。これらのアクセス権は、通常はすべてのユーザーに与えら
れます。データベース・アクセス権については、本書の 11-3 ページ『概
要』および「IBM Informix SQL リファレンス・ガイド」の第 7 章の GRANT 文
および REVOKE 文のセクションに記載されています。
リレーショナル・データベースでは、列 は、表の各行に表示される特定の
タイプの情報を含むデータ要素です。行 は、データベース表のすべての列
にわたる 1 つのエンティティーに関する情報の関連項目のグループです。
2-4 単純な SELECT 文
SELECT 文について
データベース表、システム・カタログ表、データベースに関する情報を含
むファイル、またはデータのカスタマイズされたセットを格納するために
作成された仮想表であるビュー から列と行を選択できます。システム・カ
タログ表およびビューについては、「IBM Informix SQL リファレンス・ガイ
ド」に記載されています。
関係演算
関係演算 では、1 つまたは複数の表または関係 を操作して、別の表を作成
します。3 種類の関係演算は、選択、射影、および結合です。本章では、選
択、射影、および簡単な結合の例を示します。
選択と射影
関係型の用語では、選択 は、特定の条件を満たす 1 つの表の水平方向の サ
ブセットの行を取得することと定義されます。このような SELECT 文は、
表のいくつかの行およびすべての列を戻します。選択は、SELECT 文の
WHERE 節を使用して実装されます。
SELECT * FROM customer
WHERE state = "NJ"
単純な SELECT 文 2-5
SELECT 文について
この問合せの結果には、customer 表と同じ数の列が含まれており、その行
のサブセットのみが含まれています ( 選択された列のデータは対話型エ
ディター画面の 1 行に収まらないため、データは水平方向ではなく垂直方
向に表示されます )。
2-6 単純な SELECT 文
customer_num
fname
lname
company
address1
address2
city
state
zipcode
phone
119
Bob
Shorter
The Triathletes Club
2405 Kings Highway
customer_num
fname
lname
company
address1
address2
city
state
zipcode
phone
122
Cathy
O’Brian
The Sporting Life
543 Nassau Street
Cherry Hill
NJ
08002
609-663-6079
Princeton
NJ
08540
609-342-0054
SELECT 文について
関係型の用語では、射影 は、一意な行を保持している 1 つの表の列から垂
直方向の サブセットを取得することと定義されます。このような SELECT
文は、表のいくつかの列およびすべての行を戻します。射影は、SELECT 文
の SELECT 節の選択リストを使用して実装されます。
SELECT UNIQUE city, state, zipcode
FROM customer
この問合せの結果には、customer 表と同じ数の列が含まれますが、その列
のサブセットのみが射影 されます。
city
state zipcode
Bartlesville
Blue Island
Brighton
Cherry Hill
Denver
Jacksonville
Los Altos
Menlo Park
Mountain View
Mountain View
Oakland
Palo Alto
Palo Alto
Phoenix
Phoenix
Princeton
Redwood City
Redwood City
Redwood City
San Francisco
Sunnyvale
Sunnyvale
Wilmington
OK
NY
MA
NJ
CO
FL
CA
CA
CA
CA
CA
CA
CA
AZ
AZ
NJ
CA
CA
CA
CA
CA
CA
DE
74006
60406
02135
08002
80219
32256
94022
94025
94040
94063
94609
94303
94304
85008
85016
08540
94026
94062
94063
94117
94085
94086
19898
単純な SELECT 文 2-7
SELECT 文について
最も一般的な SELECT 文では選択と射影の両方が使用されます。この種類
の問合せは、表のいくつかの行と列を戻します。
SELECT UNIQUE city, state, zipcode
FROM customer
WHERE state = "NJ"
この問合せの結果には、customer 表の行のサブセットと列のサブセットが
含まれています。
2-8 単純な SELECT 文
city
state zipcode
Cherry Hill
Princeton
NJ
NJ
08002
08540
SELECT 文について
結合
複数の表が共通の 1 つまたは複数の列によって結合される場合に結合が行
われ、結果の新規表が作成されます。図 12-1 に、items および stock 表の
サブセットを使用して結合の概念を示します。
SELECT unique item_num, order_num, stock_num, description
FROM items, stock
WHERE items.stock_num = stock.stock_num
items 表 ( 例 )
item_num
order_num
stock 表 ( 例 )
stock_num manu_code
stock_num
description
1
1001
1
1
HRO
野球グローブ
1
1002
4
1
HSK
野球グローブ
2
1002
3
2
HRO
野球
3
1003
5
4
HSK
フットボール
1
1005
5
5
NRG
テニス・ラケット
item_num
order_num
stock_num
description
1
1001
1
野球グローブ
1
1002
4
フットボール
3
1003
5
テニス・ラケット
1
1005
5
テニス・ラケット
図 12-1
2 つの表の結合の例
単純な SELECT 文 2-9
SELECT 文について
次の SELECT 文は、customer 表と state 表を結合します。
SELECT UNIQUE city, state, zipcode, sname
FROM customer, state
WHERE customer.state = state.code
この問合せの結果は、customer 表および state 表の指定された行と列で構成
されています。
2-10 単純な SELECT 文
city
state zipcode sname
Bartlesville
Blue Island
Brighton
Cherry Hill
Denver
Jacksonville
Los Altos
Menlo Park
Mountain View
Mountain View
Oakland
Palo Alto
Palo Alto
Phoenix
Phoenix
Princeton
Redwood City
Redwood City
Redwood City
San Francisco
Sunnyvale
Sunnyvale
Wilmington
OK
NY
MA
NJ
CO
FL
CA
CA
CA
CA
CA
CA
CA
AZ
AZ
NJ
CA
CA
CA
CA
CA
CA
DE
74006
60406
02135
08002
80219
32256
94022
94025
94040
94063
94609
94303
94304
85008
85016
08540
94026
94062
94063
94117
94085
94086
19898
Oklahoma
New York
Massachusetts
New Jersey
Colorado
Florida
California
California
California
California
California
California
California
Arizona
Arizona
New Jersey
California
California
California
California
California
California
Delaware
SELECT 文について
本章の構成
本章では、リレーショナル・データベースからデータを抽出する基本的な
方法について説明します。副問合せ、外部結合、和など、SELECT 文のさら
に複雑な使用方法については、次の章で説明します。
本章に示すほとんどの例は、IBM Informix アプリケーション開発支援ツール
用のソフトウェアを使用してインストールされる stores5 デモンストレー
ション・データベースの 9 つの表から採用したものです。簡略化のため、
これらの例には各 SELECT 文で抽出されるデータの一部のみを示している
場合があります。stores5 データベースの構造および内容については、
「IBM Informix SQL リファレンス・ガイド」を参照してください。SQL では大
文字と小文字は区別されませんが、例の中では、キーワードは強調のため
に大文字で示されています。
SELECT 文のフォーム
構文はすべての IBM Informix 製品で同じですが、SELECT 文のフォーム、お
よび結果出力の位置とフォーマットは、アプリケーションによって異なり
ます。本章および第 3 章の例に、DB-Access または IBM Informix SQL の対話
型問合せ言語オプションを使用する場合に表示される、SELECT 文およびそ
の出力を示します。また、SELECT 文を使用すると、IBM Informix SQL レ
ポートによって非対話式にデータを問い合わせたり、IBM Informix ESQL/C
(SELECT 文は実行可能コードとして取り扱われる ) などの言語にこれらの
SELECT 文を埋め込んだり、第 4 世代言語の一部として IBM Informix 4GL に
組み込むこともできます。
特殊なデータ型
例では IBM Informix OnLine データベース・サーバーを使用しており、デー
タベース・アプリケーションは 可変長文字 (VARCHAR) 型、テキスト (TEXT)
型、および バイト (BYTE) 型を含めることができます。これらのデータ型は、
IBM Informix SE で実行されるアプリケーションでは使用できません。
DB-Access または IBM Informix SQL 対話型エディターでは、これらの 3 つの
データ型のいずれかを含む SELECT 文を出した場合、問合せの結果の表示
が異なります。
•
可変長文字 (VARCHAR) 型列について問合せを実行すると、可変長文字
(VARCHAR) 型値全体が文字 (CHARACTER) 型値と同じように表示される。
•
テキスト (TEXT) 型列を選択すると、テキスト (TEXT) 型列の内容が表示さ
れ、その内容をスクロールできる。
•
バイト (BYTE) 型列について問合せを実行すると、実際の値ではなく
<BYTE value> が表示される。
単純な SELECT 文 2-11
単一表 SELECT 文
可変長文字 (VARCHAR) 型、テキスト (TEXT) 型、およびバイト (BYTE) 型 の相違
点については、必要に応じて本章で説明します。これらのデータ型および
その他のデータ型については、本書の第 9 章を参照してください。また、
「IBM Informix SQL リファレンス・ガイド」も参照してください。
単一表 SELECT 文
データベース内の単一表に対して問合せを行うには、さまざまな方法があ
ります。SELECT 文を目的に合わせて構成すると、次の処理を行うことがで
きます。
•
•
•
•
すべての列または特定の列を抽出する。
すべての行または特定の行を抽出する。
抽出したデータに対して計算または他の関数を実行する。
さまざまな方法でデータを順序付ける。
すべての列と行の選択
最も基本的な SELECT 文には、2 つの必須の節である SELECT 節と FROM 節
のみを含まれています。
アスタリスクの使用方法
次の文は、選択リスト の manufact 表のすべての列を指定します。選択リ
ストは、表から射影する列名または式のリストです。
SELECT manu_code, manu_name, lead_time
FROM manufact
次の文は、選択リストの省略形として ワイルドカード * を使用していま
す。アスタリスクは、表のすべての列の名前を表します。定義された順に
すべての列を選択する場合、アスタリスクを使用できます。
SELECT * FROM manufact
2-12 単純な SELECT 文
単一表 SELECT 文
2 つの例は同等であり、同じ結果が表示されます。つまり、manufact 表の
すべての列と行のリストは同じになります。結果は、DB-Access または
IBM Informix SQL 対話型エディターで表示される場合と同じように表示され
ます。
manu_code manu_name
SMT
ANZ
NRG
HSK
HRO
SHM
KAR
NKL
PRC
lead_time
Smith
Anza
Norge
Husky
Hero
Shimara
Karsten
Nikolus
ProCycle
3
5
7
5
4
30
21
8
9
列の再順序付け
選択リスト内の列の順序を変更することによって、列をリストする順序を
変更することができます。
SELECT manu_name, manu_code, lead_time
FROM manufact
この選択リストには、前の選択リストと同じ列が含まれていますが、列が
異なる順序で指定されているため、表示が異なります。
manu_name
Smith
Anza
Norge
Husky
Hero
Shimara
Karsten
Nikolus
ProCycle
manu_code lead_time
SMT
ANZ
NRG
HSK
HRO
SHM
KAR
NKL
PRC
3
5
7
5
4
30
21
8
9
単純な SELECT 文 2-13
単一表 SELECT 文
行のソート
SELECT 文に ORDER BY 節を追加することによって、特定の順序でデータを
ソートするようにシステムに指示することができます。ORDER BY 節に使
用する列は、明示的または暗黙的に選択リストに含める必要があります。
明示的な 選択リストは、すべての列名を含みます。
SELECT manu_code, manu_name, lead_time
FROM manufact
ORDER BY lead_time
暗黙的な 選択リストは、* 記号を使用します。
SELECT * FROM manufact
ORDER BY lead_time
上の文はいずれも同じ表示となり、manufact 表のすべての列と行のリスト
が lead_time の順に表示されます。
manu_code manu_name
SMT
HRO
HSK
ANZ
NRG
NKL
PRC
KAR
SHM
Smith
Hero
Husky
Anza
Norge
Nikolus
ProCycle
Karsten
Shimara
lead_time
3
4
5
5
7
8
9
21
30
昇順
デフォルトでは、抽出されたデータは 昇順 にソートおよび表示されます。
昇順は、文字 (CHARACTER) 型 の場合は大文字の A から小文字の z への順序
になり、数値のデータ型の場合は最低値から最高値への順序になります。
日付 (DATE) 型および日時 (DATETIME) 型の場合は最も早い日時から最新の日
時への順序、時間隔 (INTERVAL) 型の場合は最短の期間から最長の期間への
順序になります。
SELECT * FROM manufact
ORDER BY lead_time DESC
2-14 単純な SELECT 文
単一表 SELECT 文
降順
列名の後のキーワード DESC は、抽出されたデータを降順 にソートします。
manu_code manu_name
SHM
KAR
PRC
NKL
NRG
HSK
ANZ
HRO
SMT
lead_time
Shimara
Karsten
ProCycle
Nikolus
Norge
Husky
Anza
Hero
Smith
30
21
9
8
7
5
5
4
3
ORDER BY 節にはどのような列でも指定でき ( テキスト (TEXT) 型またはバイ
ト (BYTE) 型を除く )、データベース・サーバーはその列の値に基づいて
データをソートします。
複数列のソート
複数の列に ORDER BY を指定して、多重ソート を指定することができます。
デフォルトは昇順 のままで、ORDER BY 節に最初にリストされた列が優先
されます。
多重ソートの次の 2 つの例では、選択されたデータを表示する順序は、
ORDER BY 節に指定する 2 つの列の順序を変更することによって変更されま
す。
SELECT * FROM stock
ORDER BY manu_code, unit_price
単純な SELECT 文 2-15
単一表 SELECT 文
ここでは、manu_code 列データはアルファベット順に表示され、同じ
manu_code がある行の各セット内では ( 例えば、ANZ、HRO)、unit_price は
価格の昇順にリストされます。
stock_num manu_code description
5
9
6
313
201
310
301
304
110
205
8
302
309
.
.
.
113
5
6
1
unit_price unit unit_descr
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
HRO
HRO
tennis racquet
volleyball net
tennis ball
swim cap
golf shoes
kick board
running shoes
watch
helmet
3 golf balls
volleyball
ice pack
ear drops
$19.80
$20.00
$48.00
$60.00
$75.00
$84.00
$95.00
$170.00
$244.00
$312.00
$840.00
$4.50
$40.00
each
each
case
box
each
case
each
box
case
case
case
each
case
each
each
24 cans/case
12/box
each
12/case
each
10/box
4/case
24/case
24/case
each
20/case
SHM
SMT
SMT
SMT
18-spd, assmbld
tennis racquet
tennis ball
baseball gloves
$685.90
$25.00
$36.00
$450.00
each
each
case
case
each
each
24 cans/case
10 gloves/case
次の例では、ORDER BY 節の列の順序は逆になります。
SELECT * FROM stock
ORDER BY unit_price, manu_code
2-16 単純な SELECT 文
単一表 SELECT 文
ここでは、データは unit_price の昇順に表示され、複数の行に同じ
unit_price がある場合 ( 例えば、$20.00、$48.00、$312.00)、manu_code はア
ルファベット順に表示されます。
stock_num manu_code description
302
302
5
9
103
106
5
.
.
.
301
204
108
6
305
303
311
.
.
.
110
205
205
205
1
4
102
111
112
7
203
113
1
8
4
unit_price unit unit_descr
HRO
KAR
ANZ
ANZ
PRC
PRC
SMT
ice pack
ice pack
tennis racquet
volleyball net
frnt derailleur
bicycle stem
tennis racquet
$4.50
$5.00
$19.80
$20.00
$20.00
$23.00
$25.00
each
each
each
each
each
each
each
each
each
each
each
each
each
each
HRO
KAR
SHM
ANZ
HRO
PRC
SHM
running shoes
putter
crankset
tennis ball
first-aid kit
socks
water gloves
$42.50
$45.00
$45.00
$48.00
$48.00
$48.00
$48.00
each
each
each
case
case
box
box
each
each
each
24 cans/case
4/case
24 pairs/box
4 pairs/box
HSK
ANZ
HRO
NKL
SMT
HRO
PRC
SHM
SHM
HRO
NKL
SHM
HSK
ANZ
HSK
helmet
3 golf balls
3 golf balls
3 golf balls
baseball gloves
football
bicycle brakes
10-spd, assmbld
12-spd, assmbld
basketball
irons/wedge
18-spd, assmbld
baseball gloves
volleyball
football
$308.00
$312.00
$312.00
$312.00
$450.00
$480.00
$480.00
$499.99
$549.00
$600.00
$670.00
$685.90
$800.00
$840.00
$960.00
case
case
case
case
case
case
case
each
each
case
case
each
case
case
case
4/case
24/case
24/case
24/case
10 gloves/case
24/case
4 sets/case
each
each
24/case
2 sets/case
each
10 gloves/case
24/case
24/case
単純な SELECT 文 2-17
単一表 SELECT 文
ORDER BY 節の列の順序、および DESC キーワードの位置は重要です。次の
4 つの SELECT 文には、ORDER BY 節と同じコンポーネントが含まれており、
それぞれ異なる結果が生成されます ( ここでは表示されていない )。
SELECT * FROM stock
ORDER BY manu_code, unit_price DESC
SELECT * FROM stock
ORDER BY unit_price, manu_code DESC
SELECT * FROM stock
ORDER BY manu_code DESC, unit_price
SELECT * FROM stock
ORDER BY unit_price DESC, manu_code
2-18 単純な SELECT 文
単一表 SELECT 文
特定の列の選択
前のセクションでは、表からすべてのデータを選択して順序付ける方法に
ついて説明しました。ただし、表示するデータが 1 つまたは複数の特定の
列のデータのみである場合があります。この場合でも、SELECT 節と FROM
節を使用して列と表を指定し、必要に応じて ORDER BY 節を使用してデー
タを昇順または降順に順序付けます。
orders 表のすべての顧客番号を表示すると想定します。
SELECT customer_num FROM orders
この文は orders 表の customer_num 列のすべてのデータを選択し、重複を
含め、すべての注文の顧客番号をリストします。
customer_num
101
104
104
104
104
106
106
110
110
111
112
115
116
117
117
119
120
121
122
123
124
126
127
一部の顧客は複数の注文を出しているため、出力には数多くの重複も含ま
れています。重複行を射影に表示する場合もあります。また、各値が表示
される回数ではなく、明確な値のみを確認したい場合もあります。
単純な SELECT 文 2-19
単一表 SELECT 文
選択リストの先頭にキーワード DISTINCT またはシノニム UNIQUE を含める
ことによって、重複行を表示しないようにすることができます。
SELECT DISTINCT customer_num FROM orders
SELECT UNIQUE customer_num FROM orders
これらのいずれの文も、orders 表の各顧客番号を一度のみ表示するように
制限するため、読みやすいリストが生成されます。
customer_num
101
104
106
110
111
112
115
116
117
119
120
121
122
123
124
126
127
顧客コールを処理し、顧客注文番号 DM354331 を検索すると想定します。
このために、orders 表のすべての顧客注文番号をリストします。
SELECT po_num FROM orders
2-20 単純な SELECT 文
単一表 SELECT 文
この SELECT 文は、orders 表の po_num 列のデータを抽出し、次のリストを
表示します。
po_num
B77836
9270
B77890
8006
2865
Q13557
278693
LZ230
4745
429Q
B77897
278701
B77930
8052
MA003
PC6782
DM354331
S22942
Z55709
W2286
C3288
W9925
KF2961
単純な SELECT 文 2-21
単一表 SELECT 文
ただし、このリストの順序はあまり便利ではありません。ORDER BY 節を追
加して列データを昇順にソートすると、特定の po_num を簡単に見つける
ことができます。
SELECT po_num FROM orders
ORDER BY po_num
po_num
278693
278701
2865
429Q
4745
8006
8052
9270
B77836
B77890
B77897
B77930
C3288
DM354331
KF2961
LZ230
MA003
PC6782
Q13557
S22942
W2286
W9925
Z55709
2-22 単純な SELECT 文
単一表 SELECT 文
表から複数の列を選択するには、SELECT 節の選択リストにこれらの列をリ
ストします。列を選択する順序は、列が生成される順序、つまり左から右
への順序になります。
SELECT paid_date, ship_date, order_date,
customer_num, order_num, po_num
FROM orders
ORDER BY paid_date, order_date, customer_num
前述のように、ORDER BY 節を使用してデータを昇順または降順にソート
し、多重ソートを行うことができます。
paid_date
ship_date
order_date customer_num
06/03/1991
06/14/1991
06/21/1991
07/10/1991
07/21/1991
07/22/1991
07/31/1991
08/06/1991
08/06/1991
08/21/1991
08/22/1991
08/22/1991
08/22/1991
08/29/1991
08/31/1991
09/02/1991
09/20/1991
05/30/1991 05/22/1991
05/30/1991
06/05/1991 05/31/1991
06/29/1991 06/18/1991
07/12/1991 06/29/1991
07/13/1991 07/09/1991
05/26/1991 05/21/1991
05/23/1991 05/22/1991
06/09/1991 05/24/1991
07/03/1991 06/25/1991
07/06/1991 06/07/1991
06/01/1991 05/20/1991
07/10/1991 06/22/1991
07/13/1991 07/10/1991
07/16/1991 07/11/1991
06/21/1991 06/14/1991
06/29/1991 06/17/1991
07/25/1991 07/23/1991
07/30/1991 07/24/1991
07/03/1991 06/18/1991
07/16/1991 06/27/1991
07/30/1991 07/24/1991
07/16/1991 07/11/1991
106
112
117
117
119
120
101
104
116
106
110
104
104
121
122
111
115
124
127
104
110
126
123
order_num po_num
1004
1006
1007
1012
1016
1017
1002
1003
1005
1014
1008
1001
1013
1018
1019
1009
1010
1021
1023
1011
1015
1022
1020
8006
Q13557
278693
278701
PC6782
DM354331
9270
B77890
2865
8052
LZ230
B77836
B77930
S22942
Z55709
4745
429Q
C3288
KF2961
B77897
MA003
W9925
W2286
表の複数の列に SELECT と ORDER BY を指定すると、整数を使用して
ORDER BY 節で列の位置を簡単に参照できる場合があります。
SELECT customer_num, order_num, po_num, order_date
FROM orders
ORDER BY 4, 1
SELECT customer_num, order_num, po_num, order_date
FROM orders
ORDER BY order_date, customer_num
単純な SELECT 文 2-23
単一表 SELECT 文
これらの 2 つの文は、同じデータを抽出および表示します。
customer_num
104
101
104
106
116
112
117
110
111
115
104
117
104
106
110
119
120
121
122
123
124
126
127
2-24 単純な SELECT 文
order_num po_num
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
B77836
9270
B77890
8006
2865
Q13557
278693
LZ230
4745
429Q
B77897
278701
B77930
8052
MA003
PC6782
DM354331
S22942
Z55709
W2286
C3288
W9925
KF2961
order_date
05/20/1991
05/21/1991
05/22/1991
05/22/1991
05/24/1991
05/30/1991
05/31/1991
06/07/1991
06/14/1991
06/17/1991
06/18/1991
06/18/1991
06/22/1991
06/25/1991
06/27/1991
06/29/1991
07/09/1991
07/10/1991
07/11/1991
07/11/1991
07/23/1991
07/24/1991
07/24/1991
単一表 SELECT 文
列名に整数を割り当てた場合は、DESC キーワードを ORDER BY 節に含める
ことができます。
SELECT customer_num, order_num, po_num, order_date
FROM orders
ORDER BY 4 DESC, 1
ここでは、データはまず最初に order_date によって降順にソートされ、日
付内で customer_num によって昇順にソートされます。
サブ文字列の選択
サブ文字列 を選択リストに含めることによって、文字 (CHARACTER) 型 列の
値の一部を選択することができます。販売部門が顧客にメールを郵送する
ことを予定しており、郵便番号に基づいて大まかな地域的分布を知りたい
と想定します。
SELECT zipcode[1,3], customer_num
FROM customer
ORDER BY zipcode
単純な SELECT 文 2-25
単一表 SELECT 文
この SELECT 文は、サブ文字列を使用して zipcode 列の最初の 3 文字 ( 州を
識別する ) および完全な customer_num を選択し、これらを郵便番号の昇順
にリストします。
zipcode customer_num
021
080
085
198
322
604
740
802
850
850
940
940
940
940
940
940
940
940
940
940
940
940
940
940
941
943
943
946
125
119
122
121
123
127
124
126
128
120
105
112
113
115
104
116
110
114
106
108
117
111
101
109
102
103
107
118
WHERE 節の使用方法
特定の顧客によって発行された注文のみを表示したり、特定の顧客サービ
ス担当者によって入力されたコールを表示する場合もあります。表からこ
のような特定の列を抽出するには、SELECT 文に WHERE 節を追加します。
WHERE 節を使用すると、比較条件 または結合条件 をセットアップするこ
とができます。このセクションでは、最初の使用方法のみについて説明しま
す。結合条件については、後のセクションおよび次の章で説明します。
2-26 単純な SELECT 文
単一表 SELECT 文
SELECT 文によって戻される行のセットは、その文に対するアクティブ・
セット です。単一の SELECT 文は、1 つの行を戻します。IBM Informix 4GL
または埋込み言語プログラムでは、複数行を抽出するには、カーソル を使
用する必要があります。本書の第 6 章および第 7 章を参照してください。
比較条件の作成
SELECT 文の WHERE 節は、表示する行を指定します。比較条件は、特定の
キーワード および演算子 を使用して、検索条件を定義します。
例えば、キーワード BETWEEN、IN、LIKE、MATCHES の 1 つを使用して等
価性をテストしたり、キーワード IS NULL を使用して NULL 値をテストす
ることができます。キーワード NOT とこれらのキーワードのいずれかを組
み合わせると、反対の条件を指定できます。
図 12-2 に、等価性をテストするキーワードの代わりに WHERE 節に使用で
きる関係演算子 を示します。
演算子
=
!= or <>
>
>=
<
<=
図 12-2
演算
equals
does not equal
greater than
greater than or equal to
less than
less than or equal to
等価性をテストする関係演算子
文字 (CHAR) 型式では、“ より大きい ” は ASCII 照合順序において後 であるこ
とを意味し、小文字は大文字の後になり、両者とも数値の後になります。
「IBM Informix SQL リファレンス・ガイド」の ASCII 文字セット・チャートを
参照してください。日付 (DATE) 型および日時 (DATETIME) 型式では、“ より
大きい ” は時間的に後 であることを意味し、時間隔 (INTERVAL) 型式では、
期間が長い ことを意味します。NULL 値をテストする場合を除き、テキスト
(TEXT) 型またはバイト (BYTE) 型列を文字列式に使用することはできません。
前のキーワードおよび演算子を WHERE 節に使用して、次のような比較条件
問合せを作成することができます。
• 値を含める。
• 値を除外する。
• 値の範囲を検索する。
単純な SELECT 文 2-27
単一表 SELECT 文
• 値のサブセットを検索する。
• NULL 値を識別する。
前のキーワードおよび演算子を WHERE 節に使用して、次の項目を使用して
変数テキスト検索を行う比較条件問合せを作成することもできます。
•
•
•
•
•
テキスト比較
1 文字のワイルドカード
制限付きの 1 文字のワイルドカード
可変長ワイルドカード
サブスクリプト付け
次の例は、このような種類の問合せを示します。
行の組込み
関係演算子 = を使用して、WHERE 節に行を含めます。
SELECT customer_num, call_code, call_dtime, res_dtime
FROM cust_calls
WHERE user_id = "maryj"
この SELECT 文は、次の行のセットを戻します。
customer_num call_code call_dtime
106 D
121 O
127 I
2-28 単純な SELECT 文
res_dtime
1991-06-12 08:20 1991-06-12 08:25
1991-07-10 14:05 1991-07-10 14:06
1991-07-31 14:30
単一表 SELECT 文
行の除外
関係演算子 != または <> を使用して、WHERE 節から行を除外します。
次の例では、ANSI 準拠データベースから選択し、所有者 または customer
表の作成者のログイン名を指定することを想定しています。この修飾子は、
表の作成者が現行ユーザーであるか、またはデータベースが ANSI 準拠でな
い場合は必要ありませんが、このような場合に、この修飾子を含めても問
題はありません。所有者命名 については、「IBM Informix SQL リファレン
ス・ガイド」を参照してください。
SELECT customer_num, company, city, state
FROM odin.customer
WHERE state != "CA"
SELECT customer_num, company, city, state
FROM odin.customer
WHERE state <> "CA"
これらの文は、ユーザー odin が所有する customer 表に、state 列の値が CA
と等しくないことを指定することによって、値を除外します。
customer_num
119
120
121
122
123
124
125
126
127
128
company
city
state
The Triathletes Club
Century Pro Shop
City Sports
The Sporting Life
Bay Sports
Putnum’s Putters
Total Fitness Sports
Neelie’s Discount Sp
Big Blue Bike Shop
Phoenix College
Cherry Hill
Phoenix
Wilmington
Princeton
Jacksonville
Bartlesville
Brighton
Denver
Blue Island
Phoenix
NJ
AZ
DE
NJ
FL
OK
MA
CO
NY
AZ
単純な SELECT 文 2-29
単一表 SELECT 文
行の指定
WHERE 節に行を指定するには、いくつかの方法があります。次に、2 つの
方法を示します。
SELECT catalog_num, stock_num, manu_code, cat_advert
FROM catalog
WHERE catalog_num BETWEEN 10005 AND 10008
SELECT catalog_num, stock_num, manu_code, cat_advert
FROM catalog
WHERE catalog_num >= 10005 AND catalog_num <= 10008
これらの文は、catalog_num の範囲を 10005 ~ 10008 に指定します。最初の
文はキーワードを使用し、2 番目の文は関係演算子を使用して次の行を抽
出します。
catalog_num
stock_num
manu_code
cat_advert
10005
3
HSK
High-Technology Design Expands the Sweet Spot
catalog_num
stock_num
manu_code
cat_advert
10006
3
SHM
Durable Aluminum for High School and Collegiate
Athletes
catalog_num
stock_num
manu_code
cat_advert
10007
4
HSK
Quality Pigskin with Joe Namath Signature
catalog_num
stock_num
manu_code
cat_advert
10008
4
HRO
Highest Quality Football for High School
and Collegiate Competitions
出力には列名によって < バイト (BYTE) 型値 > のみが表示されるため、カ
タログ表にはバイト (BYTE) 型列が含まれていますが、この列は SELECT 文に
は含まれていません。IBM Informix SQL または IBM Informix 4GL のフォーム
を使用するときに PROGRAM 属性を使用するか、または 4GL か埋込み言語
プログラムを記述することによって、テキスト (TEXT) 型値およびバイト
(BYTE) 型値を表示できます。
2-30 単純な SELECT 文
単一表 SELECT 文
行の範囲の除外
SELECT fname, lname, company, city, state
FROM customer
WHERE zipcode NOT BETWEEN "94000" AND "94999"
ORDER BY state
ここでは、キーワード NOT BETWEEN を使用することによって、条件は、
zipcode 列に 94000 ~ 94999 の文字範囲を持つ行を除外します。
fname
lname
company
city
state
Fred
Frank
Eileen
Jason
Marvin
James
Bob
Cathy
Kim
Chris
Jewell
Lessor
Neelie
Wallack
Hanlon
Henry
Shorter
O’Brian
Satifer
Putnum
Century* Pro Shop
Phoenix University
Neelie’s Discount Sp
City Sports
Bay Sports
Total Fitness Sports
The Triathletes Club
The Sporting Life
Big Blue Bike Shop
Putnum’s Putters
Phoenix
Phoenix
Denver
Wilmington
Jacksonville
Brighton
Cherry Hill
Princeton
Blue Island
Bartlesville
AZ
AZ
CO
DE
FL
MA
NJ
NJ
NY
OK
WHERE 節を使用した値のサブセットの検索
前述のように、これらの例では、ANSI 準拠のデータベースを使用すること
を想定しています。ここでは、所有者 ID を引用符で囲み、大文字小文字を
区別します。
SELECT lname, city, state, phone
FROM "Aleta".customer
WHERE state = "AZ" OR state = "NJ"
ORDER BY lname
SELECT lname, city, state, phone
FROM "Aleta".customer
WHERE state IN ("AZ", "NJ")
ORDER BY lname
これらの両方の文は、Aleta.customer 表の state 列に AZ または NJ のサブ
セットが含まれている行を抽出します。
lname
city
state phone
Jewell
Lessor
O’Brian
Shorter
Phoenix
Phoenix
Princeton
Cherry Hill
AZ
AZ
NJ
NJ
602-265-8754
602-533-1817
609-342-0054
609-663-6079
単純な SELECT 文 2-31
単一表 SELECT 文
IN キーワードを使用して、テキスト (TEXT) 型列またはバイト (BYTE) 型列を
テストすることはできません。
ANSI 準拠のデータベースに対する問合せのこの例では、表の所有者名は引
用符で囲まれていません。前の 2 つの問合せは Aleta.customer 表を検索しま
したが、この SELECT 文は ALETA.customer 表 ( 別の表 ) を検索します。
SELECT lname, city, state, phone
FROM Aleta.customer
WHERE state NOT IN ("AZ", "NJ")
ORDER BY state
ここでは、キーワード NOT IN を追加することによって、state 列のサブセッ
ト AZ および NJ を除外するようにサブセットを変更します。結果は、state
の順序になります。
2-32 単純な SELECT 文
lname
city
state phone
Pauli
Sadler
Currie
Higgins
Vector
Watson
Ream
Quinn
Miller
Jaeger
Keyes
Lawson
Beatty
Albertson
Grant
Parmelee
Sipes
Baxter
Neelie
Wallack
Hanlon
Henry
Satifer
Putnum
Sunnyvale
San Francisco
Palo Alto
Redwood City
Los Altos
Mountain View
Palo Alto
Redwood City
Sunnyvale
Redwood City
Sunnyvale
Los Altos
Menlo Park
Redwood City
Menlo Park
Mountain View
Redwood City
Oakland
Denver
Wilmington
Jacksonville
Brighton
Blue Island
Bartlesville
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CA
CO
DE
FL
MA
NY
OK
408-789-8075
415-822-1289
415-328-4543
415-368-1100
415-776-3249
415-389-8789
415-356-9876
415-544-8729
408-723-8789
415-743-3611
408-277-7245
415-887-7235
415-356-9982
415-886-6677
415-356-1123
415-534-8822
415-245-4578
415-655-0011
303-936-7731
302-366-7511
904-823-4239
617-232-4159
312-944-5691
918-355-2074
単一表 SELECT 文
NULL 値の識別
IS NULL または IS NOT NULL オプションを使用して、NULL 値をチェックし
ます。NULL は、値が不明であるか適用できないこと、またはデータがない
ことを表します。NULL 値は、0 または空白とは異なります。
SELECT order_num, customer_num, po_num, ship_date
FROM orders
WHERE paid_date IS NULL
ORDER BY customer_num
この SELECT 文は、NULL paid_date を持つすべての行を戻します。
order_num
customer_num
1004
1006
1007
1012
1016
1017
106
112
117
117
119
120
po_num
ship_date
8006
Q13557
278693
278701
PC6782
DM354331
05/30/1991
06/05/1991
06/29/1991
07/12/1991
07/13/1991
複合条件の作成
論理演算子 AND、OR、および NOT を使用して、複数の比較条件またはブー
ル (BOOLEAN) 式を結合することができます。ブール (BOOLEAN) 式は、
TRUE または FALSE として評価されます。また、NULL 値が含まれている
場合は、不明として評価されます。NULL 値をテストする場合にのみ、ブー
ル (BOOLEAN) 式に TEXT または BYTE オブジェクトを使用することができ
ます。
ここでは、演算子 AND は、WHERE 節の 2 つの比較式を結合します。
SELECT order_num, customer_num, po_num, ship_date
FROM orders
WHERE paid_date IS NULL
AND ship_date IS NOT NULL
ORDER BY customer_num
単純な SELECT 文 2-33
単一表 SELECT 文
この SELECT 文は、NULL paid_date を含み、NULL ship_date を含まないすべ
ての行を戻します。
order_num customer_num po_num
1004
1007
1012
1016
1017
106
117
117
119
120
8006
278693
278701
PC6782
DM354331
ship_date
05/30/1991
06/05/1991
06/29/1991
07/12/1991
07/13/1991
変数テキスト検索の使用方法
CHARACTER フィールドのサブ文字列検索に基づいて、変数テキスト 問合
せに対してキーワード LIKE および MATCHES を使用することができます。
反対の条件を指定するには、キーワード NOT を含めます。キーワード LIKE
は ANSI 標準ですが、MATCHES は Informix 拡張です。
変数テキスト検索文字列には、LIKE または MATCHES と共に、図 12-3 に示
すワイルドカードを含めることができます。
記号
意味
LIKE
%
_
\
ゼロまたは 1 文字以上と評価する
1 文字と評価する
次の 1 文字を一般文字として扱う
MATCHES
*
?
[]
\
図 12-3
ゼロまたは 1 文字以上と評価する
1 文字と評価する (NULL を除く )
1 文字または値の範囲と評価する
次の 1 文字を一般文字として扱う
LIKE および MATCHES と共に使用するワイルドカード
LIKE または MATCHES を使用して、テキスト (TEXT) 型列またはバイト (BYTE)
型列をテストすることはできません。
2-34 単純な SELECT 文
単一表 SELECT 文
正確なテキスト比較の使用方法
次の例では、キーワード LIKE か MATCHES、または関係演算子 = を使用し
て、正確なテキスト比較を検索する WHERE 節を含めます。前の例とは異な
り、これらの例は、ANSI 準拠のデータベースの外部 表に対する問合せ方法
を示します。
外部表とは、現行のデータベースに存在しない表のことです。ANSI 準拠の
データベースの一部である外部表のみにアクセスすることができます。
本章で前に使用したデータベースは、stores5 と呼ばれるデモンストレー
ション・データベースでした。一方、次の例の FROM 節は、所有者 bubba
によって作成され、syzygy と呼ばれる ANSI 準拠のデータベースに常駐する
manatee 表を指定します。外部表の定義の詳細については、「IBM Informix
SQL リファレンス・ガイド」を参照してください。
SELECT * FROM syzygy:bubba.manatee
WHERE description = "helmet"
ORDER BY mfg_code
SELECT * FROM syzygy:bubba.manatee
WHERE description LIKE "helmet"
ORDER BY mfg_code
SELECT * FROM syzygy:bubba.manatee
WHERE description MATCHES "helmet"
ORDER BY mfg_code
これらのすべての SELECT 文は、description 列に helmet という単一文字が
含まれるすべての行を抽出します。
stock_no mfg_code
991
991
991
991
991
ANT
BKE
JSK
PRM
SHR
description
helmet
helmet
helmet
helmet
helmet
unit_price unit unit_type
$222.00
$269.00
$311.00
$234.00
$245.00
case
case
each
case
case
4/case
4/case
4/case
4/case
4/case
単一文字ワイルドカードの使用方法
次の例は、WHERE 節での単一文字ワイルドカードの使用方法を示します。
また、外部表に対する問合せを示します。ここでは、stock 表は、外部デー
タベース sloth に格納されています。このデータベースは、現行の stores5
データベースの外部にあり、meerkat と呼ばれる別のデータベース・サー
バー上にあります。
単純な SELECT 文 2-35
単一表 SELECT 文
外部表、外部データベース、およびネットワークの詳細については、本書
の第 12 章を参照してください。また、「IBM Informix SQL リファレンス・ガ
イド」も参照してください。
SELECT * FROM sloth@meerkat:stock
WHERE manu_code LIKE "_R_"
AND unit_price >= 100
ORDER BY description, unit_price
SELECT * FROM sloth@meerkat:stock
WHERE manu_code MATCHES "?R?"
AND unit_price >= 100
ORDER BY description, unit_price
両方の SELECT 文は、manu_code の中央の文字が R である行のみを抽出し
ます。
stock_num manu_code description
205
306
307
2
1
7
102
114
4
110
110
308
304
HRO
PRC
PRC
HRO
HRO
HRO
PRC
PRC
HRO
PRC
HRO
PRC
HRO
3 golf balls
Tandem adapter
baby jogger
baseball
baseball gloves
basketball
bicycle brakes
bicycle gloves
football
helmet
helmet
twin jogger
watch
unit_price unit unit_descr
$312.00
$160.00
$250.00
$126.00
$250.00
$600.00
$480.00
$120.00
$480.00
$236.00
$260.00
$280.00
$280.00
each
each
each
case
case
case
case
case
case
case
case
each
box
24/case
each
each
24/case
10 gloves/case
24/case
4 sets/case
10 pairs/case
24/case
4/case
4/case
each
10/box
比較 "_R_" (LIKE) または "?R?" (MATCHES) は、次の項目を左から右へ指定
します。
• 任意の単一文字
• 文字 R
• 任意の単一文字
2-36 単純な SELECT 文
単一表 SELECT 文
制限付きの単一文字ワイルドカードを指定した WHERE 節
SELECT * FROM stock
WHERE manu_code MATCHES "[A-H]*"
ORDER BY description, manu_code, unit_price
この文は、manu_code が A ~ H で始まる行のみを選択し、次の行を戻しま
す。
stock_num manu_code description
205
205
2
3
1
1
7
.
.
.
110
110
110
.
.
.
301
301
313
6
5
8
9
304
304
unit_price unit unit_descr
ANZ
HRO
HRO
HSK
HRO
HSK
HRO
3 golf balls
3 golf balls
baseball
baseball bat
baseball gloves
baseball gloves
basketball
$312.00
$312.00
$126.00
$240.00
$250.00
$800.00
$600.00
case
case
case
case
case
case
case
ANZ
HRO
HSK
helmet
helmet
helmet
$244.00 case 4/case
$260.00 case 4/case
$308.00 case 4/case
ANZ
HRO
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
HRO
running shoes
running shoes
swim cap
tennis ball
tennis racquet
volleyball
volleyball net
watch
watch
$95.00
$42.50
$60.00
$48.00
$19.80
$840.00
$20.00
$170.00
$280.00
each
each
box
case
each
case
each
box
box
24/case
24/case
24/case
12/case
10 gloves/case
10 gloves/case
24/case
each
each
12/box
24 cans/case
each
24/case
each
10/box
10/box
クラス・テスト "[A-H]" は、A ~ H の任意の単一文字を指定します。LIKE
キーワードと同等なワイルドカード記号はありません。
単純な SELECT 文 2-37
単一表 SELECT 文
可変長ワイルドカードを指定した WHERE 節
これらの例では、文字列の最後にワイルドカードを使用して、description
が bicycle という文字で始まるすべての行を抽出します。
SELECT * FROM stock
WHERE description LIKE "bicycle%"
ORDER BY description, manu_code
SELECT * FROM stock
WHERE description MATCHES "bicycle*"
ORDER BY description, manu_code
いずれの SELECT 文も、次の行を戻します。
stock_num manu_code description
102
102
114
107
106
101
101
105
105
PRC
SHM
PRC
PRC
PRC
PRC
SHM
PRC
SHM
bicycle
bicycle
bicycle
bicycle
bicycle
bicycle
bicycle
bicycle
bicycle
brakes
brakes
gloves
saddle
stem
tires
tires
wheels
wheels
unit_price unit unit_descr
$480.00
$220.00
$120.00
$70.00
$23.00
$88.00
$68.00
$53.00
$80.00
case
case
case
pair
each
box
box
pair
pair
4 sets/case
4 sets/case
10 pairs/case
pair
each
4/box
4/box
pair
pair
比較 "bicycle%" または "bicycle*" は、文字 bicycle の後に 0 個以上の文字の
任意のシーケンスが続く文字列を指定します。これらは bicycle stem と一致
し、stem がワイルドカードと対応しています。この記述を含む行がある場
合は、文字 bicycle と一致します。
次の SELECT 文は、PRC の manu_code を除外するもう 1 つの比較条件を追
加することによって、さらに検索を絞り込みます。
SELECT * FROM stock
WHERE description LIKE "%bicycle%"
AND manu_code NOT LIKE "PRC"
ORDER BY description, manu_code
この SELECT 文は、次の行のみを抽出します。
stock_num manu_code description
102 SHM
101 SHM
105 SHM
2-38 単純な SELECT 文
bicycle brakes
bicycle tires
bicycle wheels
unit_price unit unit_descr
$220.00 case 4 sets/case
$68.00 box 4/box
$80.00 pair pair
単一表 SELECT 文
大きな表から選択し、比較文字列に初期ワイルドカードを使用した場合、
問合せを実行するのに時間がかかることがあります。これは、インデック
スを使用できず、すべての行を検索する必要があるためです。
特殊文字の比較
キーワード ESCAPE を LIKE または MATCHES と共に使用すると、特殊文字
がワイルドカード記号として誤って解釈されるのを防ぐことができます。
SELECT * FROM cust_calls
WHERE res_descr LIKE "%!%%" ESCAPE "!"
ESCAPE キーワードは、エスケープ文字 ( この例では、!) を指定し、ワイル
ドカードではなくデータとして解釈されるようにように、後続の 1 文字を
保護します。この例では、エスケープ文字によって中央のパーセント記号
はデータとして扱われます。ESCAPE キーワードを使用して、LIKE ワイル
ドカード % によって res_descr 列のパーセント記号 (%) のオカレンスを検索
することができます。この問合せは、次の行を抽出します。
customer_num
call_dtime
user_id
call_code
call_descr
res_dtime
res_descr
116
1990-12-21 11:24
mannyn
I
Second complaint from this customer! Received
two cases right-handed outfielder gloves
(1 HRO) instead of one case lefties.
1990-12-27 08:19
Memo to shipping (Ava Brown) to send case of
left-handed gloves, pick up wrong case; memo
to billing requesting 5% discount to placate
customer due to second offense and lateness
of resolution because of holiday
WHERE 節のサブスクリプト付けの使用方法
SELECT 文の WHERE 節にサブスクリプト付け を使用して、列に文字または
数値の範囲を指定することができます。
SELECT catalog_num, stock_num, manu_code, cat_advert,
cat_descr
FROM catalog
WHERE cat_advert[1,4] = "High"
文字部分列 [1,4] によって、問合せは、cat_advert 列の最初の 4 文字が High
であるすべての行を抽出します。
単純な SELECT 文 2-39
単一表 SELECT 文
catalog_num
stock_num
manu_code
cat_advert
10004
2
HRO
Highest Quality Ball Available, from
Hand-Stitching to the Robinson Signature
cat_descr
Jackie Robinson signature ball. Highest professional quality, used by National
League.
catalog_num 10005
stock_num
3
manu_code
HSK
cat_advert
High-Technology Design Expands the Sweet Spot
cat_descr
Pro-style wood. Available in sizes: 31, 32, 33, 34, 35.
catalog_num
stock_num
manu_code
cat_advert
10008
4
HRO
Highest Quality Football for High School and
Collegiate Competitions
cat_descr
NFL-style, pigskin.
catalog_num 10012
stock_num
6
manu_code
SMT
cat_advert
High-Visibility Tennis, Day or Night
cat_descr
Soft yellow color for easy visibility in sunlight or
artificial light.
catalog_num
stock_num
manu_code
cat_advert
10043
202
KAR
High-Quality Woods Appropriate for High School
Competitions or Serious Amateurs
cat_descr
Full set of woods designed for precision control and
power performance.
catalog_num
stock_num
manu_code
cat_advert
10045
204
KAR
High-Quality Beginning Set of Irons
Appropriate for High School Competitions
cat_descr
Ideally balanced for optimum control. Nylon covered shaft.
catalog_num 10068
stock_num
310
manu_code
ANZ
cat_advert
High-Quality Kickboard
cat_descr
White. Standard size.
2-40 単純な SELECT 文
単一表 SELECT 文
式と導出値
列は名前で選択する以外の方法で選択できます。SELECT 文の SELECT 節を
使用して列データの計算を行い、1 つまたは複数の列の内容から導出され
た 情報を表示できます。このためには、選択リストに式 をリストします。
式は、列名、定数、引用符で囲まれた文字列、キーワード、または演算子
で結合されたこれらの組合せで構成されています。SELECT 文をプログラム
に埋め込む場合は、式にホスト変数 ( プログラム・データ ) を含めることも
できます。
算術式
算術式は、図 12-4 に示す 1 つまたは複数の算術演算子 を含み、数値に変換
されます。
演算子
+
*
/
図 12-4
演算
加算
減算
乗算
除算
算術式に使用される算術演算子
このような演算子を使用して、データベースのデータを実際に変更しない
で、指定する計算の結果を表示することができます。後で参照、計算、ま
たは即時レポートの作成を行うために変更したデータを一時表に保存する
には、INTO TEMP 節を追加します。
テキスト (TEXT) 型列または バイト (BYTE) 型列を算術式に使用することはで
きません。
SELECT stock_num, description, unit, unit_descr,
unit_price, unit_price * 1.07
FROM stock
WHERE unit_price >= 400
単純な SELECT 文 2-41
単一表 SELECT 文
この SELECT 文は、unit_price が $400 以上の場合、unit_price 列に関して 7%
の販売税を計算します ( ただし、データベース内のデータは更新されない )。
DB-Access または IBM Informix SQL 対話型エディターを使用している場合、
expression というラベルの付いた列に結果が表示されます。
stock_num description
1
1
4
4
7
8
102
111
112
113
203
baseball gloves
baseball gloves
football
football
basketball
volleyball
bicycle brakes
10-spd, assmbld
12-spd, assmbld
18-spd, assmbld
irons/wedge
unit unit_descr
case
case
case
case
case
case
case
each
each
each
case
10 gloves/case
10 gloves/case
24/case
24/case
24/case
24/case
4 sets/case
each
each
each
2 sets/case
unit_price
$800.00
$450.00
$960.00
$480.00
$600.00
$840.00
$480.00
$499.99
$549.00
$685.90
$670.00
(expression)
$856.0000
$481.5000
$1027.2000
$513.6000
$642.0000
$898.8000
$513.6000
$534.9893
$587.4300
$733.9130
$716.9000
この文は、注文数量が 5 個未満の場合、注文に対する $6.50 の追加料金を計
算します。
SELECT item_num, order_num, quantity,
total_price, total_price + 6.50
FROM items
WHERE quantity < 5
2-42 単純な SELECT 文
単一表 SELECT 文
DB-Access または IBM Informix SQL を使用している場合、expression という
ラベルの付いた列に結果が表示されます。
item_num
order_num quantity total_price
(expression)
1001
1002
1002
1003
1003
1004
1004
1004
1004
1
1
1
1
1
1
1
1
1
$250.00
$960.00
$240.00
$20.00
$840.00
$250.00
$126.00
$240.00
$800.00
$256.50
$966.50
$246.50
$26.50
$846.50
$256.50
$132.50
$246.50
$806.50
1
2
3
4
1
2
3
1
2
3
4
5
6
1021
1021
1021
1021
1022
1022
1022
1023
1023
1023
1023
1023
1023
2
3
3
2
1
2
2
2
2
1
1
1
1
$75.00
$225.00
$690.00
$624.00
$40.00
$96.00
$96.00
$40.00
$116.00
$80.00
$228.00
$170.00
$190.00
$81.50
$231.50
$696.50
$630.50
$46.50
$102.50
$102.50
$46.50
$122.50
$86.50
$234.50
$176.50
$196.50
.
.
.
1
1
2
1
2
1
2
3
4
SELECT customer_num, user_id, call_code,
call_dtime, res_dtime - call_dtime
FROM cust_calls
ORDER BY user_id
単純な SELECT 文 2-43
単一表 SELECT 文
この SELECT 文は、顧客注文を受けてから (call_dtime) 納入するまでの
(res_dtime) 間隔を日、時間、および分で計算し、expression 列に表示します
(DB-Access または IBM Informix SQL を使用している場合 )。
customer_num user_id
116
116
106
121
127
110
119
call_code call_dtime
mannyn
mannyn
maryj
maryj
maryj
richc
richc
I
I
D
O
I
L
B
1990-12-21
1990-11-28
1991-06-12
1991-07-10
1991-07-31
1991-07-07
1991-07-01
(expression)
11:24
13:34
08:20
14:05
14:30
10:24
15:00
5
0
0
0
20:55
03:13
00:05
00:01
0 00:06
0 17:21
表示ラベルの使用方法
表示ラベル を計算データまたは導出データの列に割り当てて、デフォルト
の列ヘッダー式 を置き換えることができます。前の 3 つの例では、SELECT
節に計算の後に表示ラベルを定義できます。表示される結果は前の結果と
同じですが、導出値を表示する列には記述ヘッダーがあります。
SELECT stock_num, description, unit, unit_descr,
unit_price, unit_price * 1.07 taxed
FROM stock
WHERE unit_price >= 400
ここでは、ラベル taxed が、演算 unit_price * 1.07 の結果を表示する選択リ
スト内の式に割り当てられます。
stock_num description
1
1
4
4
7
8
102
111
112
113
203
2-44 単純な SELECT 文
baseball gloves
baseball gloves
football
football
basketball
volleyball
bicycle brakes
10-spd, assmbld
12-spd, assmbld
18-spd, assmbld
irons/wedge
unit unit_descr
case
case
case
case
case
case
case
each
each
each
case
10 gloves/case
10 gloves/case
24/case
24/case
24/case
24/case
4 sets/case
each
each
each
2 sets/case
unit_price
taxed
$800.00
$450.00
$960.00
$480.00
$600.00
$840.00
$480.00
$499.99
$549.00
$685.90
$670.00
$856.0000
$481.5000
$1027.2000
$513.6000
$642.0000
$898.8000
$513.6000
$534.9893
$587.4300
$733.9130
$716.9000
単一表 SELECT 文
この SELECT 文では、ラベル surcharge が、演算 total_price + 6.50 の結果を
表示する列に定義されます。
SELECT item_num, order_num, quantity,
total_price, total_price + 6.50 surcharge
FROM items
WHERE quantity < 5
surcharge 列は、出力にラベルが付けられます。
item_num
.
.
.
2
3
4
1
2
1
1
2
3
4
1
2
.
.
.
order_num quantity total_price
1013
1013
1013
1014
1014
1015
1016
1016
1016
1016
1017
1017
1
1
2
1
1
1
2
3
1
1
4
1
$36.00
$48.00
$40.00
$960.00
$480.00
$450.00
$136.00
$90.00
$308.00
$120.00
$150.00
$230.00
surcharge
$42.50
$54.50
$46.50
$966.50
$486.50
$456.50
$142.50
$96.50
$314.50
$126.50
$156.50
$236.50
この SELECT 文は、DATETIME 列 call_dtime を DATETIME 列 res_dtime から
減算した結果を表示する列に、ラベル span を割り当てます。
SELECT customer_num, user_id, call_code,
call_dtime, res_dtime - call_dtime span
FROM cust_calls
ORDER BY user_id
単純な SELECT 文 2-45
単一表 SELECT 文
span 列は、出力にラベルが付けられます。
customer_num user_id
116
116
106
121
127
110
119
mannyn
mannyn
maryj
maryj
maryj
richc
richc
call_code call_dtime
I
I
D
O
I
L
B
1990-12-21
1990-11-28
1991-06-12
1991-07-10
1991-07-31
1991-07-07
1991-07-01
span
11:24
13:34
08:20
14:05
14:30
10:24
15:00
5
0
0
0
20:55
03:13
00:05
00:01
0 00:06
0 17:21
導出列のソート
式に ORDER BY を指定する場合、式に割り当てられた表示ラベルまたは整
数を使用することができます。
SELECT customer_num, user_id, call_code,
call_dtime, res_dtime - call_dtime span
FROM cust_calls
ORDER BY span
この問合せは、前の問合せと同じ cust_calls 表からのデータを抽出します
が、ORDER BY 節によって、これらのデータは span 列の導出値の昇順に表
示されます。
customer_num user_id
127
121
106
110
116
119
116
maryj
maryj
maryj
richc
mannyn
richc
mannyn
call_code call_dtime
I
O
D
L
I
B
I
1991-07-31
1991-07-10
1991-06-12
1991-07-07
1990-11-28
1991-07-01
1990-12-21
span
14:30
14:05
08:20
10:24
13:34
15:00
11:24
0
0
0
0
0
5
00:01
00:05
00:06
03:13
17:21
20:55
次のバージョンは、整数を使用して演算 res_dtime - call_dtime の結果を表示
し、同じ行を抽出します。
SELECT customer_num, user_id, call_code,
call_dtime, res_dtime - call_dtime span
FROM cust_calls
ORDER BY 5
2-46 単純な SELECT 文
単一表 SELECT 文
SELECT 文の関数の使用方法
式には、列名および演算子以外に 1 つまたは複数の関数を含めることがで
きます。
これらの関数には、5 つの集計 関数と 8 つの 時刻 関数、および LENGTH、
USER、TODAY、HEX、ROUND、TRUNC 関数があります。これらの関数につ
いては、「IBM Informix SQL リファレンス・ガイド」に詳しく記載されてい
ます。
集計関数
集計 関数は、COUNT、AVG、MAX、MIN、および SUM です。集計関数は、
選択されたすべての行に依存する値を取り、行自体ではなく、行に関する
情報を戻します。これらの関数は、テキスト (TEXT) 型列またはバイト (BYTE)
型列には使用することができません。
集計関数は、表内の行のグループに関する情報を要約する場合にも使用す
ることがあります。この使用方法については、第 3 章に記載されています。
集計関数を表全体に適用した場合、結果には、すべての選択された行を要
約する 1 つの行が含まれます。
この SELECT 文は、stock 表の合計行数をカウントして表示します。
SELECT COUNT(*)
FROM stock
結果は次のとおりです。
(count(*))
73
この文は、stock 表の特定の行 ( この場合は、SHM の manu_code を持つ行
のみ ) をカウントする WHERE 節を含めます。
SELECT COUNT (*)
FROM stock
WHERE manu_code = "SHM"
結果は次のとおりです。
(count(*))
16
単純な SELECT 文 2-47
単一表 SELECT 文
キーワード DISTINCT ( またはそのシノニム UNIQUE) および列名を SELECT
文に含めることによって、stock 表のさまざまなメーカー・コードの数を計
算することができます。
SELECT COUNT (DISTINCT manu_code)
FROM stock
結果は次のとおりです。
(count)
9
この SELECT 文は、stock 表のすべての行の平均 unit_price を計算します。
SELECT AVG (unit_price)
FROM stock
結果は次のとおりです。
(avg)
$196.00
この SELECT 文は、SHM の manu_code を持つ stock 表の行のみの平均
unit_price を計算します。
SELECT AVG (unit_price)
FROM stock
WHERE manu_code = "SHM"
結果は次のとおりです。
(avg)
$200.24
SELECT 文で集計関数を結合できます。
SELECT MAX (ship_charge), MIN (ship_charge)
FROM orders
2-48 単純な SELECT 文
単一表 SELECT 文
この SELECT 文は、orders 表の ship_charge の最高値および最低値を検索し
て表示します。
(max)
(min)
$25.20
$5.00
関数を式に適用し、その結果に表示ラベルを適用できます。
SELECT MAX (res_dtime - call_dtime) maximum,
MIN (res_dtime - call_dtime) minimum,
AVG (res_dtime - call_dtime) average
FROM cust_calls
この問合せは、顧客注文を受けてから納入までの最大時間、最小時間、お
よび平均時間 ( 日、時間、分 ) を検索して表示し、導出値に適切にラベルを
付けます。
maximum
minimum
average
5 20:55
0 00:01
1 02:56
SELECT SUM (ship_weight)
FROM orders
WHERE ship_date = "07/13/1991"
この SELECT 文は、1991 年 7 月 13 日に発送された注文の合計 ship_weight を
計算して表示します。
(sum)
130.5
時刻関数
時刻 関数 DAY、MDY、MONTH、WEEKDAY、YEAR、および DATE を問合せ
の SELECT 節または WHERE 節に使用することができます。これらの関数
は、関数を呼び出すために使用する式また引き数に対応する値を戻します。
CURRENT 関数 を使用して現在の日付と時刻を持つ値を戻したり、EXTEND
関数を使用して DATE または DATETIME 値の精度を調整することもできま
す。
単純な SELECT 文 2-49
単一表 SELECT 文
DAY と CURRENT の使用方法
SELECT customer_num, DAY (call_dtime), DAY (res_dtime)
FROM cust_calls
この SELECT 文は、call_dtime 列および res_dtime 列の月の日付を 2 つの
expression 列に入れて戻します。
customer_num (expression) (expression)
106
110
119
121
127
116
116
12
7
1
10
31
28
21
12
7
2
10
28
27
SELECT customer_num, DAY (call_dtime), DAY (res_dtime)
FROM cust_calls
WHERE DAY (call_dtime) < DAY (CURRENT)
この SELECT 文は、DAY 関数および CURRENT 関数を使用して、列値を月の
現在の日付と比較します。これにより、値が現在の日付よりも前である行
のみが選択されます。
customer_num (expression) (expression)
106
110
119
2-50 単純な SELECT 文
12
7
1
12
7
2
単一表 SELECT 文
SELECT customer_num, call_code, call_descr
FROM cust_calls
WHERE call_dtime < CURRENT YEAR TO DAY
この問合せは、CURRENT 関数の別の使用方法を示し、日付が現在の日付よ
りも前である行を選択します。
customer_num 106
call_code
D
call_descr
Order was received, but two of the cans of ANZ tennis
balls within the case were empty
customer_num 116
call_code
I
call_descr
Received plain white swim caps (313 ANZ) instead of
navy with team logo (313 SHM)
customer_num 116
call_code
I
call_descr
Second complaint from this customer! Received two
cases right-handed outfielder gloves (1 HRO) instead of
one case lefties.
単純な SELECT 文 2-51
単一表 SELECT 文
MONTH の使用方法
SELECT customer_num,
MONTH (call_dtime) call_month,
MONTH (res_dtime) res_month
FROM cust_calls
この SELECT 文は、MONTH 関数を使用して、顧客注文を受けて納入した月
を抽出して表示し、結果の列に表示ラベルを適用します。ただし、年は区
別されません。
customer_num
call_month
res_month
106
110
119
121
127
116
116
6
7
7
7
7
11
12
6
7
7
7
11
12
SELECT customer_num,
MONTH (call_dtime) called,
MONTH (res_dtime) resolved
FROM cust_calls
WHERE DAY (res_dtime) < DAY (CURRENT)
この SELECT 文は、MONTH 関数、DAY 関数、および CURRENT 関数を使用
して、DAY が現在の日付より前の場合、顧客注文を受けて納入した月を表
示します。
2-52 単純な SELECT 文
customer_num
called
resolved
106
110
119
121
6
7
7
7
6
7
7
7
単一表 SELECT 文
WEEKDAY の使用方法
SELECT customer_num,
WEEKDAY (call_dtime) called,
WEEKDAY (res_dtime) resolved
FROM cust_calls
ORDER BY resolved
この SELECT 文は、WEEKDAY 関数を使用して、注文を受けて納入した曜日
を表示し (0 は日曜、1 は月曜を表す )、式列にラベルを付けます。
customer_num called resolved
127
119
106
121
116
116
110
2
0
2
2
2
4
6
1
2
2
2
3
6
SELECT COUNT(*)
FROM cust_calls
WHERE WEEKDAY (call_dtime) IN (0,7)
この SELECT 文は、COUNT 関数および WEEKDAY 関数を使用して、週末に
受けた注文数をカウントします。このような SELECT 文によって、顧客注
文のパターンを把握したり、残業手当が必要かどうかを判断することがで
きます。
(count(*))
1
単純な SELECT 文 2-53
単一表 SELECT 文
SELECT customer_num, call_code,
YEAR (call_dtime) call_year,
YEAR (res_dtime) res_year
FROM cust_calls
WHERE YEAR (call_dtime) < YEAR (TODAY)
この SELECT 文は、call_dtime が現在の年の初めよりも前である行を抽出し
ます。
customer_num call_code
call_year
res_year
1990
1990
1990
1990
116 I
116 I
DATETIME 値のフォーマット
次の問合せでは、EXTEND 関数は、指定されたサブフィールドのみを表示す
ることによって、2 つの DATETIME 値を制限します。
SELECT customer_num,
EXTEND (call_dtime, month to minute) call_time,
EXTEND (res_dtime, month to minute) res_time
FROM cust_calls
ORDER BY res_time
この結果は、call_time および res_time というラベルが付けられた列を月~
分の範囲で戻し、作業量を示します。
customer_num call_time
127
106
119
110
121
116
116
2-54 単純な SELECT 文
07-31
06-12
07-01
07-07
07-10
11-28
12-21
14:30
08:20
15:00
10:24
14:05
13:34
11:24
res_time
06-12
07-02
07-07
07-10
11-28
12-27
08:25
08:21
10:30
14:06
16:47
08:19
単一表 SELECT 文
DATE 関数の使用方法
この問合せは、call_dtime が、指定された DATE よりも後である場合にの
み、DATETIME 値を抽出します。
SELECT customer_num, call_dtime, res_dtime
FROM cust_calls
WHERE call_dtime > DATE ("12/31/90")
次の行が戻されます。
customer_num call_dtime
106
110
119
121
127
1991-06-12
1991-07-07
1991-07-01
1991-07-10
1991-07-31
res_dtime
08:20
10:24
15:00
14:05
14:30
1991-06-12
1991-07-07
1991-07-02
1991-07-10
08:25
10:30
08:21
14:06
SELECT customer_num,
DATE (call_dtime) called,
DATE (res_dtime) resolved
FROM cust_calls
WHERE call_dtime >= DATE ("1/1/91")
ここでは、SELECT 文は、call_dtime が特定の日付以降である場合にのみ、
DATETIME 値を DATE フォーマットに変換し、値をラベルと共に表示しま
す。
customer_num
called
resolved
106
110
119
121
127
06/12/1991
07/07/1991
07/01/1991
07/10/1991
07/31/1991
06/12/1991
07/07/1991
07/02/1991
07/10/1991
その他の関数とキーワード
LENGTH、USER、CURRENT、および TODAY 関数は、定数を使用する SQL 式
の任意の位置に使用することもできます。また、IBM Informix OnLine を使
用すると、SITENAME キーワードを SELECT 文に含めて、現行のデータベー
スが常駐するデータベース・サーバーの名前を表示することができます。
単純な SELECT 文 2-55
単一表 SELECT 文
これらの関数およびキーワードを使用して、定数値のみで構成される式ま
たは列データを含める式を選択することができます。最初の例では、結果
は、出力のすべての行で同じです。
また、HEX 関数を使用して式の 16 進エンコードを戻したり、ROUND 関数
を使用して式の丸められた値を戻したり、TRUNC 関数を使用して式の切り
捨てられた値を戻すことができます。
SELECT customer_num,
LENGTH (fname) + LENGTH (lname) namelength
FROM customer
WHERE LENGTH (company) > 15
この SELECT 文では、LENGTH 関数は、company の長さが 15 を超える各行
の結合された fname 列と lname 列のバイト数を計算します。
customer_num
namelength
101
105
107
112
115
118
119
120
122
124
125
126
127
128
11
13
11
14
11
10
10
10
12
11
10
12
10
11
DB-Access または IBM Informix SQL 対話型エディターを使用する場合はあま
り役立ちませんが、LENGTH 関数は、プログラムおよびレポートの文字列
の長さを決定するときに重要な役割を果たす場合があります。LENGTH は、
文字 (CHARACTER) 型または 可変長文字 (VARCHAR) 型文字列のクリップされ
た長さを戻し、テキスト (TEXT) 型またはバイト (BYTE) 型文字列の完全なバイ
ト数を戻します。
USER 関数は、ユーザーの行のみを含む表の制限付きビューを定義する場合
に便利です。ビューの作成の詳細については、本書の第 11 章を参照してく
ださい。GRANT 文および CREATE VIEW 文の詳細については、
「IBM Informix
SQL リファレンス・ガイド 」を参照してください。
2-56 単純な SELECT 文
単一表 SELECT 文
この SELECT 文は、cust_calls 表を指定します。
SELECT USER from cust_calls
この SELECT 文は、問合せを実行したユーザーのユーザー名 ( ログイン・ア
カウント名 ) を戻します。この処理は、表の行ごとに 1 回ずつ繰り返され
ます。
SELECT * FROM cust_calls
WHERE user_id = USER
現行のユーザーのユーザー名が richc である場合、この SELECT 文は、
cust_calls 表内のこのユーザーが所有する行のみを抽出します。
customer_num 110
call_dtime
1991-07-07 10:24
user_id
richc
call_code
L
call_descr
Order placed one month ago (6/7) not received.
res_dtime
1991-07-07 10:30
res_descr
Checked with shipping (Ed Smith). Order sent
yesterday- we were waiting for goods from ANZ. Next
time will call with delay if necessary.
customer_num
call_dtime
user_id
call_code
call_descr
res_dtime
res_descr
error and
119
1991-07-01 15:00
richc
B
Bill does not reflect credit from previous order
1991-07-02 08:21
Spoke with Jane Akant in Finance. She found the
is sending new bill to customer
SELECT * FROM orders
WHERE order_date = TODAY
この SELECT 文は、今日のシステム日付が 1991 年 7 月 10 日であるときに出
された場合、この行を戻します。
order_num
order_date
customer_num
ship_instruct
backlog
po_num
ship_date
ship_weight
ship_charge
paid_date
1018
07/10/1991
121
SW corner of Biltmore Mall
n
S22942
07/13/1991
70.50
$20.00
08/06/1991
単純な SELECT 文 2-57
単一表 SELECT 文
キーワード SITENAME を IBM Informix OnLine の SELECT 文に含めて、データ
ベース・サーバー名を検索することができます。システム・カタログ表を
含め、行を持つ任意の表に対して SITENAME を問い合わせることができま
す。
SELECT SITENAME server, tabid FROM systables
WHERE tabid <= 4
この SELECT 文では、ラベル server を SITENAME 式に割り当て、systables シ
ステム・カタログ表から tabid 列を選択します。この表はデータベース表を
記述し、tabid はシリアル時間間隔表 ID です。
server
montague
montague
montague
montague
tabid
1
2
3
4
tabid の値を制約する WHERE 節がない場合、systables 表の行ごとにデータ
ベース・サーバー名が繰り返されます。
2-58 単純な SELECT 文
単一表 SELECT 文
SELECT HEX(customer_num) hexnum, HEX (zipcode) hexzip,
HEX (rowid) hexrow
FROM CUSTOMER
この SELECT 文では、HEX 関数は、customer 表の 3 つの指定された列の 16
進フォーマットを戻します。
hexnum
hexzip
hexrow
0x00000065
0x00000066
0x00000067
0x00000068
0x00000069
0x0000006A
0x0000006B
0x0000006C
0x0000006D
0x0000006E
0x0000006F
0x00000070
0x00000071
0x00000072
0x00000073
0x00000074
0x00000075
0x00000076
0x00000077
0x00000078
0x00000079
0x0000007A
0x0000007B
0x0000007C
0x0000007D
0x0000007E
0x0000007F
0x00000080
0x00016F86
0x00016FA5
0x0001705F
0x00016F4A
0x00016F46
0x00016F6F
0x00017060
0x00016F6F
0x00016F86
0x00016F6E
0x00016F85
0x00016F46
0x00016F49
0x00016F6E
0x00016F49
0x00016F58
0x00016F6F
0x00017191
0x00001F42
0x00014C18
0x00004DBA
0x0000215C
0x00007E00
0x00012116
0x00000857
0x0001395B
0x0000EBF6
0x00014C10
0x00000001
0x00000002
0x00000003
0x00000004
0x00000005
0x00000006
0x00000007
0x00000008
0x00000009
0x0000000A
0x0000000B
0x0000000C
0x0000000D
0x0000000E
0x0000000F
0x00000010
0x00000011
0x00000012
0x00000013
0x00000014
0x00000015
0x00000016
0x00000017
0x00000018
0x00000019
0x0000001A
0x0000001B
0x0000001C
単純な SELECT 文 2-59
複数表 SELECT 文
複数表 SELECT 文
FROM 節に表を指定して、複数の表からデータを選択することができます。
各表の 1 つ以上の関連する列間の結合条件を作成するには、WHERE 節を追
加します。これにより、結合条件を満たす行の各ペアがリンクされて単一
行が構成される一時複合表が作成されます。
単純結合 は、各表の単一の列間の関係に基づいて、複数の表の情報を結合
します。複合結合 とは、各表の複数の列間の関係に基づく複数の表の結合
のことです。
結合を作成するには、各表の 1 つ以上の列間に、結合条件 と呼ばれる関係
を指定する必要があります。列は、比較できるように互換データ型を持つ
必要があります。大きな表を結合する場合は、結合条件の列をインデック
ス付けすると、パフォーマンスが向上します。
データ型については、
「IBM Informix SQL リファレンス・ガイド」の第 3 章に
記載されており、インデックス付けについては、本書の第 4 章および第 10
章に記載されています。
デカルト積の作成
表間の結合条件を明示的に指定していない複数表問合せを実行する場合は、
デカルト積 を作成します。デカルト積は、表の行のあらゆる組合せで構成
されています。通常、デカルト積の結果は非常に大きく複雑になり、デー
タは正確でなくなります。
この SELECT 文は、2 つの表から選択してデカルト積を作成します。
SELECT * FROM customer, state
2-60 単純な SELECT 文
複数表 SELECT 文
state 表は 52 行のみで、customer 表は 28 行ですが、この SELECT 文は、1 つ
の表の行にもう 1 つの表の行を乗算し、実際的でない 1456 行を抽出しま
す。
customer_num
fname
lname
company
address1
address2
city
state
zipcode
phone
code
sname
101
Ludwig
Pauli
All Sports Supplies
213 Erstwild Court
customer_num
fname
lname
company
address1
address2
city
state
zipcode
phone
code
sname
101
Ludwig
Pauli
All Sports Supplies
213 Erstwild Court
customer_num
fname
lname
company
address1
address2
city
state
zipcode
phone
code
sname
.
.
.
101
Ludwig
Pauli
All Sports Supplies
213 Erstwild Court
Sunnyvale
CA
94086
408-789-8075
AK
Alaska
Sunnyvale
CA
94086
408-789-8075
HI
Hawaii
Sunnyvale
CA
94086
408-789-8075
CA
California
連結された行に表示されるデータの一部は、正確ではありません。例えば、
customer 表の city と state はカリフォルニア州のアドレスを示しますが、
state 表の code と sname は他の州のものである場合があります。
単純な SELECT 文 2-61
複数表 SELECT 文
結合の作成
概念的には、結合の最初の段階としてデカルト積を作成します。このデカ
ルト積を精緻化または制限し、意味のない行のデータを除去するには、有
効な結合条件を指定した WHERE 節を SELECT 文に含めます。
このセクションでは、等価結合、自然結合、および複数表結合 について説
明します。自己結合 や 外部結合 などのさらに複雑なフォームについては、
第 3 章に記載されています。
等価結合
等価結合は、等価性または照合値に基づく結合です。この等価性は、
WHERE 節に比較演算の等号 (=) で示されます。
SELECT * FROM manufact, stock
WHERE manufact.manu_code = stock.manu_code
この SELECT 文は、manu_code 列で manufact 表と stock 表を結合し、2 つの
列の値が等しい行のみを抽出します。
2-62 単純な SELECT 文
複数表 SELECT 文
manu_code
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
SMT
Smith
3
1
SMT
baseball gloves
$450.00
case
10 gloves/case
manu_code
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
SMT
Smith
3
5
SMT
tennis racquet
$25.00
each
each
manu_code
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
SMT
Smith
3
6
SMT
tennis ball
$36.00
case
24 cans/case
manu_code
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
.
.
.
ANZ
Anza
5
5
ANZ
tennis racquet
$19.80
each
each
この等価結合では、選択リストによってすべての列が要求されるため、出
力には manufact 表および stock 表の manu_code 列が含まれます。
追加の制約がある等価結合として、結合された列の値の等価性に比較条件
が基づく等価結合を作成することもできます。このような結合は、WHERE
節に指定する比較条件に = 以外の関係演算子を使用します。
単純な SELECT 文 2-63
複数表 SELECT 文
結合された表の列が同じ名前を持つ場合、次の例に示すように、列の前に
特定の表の名前とピリオドを指定する必要があります。
SELECT order_num, order_date, ship_date, cust_calls.*
FROM orders, cust_calls
WHERE call_dtime >= ship_date
AND cust_calls.customer_num = orders.customer_num
ORDER BY customer_num
2-64 単純な SELECT 文
複数表 SELECT 文
この SELECT 文は、customer_num 列で結合し、cust_calls 表の call_dtime が
orders 表の ship_date 以上である行のみを選択します。次の行が戻されま
す。
order_num
order_date
ship_date
customer_num
call_dtime
user_id
call_code
call_descr
res_dtime
res_descr
1004
05/22/1991
05/30/1991
106
1991-06-12 08:20
maryj
D
Order received okay, but two of the cans of
ANZ tennis balls within the case were empty
1991-06-12 08:25
Authorized credit for two cans to customer,
issued apology. Called ANZ buyer to report
the qa problem.
order_num
order_date
ship_date
customer_num
call_dtime
user_id
call_code
call_descr
res_dtime
res_descr
1008
06/07/1991
07/06/1991
110
1991-07-07 10:24
richc
L
Order placed one month ago (6/7) not received.
1991-07-07 10:30
Checked with shipping (Ed Smith). Order out
yesterday-was waiting for goods from ANZ.
Next time will call with delay if necessary.
order_num
order_date
ship_date
customer_num
call_dtime
user_id
call_code
call_descr
1023
07/24/1991
07/30/1991
127
1991-07-31 14:30
maryj
I
Received Hero watches (item # 304) instead
of ANZ watches
res_dtime
res_descr
Sent memo to shipping to send ANZ item 304
to customer and pickup HRO watches. Should
be done tomorrow, 8/1
自然結合
自然結合は、次の例のように、結合列がデータを冗長に表示しないように
構成されています
SELECT manu_name, lead_time, stock.*
FROM manufact, stock
WHERE manufact.manu_code = stock.manu_code
単純な SELECT 文 2-65
複数表 SELECT 文
前の例と同じように、この SELECT 文は manu_code 列で manufact 表と
stock 表を結合しますが、選択リストがさらに明確に定義されるため、
manu_code は抽出する各行に対して 1 回のみリストされます。
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
Smith
3
1
SMT
baseball gloves
$450.00
case
10 gloves/case
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
Smith
3
5
SMT
tennis racquet
$25.00
each
each
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
Smith
3
6
SMT
tennis ball
$36.00
case
24 cans/case
manu_name
lead_time
stock_num
manu_code
description
unit_price
unit
unit_descr
.
.
.
2-66 単純な SELECT 文
Anza
5
5
ANZ
tennis racquet
$19.80
each
each
複数表 SELECT 文
すべての結合には結合性 があり、WHERE 節の結合条件の順序は結合の意味
に影響を与えません。
SELECT catalog.*, description, unit_price, unit, unit_descr
FROM catalog, stock
WHERE catalog.stock_num = stock.stock_num
AND catalog.manu_code = stock.manu_code
AND catalog_num = 10017
SELECT catalog.*, description, unit_price, unit, unit_descr
FROM catalog, stock
WHERE catalog_num = 10017
AND catalog.manu_code = stock.manu_code
AND catalog.stock_num = stock.stock_num
これらの SELECT 文は、同じ自然結合を作成し、次の行を抽出します。
catalog_num 10017
stock_num
101
manu_code
PRC
cat_descr
Reinforced, hand-finished tubular. Polyurethane belted.
Effective against punctures. Mixed tread for super wear
and road grip.
cat_picture <BYTE value>
cat_advert
description
unit_price
unit
unit_descr
Ultimate in Puncture Protection, Tires
Designed for In-City Riding
bicycle tires
$88.00
box
4/box
この表示には、テキスト (TEXT) 型列 cat_descr、バイト (BYTE) 型列
cat_picture、および可変長文字 (VARCHAR) 型列 cat_advert が含まれていま
す。
単純な SELECT 文 2-67
複数表 SELECT 文
複数表結合
複数表結合は、1 つまたは複数の関連列で複数の表を結合します。この場
合、等価結合または自然結合にすることができます。
SELECT * FROM catalog, stock, manufact
WHERE catalog.stock_num = stock.stock_num
AND stock.manu_code = manufact.manu_code
AND catalog_num = 10025
この SELECT 文は、catalog 表、stock 表、および manufact 表の等価結合を
作成し、次の行を抽出します。
catalog_num 10025
stock_num
106
manu_code
PRC
cat_descr
Hard anodized alloy with pearl finish; 6mm hex bolt hardware.
Available in lengths of 90-140mm in 10mm increments.
cat_picture <BYTE value>
cat_advert
stock_num
manu_code
description
unit_price
unit
unit_descr
manu_code
manu_name
lead_time
ProCycle Stem with Pearl Finish
106
PRC
bicycle stem
$23.00
each
each
PRC
ProCycle
9
manu_code は表ごとに 1 回ずつ、3 回繰り返され、stock_num は 2 回繰り返
されます。
複数行の問合せの前の例にはかなり重複があるため、特定の列を選択リス
トに含めることによって、SELECT 文をさらに明確に定義することをお勧め
します。
2-68 単純な SELECT 文
複数表 SELECT 文
SELECT catalog.*, description, unit_price, unit,
unit_descr, manu_name, lead_time
FROM catalog, stock, manufact
WHERE catalog.stock_num = stock.stock_num
AND stock.manu_code = manufact.manu_code
AND catalog_num = 10025
この SELECT 文は、ワイルドカードを使用して、ほとんどの列がある表か
らすべての列を選択し、他の 2 つの表から特定の列を指定します。この
SELECT 文は、前の例と同じ情報を表示する、重複のない次の自然結合を作
成します。
catalog_num 10025
stock_num
106
manu_code
PRC
cat_descr
Hard anodized alloy with pearl finish. 6mm hex bolt hardware.
Available in lengths of 90-140mm in 10mm increments.
cat_picture <BYTE value>
cat_advert
description
unit_price
unit
unit_descr
manu_name
lead_time
ProCycle Stem with Pearl Finish
bicycle stem
$23.00
each
each
ProCycle
9
単純な SELECT 文 2-69
複数表 SELECT 文
問合せのショートカット
別名、INTO TEMP 節、および表示ラベルを使用して、結合と複数表問合せ
を迅速化し、他の用途のための出力を作成します。
別名の使用方法
SELECT 文の表に別名 を割り当てることによって、複数表問合せを短縮し、
読みやすくすることができます。別名は、FROM 節で表名の直後に続く語
です。例えば、他の節の列名のプレフィックスとして表名を使用するたび
に、別名を使用できます。
SELECT s.stock_num, s.manu_code, s.description,
s.unit_price, s.unit, c.catalog_num,
c.cat_descr, c.cat_advert, m.lead_time
FROM stock s, catalog c, manufact m
WHERE s.stock_num = c.stock_num
AND s.manu_code = c.manu_code
AND s.manu_code = m.manu_code
AND s.manu_code IN ("HRO", "HSK")
AND s.stock_num BETWEEN 100 AND 301
ORDER BY catalog_num
SELECT 文の結合性により、定義する前に別名を使用することができます。
この例では、stock 表の別名 s、catalog 表の別名 c、および manufact 表の別
名 m は、FROM 節に指定され、列プレフィックスとして SELECT 節および
WHERE 節で使用されます。
前の SELECT 文の長さを、別名を使用しない次の SELECT 文の長さと比較
してください。
SELECT stock.stock_num, stock.manu_code, stock.description,
stock.unit_price, stock.unit, catalog.catalog_num,
catalog.cat_descr, catalog.cat_advert,
manufact.lead_time
FROM stock, catalog, manufact
WHERE stock.stock_num = catalog.stock_num
AND stock.manu_code = catalog.manu_code
AND stock.manu_code = manufact.manu_code
AND stock.manu_code IN ("HRO", "HSK")
AND stock.stock_num BETWEEN 100 AND 301
ORDER BY catalog_num
2-70 単純な SELECT 文
複数表 SELECT 文
これらの 2 つの SELECT 文は同等で、次のデータを抽出します。
stock_num
110
manu_code
HRO
description helmet
unit_price
$260.00
unit
case
catalog_num 10033
cat_descr
Newest ultralight helmet uses plastic shell. Largest ventilation
channels of any helmet on the market. 8.5 oz.
cat_advert
Lightweight Plastic Slatted with Vents Assures Cool
Comfort Without Sacrificing Protection
lead_time
4
stock_num
110
manu_code
HSK
description helmet
unit_price
$308.00
unit
each
catalog_num 10034
cat_descr
Aerodynamic (teardrop) helmet covered with anti-drag fabric.
Credited with shaving 2 seconds/mile from winner’s time in
Tour de France time-trial. 7.5 oz.
cat_advert
Teardrop Design Endorsed by Yellow Jerseys,
You Can Time the Difference
lead_time
5
stock_num
205
manu_code
HRO
description 3 golf balls
unit_price
$312.00
unit
each
catalog_num 10048
cat_descr
Combination fluorescent yellow and standard white.
cat_advert
HiFlier Golf Balls: Case Includes Fluorescent
Yellow and Standard White
lead_time
4
stock_num
301
manu_code
HRO
description running shoes
unit_price
$42.50
unit
each
catalog_num 10050
cat_descr
Engineered for serious training with exceptional stability.
Fabulous shock absorption. Great durability. Specify
mens/womens, size.
cat_advert
Pronators and Supinators Take Heart: A Serious
Training Shoe For Runners Who Need Motion Control
lead_time
4
テキスト (TEXT) 型列 cat_descr または バイト (BYTE) 型列 cat_picture に対して
ORDER BY を指定することはできません。
単純な SELECT 文 2-71
複数表 SELECT 文
また、別名を使用して、外部データベースに常駐する外部表に対する問合
せを短縮することもできます。
SELECT order_num, lname, fname, phone
FROM masterdb@central:customer c, sales@western:orders o
WHERE c.customer_num = o.customer_num
AND order_num <= 1010
この SELECT 文は、現行のデータベースまたはシステムではない、異なる
データベースおよびシステムに常駐する 2 つの表の列を結合します。別名 c
および o を、ロング database@system:table ネームである
masterdb@central:customer と sales@western:orders にそれぞれ割り当てる
ことによって、別名を使用して WHERE 節の式を短縮し、この情報を抽出す
ることができます。
order_num lname
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
Higgins
Pauli
Higgins
Watson
Parmelee
Lawson
Sipes
Jaeger
Keyes
Grant
fname
phone
Anthony
Ludwig
Anthony
George
Jean
Margaret
Arnold
Roy
Frances
Alfred
415-368-1100
408-789-8075
415-368-1100
415-389-8789
415-534-8822
415-887-7235
415-245-4578
415-743-3611
408-277-7245
415-356-1123
外部表と外部データベースの詳細については、本書の第 12 章および
「IBM Informix SQL リファレンス・ガイド」を参照してください。
外部と現行の表およびビューのロング・ネームへの省略形参照として、シ
ノニム を使用することもできます。シノニムを作成および使用する方法の
詳細については、「IBM Informix SQL リファレンス・ガイド」の第 7 章の
CREATE SYNONYM 文の説明を参照してください。
2-72 単純な SELECT 文
複数表 SELECT 文
INTO TEMP 節
INTO TEMP 節を SELECT 文に追加することによって、データベースを変更す
ることなく問合せおよび操作できる別の表に、複数表問合せの結果を一時
的に保存することができます。一次表は、SQL セッションを終了するか、
またはプログラムかレポートが終了するときに削除されます。
SELECT DISTINCT stock_num, manu_name, description,
unit_price, unit_price * 1.05
FROM stock, manufact
WHERE manufact.manu_code = stock.manu_code
INTO TEMP stockman
この SELECT 文は、stockman と呼ばれる一時表を作成し、この表に問合せ
の結果を格納します。
stock_num manu_name
1
1
1
2
3
4
4
.
.
.
306
307
308
309
309
310
310
311
312
312
description
Hero
Husky
Smith
Hero
Husky
Hero
Husky
baseball
baseball
baseball
baseball
baseball
football
football
gloves
gloves
gloves
Shimara
ProCycle
ProCycle
Hero
Shimara
Anza
Shimara
Shimara
Hero
Shimara
tandem adapter
infant jogger
twin jogger
ear drops
ear drops
kick board
kick board
water gloves
racer goggles
racer goggles
bat
unit_price (expression)
$250.00
$800.00
$450.00
$126.00
$240.00
$480.00
$960.00
$262.5000
$840.0000
$472.5000
$132.3000
$252.0000
$504.0000
$1008.0000
$190.00
$250.00
$280.00
$40.00
$40.00
$84.00
$80.00
$48.00
$72.00
$96.00
$199.5000
$262.5000
$294.0000
$42.0000
$42.0000
$88.2000
$84.0000
$50.4000
$75.6000
$100.8000
この表を問い合わせて他の表と結合することによって、複数ソートを防止
し、データベース内を迅速に移動することができます。一時表の詳細につ
いては、本書の第 4 章に記載されています。
単純な SELECT 文 2-73
サマリー
サマリー
本章では、リレーショナル・データベースを問い合わせるために使用する
基本的な SELECT 文の構文の例と結果について説明しました。本章の前の
セクションでは、次の動作を実行する方法について説明しました。
•
SELECT 節および FROM 節を使用して、表からすべての列と行を選択す
•
•
SELECT 節および FROM 節を使用して、表から特定の列を選択する。
•
SELECT 節に DISTINCT または UNIQUE キーワードを使用して、問合せ結
果から重複行を除去する。
•
ORDER BY 節および DESC キーワードを使用して、抽出されたデータを
ソートする。
•
WHERE 節に BETWEEN、IN、MATCHES、および LIKE キーワードとさま
ざまな関係演算子を使用して、比較条件を作成する。
る。
SELECT 節、FROM 節、および WHERE 節を使用して、表から特定の行を
選択する。
• 値を含めたり、値を除外したり、値の範囲を検索したり ( キーワード、
関係演算子、およびサプスクリプト付けを使用 )、値のサブセットを検
索する比較条件を作成する。
• 正確なテキスト比較、可変長ワイルドカード、および制限付きと制限な
しのワイルドカードを使用して、変数テキスト検索を実行する。
• 論理演算子 AND、OR、および NOT を使用して、WHERE 節の検索条件ま
たはブール (BOOLEAN) 式を結合する。
•
•
ESCAPE キーワードを使用して、問合せの特殊文字を保護する。
•
SELECT 節に算術演算子を使用して、数値フィールドの計算を行い、導
出データを表示する。
WHERE 節に IS NULL および IS NOT NULL キーワードを指定して、NULL
値を検索する。
• サブ文字列およびサプスクリプト付けを使用して、問合せを目的に合わ
せて構成する。
• レポートのフォーマット・ツールとして計算された列に表示ラベルを割
り当てる。
•
SELECT 節に集計関数 COUNT、AVG、MAX、MIN、および SUM を使用し
て、特定のデータを計算および抽出する。
• 時刻関数 DATE、DAY、MDY、MONTH、WEEKDAY、YEAR、CURRENT、
EXTEND、および TODAY、LENGTH、USER 関数を SELECT 文に含める。
2-74 単純な SELECT 文
サマリー
本章では、複数の表からデータを選択して表示するための簡単な結合条件
についても説明しました。セクション “ 複数表 SELECT 文 ” では、次の操作
方法について説明しました。
• デカルト積を作成する。
• 問合せに有効な結合条件を使用して、WHERE 節を含めることによって
デカルト積を制限する。
• 自然結合および等価結合を定義して作成する。
• 1 つまたは複数の列で複数の表を結合する。
• 複数表問合せにショートカットとして別名を使用する。
• INTO TEMP 節を使用して、選択したデータを別の一時表に抽出し、デー
タベース外部で計算を実行する。
次の章では、さらに複雑な問合せと副問合せ、自己結合と外部結合、
GROUP BY 節と HAVING 節、および 和、積、差集合演算について説明します。
単純な SELECT 文 2-75
サマリー
2-76 単純な SELECT 文
高度な SELECT 文
概要 3
GROUP BY および HAVING 節の使用法 4
GROUP BY 節の使用法 4
HAVING 節の使用法 8
高度な結合の作成 10
自己結合 11
外部結合 19
単純結合 20
2 つの表に関する単純な外部結合 22
3 番目の表との単純結合による外部結合 24
3 番目の表との外部結合による外部結合 25
2 つの表と 3 番目の表との外部結合 27
SELECT 文内の副問合せ 29
ALL の使用法 30
ANY の使用法 31
一価副問合せ 32
相関副問合せ 33
EXISTS の使用法 34
集合演算 37
和 37
積 45
差 47
サマリー 48
第
3
章
3-2 高度な SELECT 文
概要
前の章では、SELECT 文を使用してリレーショナル・データベースからデー
タを抽出する基本的な方法について説明しました。本章では、この強力な
SQL 文を使用して実行できる作業範囲を拡大し、より複雑なデータベース
の問合せおよびデータ操作を実行できるようにします。
前の章では、SELECT 文の構文で使用される 5 つの節について重点的に説明
しましたが、本章ではさらに 2 つの節について説明します。GROUPBY 節を
集計関数と共に使用すると、FROM 節によって戻された行を編成すること
ができます。HAVING 節を指定すると、GROUPBY 節によって戻された値に
条件を設定できます。
本章では、前に説明した結合の内容について、より詳細に説明します。表
に表自体を結合できる自己結合、および複数の結合表を不均一に処理する
ためのキーワード OUTER を適用する 4 種類の外部結合 について説明しま
す。また、相関および無相関の副問合せ、これらの演算に関するキーワー
ド、UNION 演算子を使用して問合せを結合する方法、和、積、差と呼ばれ
る集合演算の定義についても説明します。
本章の例では、SELECT 文の節の一部か、またはすべてを問合せ内で使用す
る方法について説明します。これらの節は、次の順序で指定する必要があ
ります。
1. SELECT 節
2. FROM 節
3. WHERE 節
4. GROUP BY 節
5. HAVING 節
6. ORDER BY 節
7. INTO TEMP 節
IBM Informix 4GL 内のプログラムやホスト変数、および埋め込み言語製品を
指定するために使用できる SELECT 文の別の節 INTO については、本書の第
6 章および製品マニュアルで説明します。
高度な SELECT 文 3-3
GROUP BY および HAVING 節の使用法
GROUP BY および HAVING 節の使用法
オプションの GROUP BY 節および HAVING 節を指定すると、SELECT 文に機
能が追加されます。基本的な SELECT 文にこれらの節のいずれか、または
両方を指定すると、集合を操作する機能が向上します。
GROUP BY 節は類似の行を結合して、選択リスト内の各列で値が同じ行の
グループ ごとに結果行を 1 つ作成します。HAVING 節は、これらのグルー
プが形成された後に条件を設定します。GROUP BY 節を使用して HAVING
節を省略したり、HAVING 節を使用して GROUP BY 節を省略することができ
ます。
GROUP BY 節の使用法
GROUP BY 節は、表をいくつかの集合に分割します。通常、この節は、こ
れらの集合ごとに集計値を算出する集計関数と併用します。第 2 章の例の
一部に、表全体に適用される集計関数の使用法を示します。本章では、行
のグループに適用される集計関数を示します。
集計関数を使用しないで GROUP BY を使用することは、SELECT 節内で
DISTINCT ( または UNIQUE) キーワードを使用することとほぼ同じです。こ
の例については、第 2 章で説明しました。
SELECT DISTINCT customer_num FROM orders
この文は、次のように記述することもできます。
SELECT customer_num
FROM orders
GROUP BY customer_num
3-4 高度な SELECT 文
GROUP BY および HAVING 節の使用法
いずれの文も、次の行を戻します。
customer_num
101
104
106
110
111
112
115
116
117
119
120
121
122
123
124
126
127
GROUP BY 節は、収集した行をいくつかの集合にまとめて、各集合内のす
べての行で顧客番号が同じになるようにしています。その他の列は選択さ
れていないため、一意な customer_num 値のリストが作成されます。
GROUP BY 節は、集計関数と組み合わせて使用すると、より威力を発揮し
ます。
SELECT order_num, COUNT (*) number, SUM (total_price) price
FROM items
GROUP BY order_num
この SELECT 文は、注文ごとに品目数およびすべての品目の合計価格を抽
出します。GROUPBY 節を使用すると、items 表の行が収集されてグループ
( 各グループは同一の order_num 値を持つ行で構成される ) にまとめられま
す ( つまり、各注文の品目がグループ化されます )。グループが形成された
後で、集計関数 COUNT および SUM が各グループに適用されます。
高度な SELECT 文 3-5
GROUP BY および HAVING 節の使用法
この問合せは、それぞれのグループごとに 1 行を戻します。COUNT および
SUM 式の結果に名前を付けるために、次のようなラベルが使用されます。
order_num
number
price
1001
1002
1003
1004
1005
1006
1007
1008
.
.
.
1015
1016
1017
1018
1019
1020
1021
1022
1023
1
2
3
4
4
5
5
2
$250.00
$1200.00
$959.00
$1416.00
$562.00
$448.00
$1696.00
$940.00
1
4
3
5
1
2
4
3
6
$450.00
$654.00
$584.00
$1131.00
$1499.97
$438.00
$1614.00
$232.00
$824.00
SELECT 文は items 表の行を収集して、注文番号が同じであるグループにま
とめて、各グループの行の COUNT および価格の合計を計算します。
GROUP BY 節には、TEXT または BYTE データ型の列を指定できません。グ
ループ化 するには、ソート 可能である必要がありますが、TEXT または
BYTE データには自然なソート順がありません。
ORDER BY 節と異なり、GROUP BY 節はデータの並べ替えを行いません。
データを特定の順序でソートするか、または選択リスト内の集合に基づい
てソートする場合は、ORDER BY 節を GROUPBY 節の後に 指定します。
SELECT order_num, COUNT(*) number, SUM (total_price) price
FROM items
GROUP BY order_num
ORDER BY price
3-6 高度な SELECT 文
GROUP BY および HAVING 節の使用法
この問合せは、ORDER BY 節を追加し、抽出した行を price に基づいて昇順
にソートする点以外は、この前の問合せと同じです。
order_num
number
price
1010
1011
1013
1022
1001
1020
1006
1015
1009
.
.
.
1018
1002
1004
1014
1019
1021
1007
2
1
4
3
1
2
5
1
1
$84.00
$99.00
$143.80
$232.00
$250.00
$438.00
$448.00
$450.00
$450.00
5
2
4
2
1
4
5
$1131.00
$1200.00
$1416.00
$1440.00
$1499.97
$1614.00
$1696.00
前の章で説明したように、ORDER BY 節に整数を使用して、選択リスト内
の列の位置を指定することができます。同様に、GROUP BY 節に整数を使
用して、グループ・リスト内のグループ名または表示ラベルの位置を指定
することができます。
次の SELECT 文は、この前の問合せと同じ行を戻します。
SELECT order_num, COUNT(*) number, SUM (total_price) price
FROM items
GROUP BY 1
ORDER BY 3
SELECT 文を作成する場合、SELECT 節の選択リスト内にある集合以外のす
べての列が GROUPBY 節のグループ・リストにも含まれている必要があり
ます。これは、SELECT 文に GROUPBY を指定した場合、グループあたり 1
行のみが戻される必要があるためです。GROUP BY の後に指定された列に
は、1 グループに一意の値が 1 つ存在し、この値を戻すことができます。た
だし、GROUPBY の後に指定されていない列の値は、グループ内の各行で異
なる場合があります。
高度な SELECT 文 3-7
GROUP BY および HAVING 節の使用法
表を結合する SELECT 文で GROUP BY 節を使用することができます。
SELECT o.order_num, SUM (i.total_price)
FROM orders o, items i
WHERE o.order_date > "01/01/90"
AND o.customer_num = 110
AND o.order_num = i.order_num
GROUP BY o.order_num
この問合せは、orders および items 表を結合し、結合した表に別名を割り
当て、次の 2 つの行を戻します。
order_num
(sum)
1008
1015
$940.00
$450.00
HAVING 節の使用法
通常、HAVING 節はグループが形成された後に 1 つ以上の修飾条件を適用し
て GROUP BY 節を補足します。この方法は、WHERE 節が各行を修飾する方
法と似ています。HAVING 節を使用する利点の 1 つに、検索条件に集計関数
を指定できることがありますが、WHERE 節の検索条件には集計関数を指定
することができません。
各 HAVING 条件は、グループ内の特定の列または集計式をグループの別の
集計式または定数と比較します。HAVING を使用すると、グループ・リス
トの列の値および集計値の両方に条件を設定できます。
SELECT order_num, COUNT(*) number, AVG (total_price) average
FROM items
GROUP BY order_num
HAVING COUNT(*) > 2
3-8 高度な SELECT 文
GROUP BY および HAVING 節の使用法
この SELECT 文は、複数の品目を含むすべての注文に関して、品目あたり
の平均合計価格を戻します。HAVING 節は、グループ形成時に各グループ
をテストして、複数の行で構成されるグループを選択します。
order_num
number
average
1003
1004
1005
1006
1007
1013
1016
1017
1018
1021
1022
1023
3
4
4
5
5
4
4
3
5
4
3
6
$319.67
$354.00
$140.50
$89.60
$339.20
$35.95
$163.50
$194.67
$226.20
$403.50
$77.33
$137.33
HAVING 節を指定し、GROUP BY 節を指定しない場合、HAVING 条件は検索
条件を満たす行すべてに適用されます。つまり、検索条件を満たす行すべ
てが 1 つのグループを形成します。
SELECT AVG (total_price) average
FROM items
HAVING count(*) > 2
この文は、前の例を変更したバージョンであり、表内のすべての
total_price 値の平均を 1 行で戻します。
average
$270.97
この前の問合せと同様、この問合せでは、選択リスト内に集計関数でない
列 order_num が含まれているため、GROUPBY 節を追加し、グループ・リ
ストにこの列を指定する必要があります。また、HAVING 節内の条件が満
たされない場合は、列見出しおよび行が見つからなかったことを示すメッ
セージが表示されます。
高度な SELECT 文 3-9
高度な結合の作成
次の例には、対話型 SQL の Informix バージョンで使用できる SELECT 文の 7
つの節がすべて含まれています (INTO 節命名プログラムまたはホスト変数
は IBM Informix 4GL または埋め込み言語プログラムでのみ使用できます )。
SELECT o.order_num, SUM (i.total_price) price,
paid_date - order_date span
FROM orders o, items i
WHERE o.order_date > "01/01/90"
AND o.customer_num > 110
AND o.order_num = i.order_num
GROUP BY 1, 3
HAVING COUNT (*) < 5
ORDER BY 3
INTO TEMP temptab1
この SELECT 文は、orders と items 表を結合し、表示ラベル、表の別名、お
よび列を示すための整数を使用し、データをグループ化して並べ替え、次
の結果を一時表に格納します。
order_num
price
span
1017
1016
1012
1019
1005
1021
1022
1010
1009
1020
$584.00
$654.00
$1040.00
$1499.97
$562.00
$1614.00
$232.00
$84.00
$450.00
$438.00
26
28
30
40
66
68
71
高度な結合の作成
前の章では、SELECT 文に WHERE 文を指定して、1 つ以上の列に関して複
数の表を結合する方法について説明しました。また、自然結合および等価
結合についても説明しました。
本章では、より複雑な結合である自己結合および外部結合の使用法につい
て説明します。第 2 章で簡単な結合について説明したように、表の別名を
定義し、式に表示ラベルを割り当て、複数の表からなる問合せを短くまと
めることができます。ORDERBY 節および SELECT 問合せ結果を使用して
データをソートし、一時表に格納することもできます。
3-10 高度な SELECT 文
高度な結合の作成
自己結合
結合には、常に 2 つの表を使用する必要があるとは限りません。表を自分
自身に結合させて、自己結合 を作成することができます。自己結合は、列
内の値を同じ列内の他の値と比較する場合に便利です。
自己結合を作成するには、FROM 節内で特定の表を 2 回指定し、それぞれに
異なる別名を割り当てます。SELECT および WHERE 節内では、2 つの異な
る表であるかのようにこの表を別名で参照します (SELECT 文の別名につい
ては、本書の第 2 章、および「IBM Informix SQL リファレンス・ガイド」の第
7 章を参照してください )。
表間の結合と同様、自己結合でも算術式を使用することができます。NULL
値をテストしたり、指定された列を昇順または降順で並べ替える (ORDER
BY) ことができます。
SELECT x.order_num, x.ship_weight, x.ship_date,
y.order_num, y.ship_weight, y.ship_date
FROM orders x, orders y
WHERE x.ship_weight >= 5 * y.ship_weight
AND x.ship_date IS NOT NULL
AND y.ship_date IS NOT NULL
ORDER BY x.ship_date
この SELECT 文は、ship_weight が 5 倍以上異なり、かつ ship_date が NULL
でない注文のペアを検出し、日付を ship_date 順に並べ替えます。
order_num ship_weight ship_date
1004
1004
1004
1007
1007
1007
1007
1007
1007
1005
1005
1005
1012
1012
1013
1017
1018
.
.
.
95.80
95.80
95.80
125.90
125.90
125.90
125.90
125.90
125.90
80.80
80.80
80.80
70.80
70.80
60.80
60.00
70.50
05/30/1991
05/30/1991
05/30/1991
06/05/1991
06/05/1991
06/05/1991
06/05/1991
06/05/1991
06/05/1991
06/09/1991
06/09/1991
06/09/1991
06/29/1991
06/29/1991
07/10/1991
07/13/1991
07/13/1991
order_num ship_weight ship_date
1011
1020
1022
1015
1020
1022
1011
1001
1009
1011
1020
1022
1011
1020
1011
1011
1011
10.40
14.00
15.00
20.60
14.00
15.00
10.40
20.40
20.40
10.40
14.00
15.00
10.40
14.00
10.40
10.40
10.40
07/03/1991
07/16/1991
07/30/1991
07/16/1991
07/16/1991
07/30/1991
07/03/1991
06/01/1991
06/21/1991
07/03/1991
07/16/1991
07/30/1991
07/03/1991
07/16/1991
07/03/1991
07/03/1991
07/03/1991
高度な SELECT 文 3-11
高度な結合の作成
自己結合の結果を一時表に格納するとします。通常、INTO TEMP 節を
SELECT 文に追加します。ただし、実際は新規表を作成する作業であるた
め、少なくとも 1 つの列名セットに表示ラベルを割り当て、列を名前変更
する必要もあります。このようにしないと、列名の重複を示すエラー・
メッセージが表示され、一時表を作成できません。
SELECT x.order_num orders1, x.po_num purch1,
x.ship_date ship1, y.order_num orders2,
y.po_num purch2, y.ship_date ship2
FROM orders x, orders y
WHERE x.ship_weight >= 5 * y.ship_weight
AND x.ship_date IS NOT NULL
AND y.ship_date IS NOT NULL
INTO TEMP shipping
この SELECT 文はこの前の文と類似しており、orders 表から選択されたす
べての列にラベルを付け、shipping という名前の一時表に格納します。こ
の表 SELECT* を使用した場合は、次の行が表示されます。
orders1 purch1
1004
1004
1004
1005
1005
1005
1007
1007
1007
1007
1007
1007
1012
1012
1013
1017
1018
1018
1019
1019
1019
1023
3-12 高度な SELECT 文
8006
8006
8006
2865
2865
2865
278693
278693
278693
278693
278693
278693
278701
278701
B77930
DM354331
S22942
S22942
Z55709
Z55709
Z55709
KF2961
ship1
05/30/1991
05/30/1991
05/30/1991
06/09/1991
06/09/1991
06/09/1991
06/05/1991
06/05/1991
06/05/1991
06/05/1991
06/05/1991
06/05/1991
06/29/1991
06/29/1991
07/10/1991
07/13/1991
07/13/1991
07/13/1991
07/16/1991
07/16/1991
07/16/1991
07/30/1991
orders2 purch2
1011
1020
1022
1011
1020
1022
1001
1009
1011
1015
1020
1022
1011
1020
1011
1011
1011
1020
1011
1020
1022
1011
B77897
W2286
W9925
B77897
W2286
W9925
B77836
4745
B77897
MA003
W2286
W9925
B77897
W2286
B77897
B77897
B77897
W2286
B77897
W2286
W9925
B77897
ship2
07/03/1991
07/16/1991
07/30/1991
07/03/1991
07/16/1991
07/30/1991
06/01/1991
06/21/1991
07/03/1991
07/16/1991
07/16/1991
07/30/1991
07/03/1991
07/16/1991
07/03/1991
07/03/1991
07/03/1991
07/16/1991
07/03/1991
07/16/1991
07/30/1991
07/03/1991
高度な結合の作成
表と表自身との結合は、複数回行うことができます。自己結合の最大回数
は、使用可能な資源によって決定されます。
SELECT s1.manu_code, s2.manu_code, s3.manu_code,
s1.stock_num, s1.description
FROM stock s1, stock s2, stock s3
WHERE s1.stock_num = s2.stock_num
AND s2.stock_num = s3.stock_num
AND s1.manu_code < s2.manu_code
AND s2.manu_code < s3.manu_code
ORDER BY stock_num
この自己結合は、3 つのメーカーにより提供された stock 表内の品目のリス
トを作成します。WHERE 節に最後の 2 つの条件を追加すると、抽出された
行内の重複するメーカー・コードが除去されます。
manu_code manu_code manu_code stock_num description
HRO
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
HRO
HRO
HRO
HSK
ANZ
ANZ
ANZ
.
.
.
HRO
KAR
KAR
KAR
NKL
HSK
NRG
HRO
HRO
HRO
HSK
HSK
PRC
HSK
HSK
PRC
PRC
KAR
HRO
HRO
SMT
SMT
HSK
PRC
SHM
PRC
SHM
SHM
PRC
SHM
SHM
SHM
NKL
NKL
KAR
1
5
110
110
110
110
110
110
110
110
110
110
201
205
301
baseball gloves
tennis racquet
helmet
helmet
helmet
helmet
helmet
helmet
helmet
helmet
helmet
helmet
golf shoes
3 golf balls
running shoes
PRC
NKL
NKL
PRC
PRC
SHM
PRC
SHM
SHM
SHM
301
301
301
301
301
running
running
running
running
running
shoes
shoes
shoes
shoes
shoes
高度な SELECT 文 3-13
高度な結合の作成
給与計算表から行を選択して、マネージャーよりも所得の多い従業員を判
別するとします。次のような自己結合を作成できます。
SELECT emp.employee_num, emp.gross_pay, emp.level,
emp.dept_num, mgr.employee_num, mgr.gross_pay,
mgr.level
FROM payroll emp, payroll mgr
WHERE emp.gross_pay > mgr.gross_pay
AND emp.level < mgr.level
ORDER BY 4
次の自己結合の例は、相関副問合せ を使用して、価格の高い品目を上から
順に 10 個抽出してリストします。
SELECT order_num, total_price
FROM items a
WHERE 10 >
(SELECT COUNT (*)
FROM items b
WHERE b.total_price < a.total_price)
ORDER BY total_price
次の 10 の行が戻されます。
order_num total_price
1018
1013
1003
1005
1006
1013
1010
1013
1022
1023
$15.00
$19.80
$20.00
$36.00
$36.00
$36.00
$36.00
$40.00
$40.00
$40.00
同様の問合せを作成して、会社内で最も年齢の高い従業員を 10 人検索し、
リストすることができます。
相関副問合せおよび無相関副問合せについては、本章の後半で説明します。
3-14 高度な SELECT 文
高度な結合の作成
行 ID 値の使用法
自己結合内の非表示の rowid 列を使用すると、表内の重複値を特定できま
す。次の例では、条件 x.rowid != y.rowid は、「行 x は、行 y と同じ行ではな
い」ことを意味します。
SELECT x.rowid, x.customer_num
FROM cust_calls x, cust_calls y
WHERE x.customer_num = y.customer_num
AND x.rowid != y.rowid
この SELECT 文は、cust_calls 表からデータを 2 回選択し、
表の別名 x および y を割り当てます。customer_num 列内の重複値および行
ID を検索して、そのペアを見つけます。
rowid customer_num
515
769
116
116
この前の SELECT 文の最後の条件は、次のように記述することもできます。
AND x.rowid != y.rowid
または
AND NOT x.rowid = y.rowid
重複値を特定するもう 1 つの方法は、次のように相関副問合せを使用する
ことです。
SELECT x.customer_num, x.call_dtime
FROM cust_calls x
WHERE 1 <
(SELECT COUNT (*) FROM cust_calls y
WHERE x.customer_num = y.customer_num)
高度な SELECT 文 3-15
高度な結合の作成
この SELECT 文は、この前の問合せと同様、重複する同じ 2 つの
customer_num 値を特定し、これらの行を戻します。
customer_num call_dtime
116 1990-11-28 13:34
116 1990-12-21 11:24
自己結合ですでに示したように、行 ID を使用すると、データベース表内の
行に関連付けられた内部レコード番号を特定することができます。行 ID
は、実際は各表の非表示列です。連続する行 ID 値には特に重要な意味はな
く、チャンク内の物理データの位置によって変わることがあります。パ
フォーマンスに関する問題および行 ID 値については、本書の第 4 章を参照
してください。
SELECT rowid, * FROM manufact
この SELECT 文は、SELECT 節内で行 ID およびワイルドカード * を使用し
て、manufact 表内の各行および対応する行 ID を抽出します。
rowid manu_code manu_name
257
258
259
260
261
262
263
264
265
SMT
ANZ
NRG
HSK
HRO
SHM
KAR
NKL
PRC
Smith
Anza
Norge
Husky
Hero
Shimara
Karsten
Nikolus
ProCycle
lead_time
3
5
7
5
4
30
21
8
9
特定の列を選択するときに、行 ID を使用することもできます。
SELECT rowid, manu_code FROM manufact
3-16 高度な SELECT 文
高度な結合の作成
この SELECT 文により、次のような結果が戻されます。
rowid manu_code
258
261
260
263
264
259
265
262
257
ANZ
HRO
HSK
KAR
NKL
NRG
PRC
SHM
SMT
WHERE 節内で行 ID を使用して、内部レコード番号に基づいて行を抽出す
ることもできます。この方法は、表内に他に一意な列が存在しない場合に
便利です。
SELECT * FROM manufact WHERE rowid = 263
この SELECT 文は、行を 1 つのみ戻します。
manu_code manu_name
KAR
Karsten
lead_time
21
USER 機能の使用法
表に関する補足情報を取得する場合、行 ID と USER 機能、および
IBM Informix OnLine では SITENAME キーワードとを組み合わせることがで
きます。USER および SITENAME については、本書の第 2 章を参照してくだ
さい。
SELECT USER username, rowid FROM cust_calls
高度な SELECT 文 3-17
高度な結合の作成
この問合せは、ラベル username を USER 式列に割り当て、cust_calls 表に
関するこの情報を戻します。
username
rowid
zenda
zenda
zenda
zenda
zenda
zenda
zenda
257
258
259
513
514
515
769
また、行 ID を選択する場合は、WHERE 節内で USER 機能を使用することも
できます。
SELECT rowid FROM cust_calls WHERE user_id = USER
この問合せは、文を入力したユーザーが入力した行の行 ID のみを戻しま
す。例えば、ユーザー richc がこの SELECT 文を入力した場合、出力は次の
ようになります。
rowid
258
259
SITENAME 機能の使用法
現在データベースが格納されている場所を調べる場合は、DBSERVERNAME
キーワードを追加します。
SELECT DBSERVERNAME server, tabid, rowid, USER username
FROM systables
WHERE tabid >= 105 OR rowid <= 260
ORDER BY rowid
3-18 高度な SELECT 文
高度な結合の作成
この SELECT 文は、サーバー名、ユーザー名、行 ID、およびシステム・カ
タログ表のシリアル時間隔表識別子である標識別子 を検出します。DBSERVERNAME および USER 式に表示ラベルを割り当て、systables システム・カ
タログ表から次のような 10 行を戻します。
server
manatee
manatee
manatee
manatee
manatee
manatee
manatee
manatee
manatee
manatee
tabid
1
2
3
4
105
106
107
108
109
110
rowid username
257
258
259
260
274
1025
1026
1027
1028
1029
zenda
zenda
zenda
zenda
zenda
zenda
zenda
zenda
zenda
zenda
行 ID は変わることがあるため、永続 表に行 ID を格納したり、外部キーと
して使用しないでください。例えば、表が削除されて外部データから再
ロードされた場合は、行 ID はすべて異なる値になります。
外部結合
第 2 章では、単純結合の作成方法および使用方法について説明しました。
単純結合では結合された複数の表が均等に扱われますが、外部結合 では非
対称的 に扱われます。外部結合では、表の 1 つが主 表 ( または「保存表」)
となり、他の表が従 表になります。
外部結合には、次の 4 つの基本的なタイプがあります。
•
•
•
•
2 つの表に関する単純外部結合
3 番目の表との単純な外部結合
3 番目の表との単純結合による外部結合
3 番目の表との外部結合による外部結合
このセクションでは、これらの 4 つの外部結合タイプについて説明します。
これらの構文、使用法、ロジックの詳細は、「IBM Informix SQL リファレン
ス・ガイド」の第 7 章の外部結合に関する説明を参照してください。
単純結合 では、表の行のうち、結合条件を満たす組合せのみが結果に含ま
れます。結合条件を満たさない行は、廃棄されます。
高度な SELECT 文 3-19
高度な結合の作成
外部結合 では、表の行のうち結合条件を満たす組合せのみが結果に含まれ
ます。一致する行が従表にない場合にも、本来廃棄されるはずの主表の行
は保持されます。一致する行が従表にない主表の行には、NULL 行が設定
され、その後、選択された列が射影されます。
外部結合は、従表に条件を適用し、同時に主表の行に結合条件を順次適用
します。条件は、WHERE 節で表されます。
外部結合には、SELECT 節、FROM 節、および WHERE 節を指定する必要があ
ります。単純結合を外部結合に変換するには、FROM 節内の従表の名前の
直前にキーワード OUTER を挿入します。このセクションの後半で説明する
ように、OUTER キーワードは問合せ内に複数回挿入することができます。
外部結合を多数使用する前に、1 つまたは複数の単純結合で代用できるか
どうかを判別する必要があります。通常、その他の表の補足情報が必要な
い場合は、単純結合で間に合わせることができます。
このセクションの例では、簡単にするために、表の別名を使用しています。
表の別名については、前の章を参照してください。
単純結合
次の例は、本書の第 2 章で説明する customer および cust_calls 表の単純結
合タイプを示します。
SELECT c.customer_num, c.lname, c.company,
c.phone, u.call_dtime, u.call_descr
FROM customer c, cust_calls u
WHERE c.customer_num = u.customer_num
この問合せは、カスタマー・サービスに電話をかけたカスタマーに関する
行のみを戻します。
3-20 高度な SELECT 文
高度な結合の作成
customer_num
lname
company
phone
call_dtime
call_descr
106
Watson
Watson & Son
415-389-8789
1991-06-12 08:20
Order was received, but two of the cans of
ANZ tennis balls within the case were empty
customer_num
lname
company
phone
call_dtime
call_descr
110
Jaeger
AA Athletics
415-743-3611
1991-07-07 10:24
Order placed one month ago (6/7) not received.
customer_num
lname
company
phone
call_dtime
call_descr
119
Shorter
The Triathletes Club
609-663-6079
1991-07-01 15:00
Bill does not reflect credit from previous order
customer_num
lname
company
phone
call_dtime
call_descr
121
Wallack
City Sports
302-366-7511
1991-07-10 14:05
Customer likes our merchandise. Requests that we
stock more types of infant joggers. Will call back
to place order.
customer_num
lname
company
phone
call_dtime
call_descr
127
Satifer
Big Blue Bike Shop
312-944-5691
1991-07-31 14:30
Received Hero watches (item # 304) instead of
ANZ watches
customer_num
lname
company
phone
call_dtime
call_descr
116
Parmelee
Olympic City
415-534-8822
1990-11-28 13:34
Received plain white swim caps (313 ANZ) instead
of navy with team logo (313 SHM)
customer_num
lname
company
phone
call_dtime
call_descr
116
Parmelee
Olympic City
415-534-8822
1990-12-21 11:24
Second complaint from this customer! Received
two cases right-handed outfielder gloves (1 HRO)
instead of one case lefties.
高度な SELECT 文 3-21
高度な結合の作成
2 つの表に関する単純な外部結合
次の例では、前の例と同じ選択リスト、表、および比較条件を使用します
が、ここでは単純外部結合を作成します。
SELECT c.customer_num, c.lname, c.company,
c.phone, u.call_dtime, u.call_descr
FROM customer c, OUTER cust_calls u
WHERE c.customer_num = u.customer_num
cust_calls 表の前にキーワード OUTER が追加されているため、この表は従
表になります。外部結合が設定されているため、カスタマーがカスタ
マー・サービスに電話をかけたかどうかに関係なく、問合せは すべての カ
スタマーに関する情報を戻します。主表である customer 表のすべての行が
抽出され、従表 cust_calls 表の対応する行に NULL 値が割り当てられます。
3-22 高度な SELECT 文
高度な結合の作成
customer_num
lname
company
phone
call_dtime
call_descr
101
Pauli
All Sports Supplies
408-789-8075
customer_num
lname
company
phone
call_dtime
call_descr
102
Sadler
Sports Spot
415-822-1289
customer_num
lname
company
phone
call_dtime
call_descr
103
Currie
Phil’s Sports
415-328-4543
customer_num
lname
company
phone
call_dtime
call_descr
104
Higgins
Play Ball!
415-368-1100
customer_num
lname
company
phone
call_dtime
call_descr
105
Vector
Los Altos Sports
415-776-3249
customer_num
lname
company
phone
call_dtime
call_descr
106
Watson
Watson & Son
415-389-8789
1991-06-12 08:20
Order was received, but two of the cans of
ANZ tennis balls within the case were empty
customer_num
lname
company
phone
call_dtime
call_descr
107
Ream
Athletic Supplies
415-356-9876
customer_num
lname
company
phone
call_dtime
call_descr
108
Quinn
Quinn’s Sports
415-544-8729
.
.
.
高度な SELECT 文 3-23
高度な結合の作成
3 番目の表との単純結合による外部結合
次の例では、3 番目の表との単純結合によって作成される外部結合を示し
ます。この 2 番目の外部結合タイプは、入れ子になった単純結合 と呼びま
す。
SELECT c.customer_num, c.lname, o.order_num,
i.stock_num, i.manu_code, i.quantity
FROM customer c, OUTER (orders o, items i)
WHERE c.customer_num = o.customer_num
AND o.order_num = i.order_num
AND manu_code IN ("KAR", "SHM")
ORDER BY lname
この SELECT 文は、最初に orders および items 表に単純結合を実行してか
ら、manu_code が KAR または SHM である品目のすべての注文情報を抽出
します。次に、外部結合を実行して、この情報を主表である customer 表の
データと組み合わせます。オプションの ORDER BY 節を指定すると、デー
タが次の形式に並べ替えられます。
customer_num lname
114
118
113
103
115
123
123
125
104
110
120
120
111
112
128
109
126
122
116
101
124
108
107
102
127
127
127
119
117
105
121
106
3-24 高度な SELECT 文
Albertson
Baxter
Beatty
Currie
Grant
Hanlon
Hanlon
Henry
Higgins
Jaeger
Jewell
Jewell
Keyes
Lawson
Lessor
Miller
Neelie
O’Brian
Parmelee
Pauli
Putnum
Quinn
Ream
Sadler
Satifer
Satifer
Satifer
Shorter
Sipes
Vector
Wallack
Watson
order_num stock_num manu_code quantity
1020
1020
301 KAR
204 KAR
4
2
1017
1017
202 KAR
301 SHM
1
2
1019
111 SHM
3
1021
202 KAR
3
1023
1023
1023
1016
306
105
110
101
SHM
SHM
SHM
SHM
1
1
1
2
1018
302 KAR
3
高度な結合の作成
3 番目の表との外部結合による外部結合
この SELECT 文は、3 番目の表との外部結合によって外部結合を作成しま
す。この 3 番目のタイプは、入れ子になった外部結合 と呼びます。
SELECT c.customer_num, lname, o.order_num,
stock_num, manu_code, quantity
FROM customer c, OUTER (orders o, OUTER items i)
WHERE c.customer_num = o.customer_num
AND o.order_num = i.order_num
AND manu_code IN ("KAR", "SHM")
ORDER BY lname
この問合せは、最初に orders および items 表に関する外部結合を実行して
から、manu_code が KAR または SHM である品目に関するすべての注文情
報を抽出します。次に、この情報を主表である customer 表のデータと組み
合わせる外部結合を実行します。この問合せでは、この前の例で除去され
た注文番号が保持されており、いずれかのメーカー・コードに対応する品
目を含まない注文行を戻します。オプションの ORDER BY 節を指定すると、
データが再編成されます。
高度な SELECT 文 3-25
高度な結合の作成
customer_num lname
114
118
113
103
115
123
123
125
104
104
104
104
110
110
120
120
111
112
128
109
126
122
116
101
124
108
107
102
127
127
127
119
117
117
105
121
106
106
Albertson
Baxter
Beatty
Currie
Grant
Hanlon
Hanlon
Henry
Higgins
Higgins
Higgins
Higgins
Jaeger
Jaeger
Jewell
Jewell
Keyes
Lawson
Lessor
Miller
Neelie
O’Brian
Parmelee
Pauli
Putnum
Quinn
Ream
Sadler
Satifer
Satifer
Satifer
Shorter
Sipes
Sipes
Vector
Wallack
Watson
Watson
order_num stock_num manu_code quantity
1010
1020
1020
204 KAR
301 KAR
2
4
301 SHM
202 KAR
2
1
111 SHM
3
202 KAR
3
1023
1023
1023
1016
1012
1007
110
105
306
101
SHM
SHM
SHM
SHM
1
1
1
2
1018
1014
1004
302 KAR
3
1011
1001
1013
1003
1008
1015
1017
1017
1009
1006
1022
1019
1005
1002
1021
3 番目の表との外部結合の結果に外部結合を適用する場合は、2 つの方法で
結合条件を指定できます。2 つの従表は結合されますが、主表と従表が共
通の列を共有している場合は、主表をいずれの従表と結合しても結果は変
わりません。
3-26 高度な SELECT 文
高度な結合の作成
2 つの表と 3 番目の表との外部結合
次に示す SELECT 文は、2 つの表を 3 番目の表とそれぞれ外部結合すること
によって作成される外部結合を示します。この 4 番目の外部結合タイプで
は、結合関係は主表と従表の間でのみ 有効です。
SELECT c.customer_num, lname, o.order_num,
order_date, call_dtime
FROM customer c, OUTER orders o, OUTER cust_calls x
WHERE c.customer_num = o.customer_num
AND c.customer_num = x.customer_num
INTO TEMP service
この問合せは、従表 orders および cust_calls を主表 customer 表に個別に結
合します。2 つの従表は結合しません。INTOTEMP 節は、結果を選択して一
時表に格納し、さらに、操作または問合せを実行できるようにします。
高度な SELECT 文 3-27
高度な結合の作成
customer_num lname
114
118
113
103
115
123
125
104
104
104
104
110
110
120
111
112
109
128
126
122
116
116
101
124
108
107
102
127
119
117
117
105
121
106
106
Albertson
Baxter
Beatty
Currie
Grant
Hanlon
Henry
Higgins
Higgins
Higgins
Higgins
Jaeger
Jaeger
Jewell
Keyes
Lawson
Miller
Moore
Neelie
O’Brian
Parmelee
Parmelee
Pauli
Putnum
Quinn
Ream
Sadler
Satifer
Shorter
Sipes
Sipes
Vector
Wallack
Watson
Watson
order_num order_date call_dtime
1010 06/17/1991
1020 07/11/1991
1003
1001
1013
1011
1015
1008
1017
1009
1006
05/22/1991
05/20/1991
06/22/1991
06/18/1991
06/27/1991 1991-07-07 10:24
06/07/1991 1991-07-07 10:24
07/09/1991
06/14/1991
05/30/1991
1022
1019
1005
1005
1002
1021
07/24/1991
07/11/1991
05/24/1991 1990-12-21 11:24
05/24/1991 1990-11-28 13:34
05/21/1991
07/23/1991
1023
1016
1007
1012
07/24/1991 1991-07-31 14:30
06/29/1991 1991-07-01 15:00
05/31/1991
06/18/1991
1018 07/10/1991 1991-07-10 14:05
1004 05/22/1991 1991-06-12 08:20
1014 06/25/1991 1991-06-12 08:20
前の SELECT 文を使用して、2 つの従表 o および x の間の結合条件を作成し
ようとすると、次の例のように、両面外部結合が作成されたことを示すエ
ラー・メッセージが表示されます。
WHERE o.customer_num = x.customer_num
3-28 高度な SELECT 文
SELECT 文内の副問合せ
SELECT 文内の副問合せ
別の SELECT 文内 ( または INSERT、DELETE、UPDATE 文内 ) の WHERE 節で
入れ子 になっている SELECT 文は、副問合せ といいます。副問合せには、
それぞれ SELECT 節および FROM 節を指定し、データベース・サーバーに
この操作を最初に実行するように指示するために、括弧で囲む必要があり
ます。
副問合せは、相関 または無相関 のいずれかになります。副問合せ ( 内部
SELECT 文 ) によって生成される値が、この値を囲む 外部 SELECT 文の値に
よって決定される場合、この副問合せは相関です。その他の種類の副問合
せはすべて無相関です。
相関副問合せの重要な機能は、外部 SELECT の値に依存するため、外部
SELECT によって生成される値ごとに繰り返し実行する必要があることで
す。無相関副問合せは、一度だけ実行されます。
通常、2 つの異なる SELECT 文の代わりに、副問合せを含む SELECT 文を構
築することができます。
SELECT 文内の副問合せを使用すると、次の処理を行うことができます。
• 別の SELECT 文の結果と式を比較する。
• 式が別の SELECT 文の結果に含まれているかどうかを判別できる。
• 行が SELECT 文によって選択されているかどうかを判別できる。
副問合せ内のオプションの WHERE 節は、通常、検索条件を絞り込むために
使用されます。
副問合せは、最初または外部の SELECT 文の値を選択したり、戻します。
副問合せは、0、1 つ、または複数の値を戻すことがあります。
• 副問合せが値を戻さない 場合、問合せも行をまったく戻さない。この
ような副問合せは、NULL 値と同等です。
• 値を 1 つ 戻す副問合せは、集計式を 1 つ戻すか、または特定の行の特定
の列を選択する。このような副問合せは、単一の数値または文字値と同
等です。
• 値のリストまたは一連の 値を戻す副問合せは、1 行、または 1 列を戻
す。
次のキーワードは、SELECT 文内の WHERE 節内に副問合せを導入します。
•
•
•
•
ALL
ANY
IN
EXISTS
高度な SELECT 文 3-29
SELECT 文内の副問合せ
ALL および ANY に任意の関係演算子を使用すると、特定の値を、副問合せ
が生成するすべての値と比較したり (ALL)、副問合せが生成するいずれか
の値と比較する (ANY) ことができます。ANY の代わりに キーワード SOME
を使用することができます。演算子 IN は、=ANY と同等です。反対の意味
の検索条件を作成するには、キーワード NOT または別の関係演算子を使用
します。
EXISTS 演算子は、何らかの値が戻されるかどうか、つまり結果が NULL で
ないかどうかを副問合せに対してテストします。
副問合せを指定して条件を作成する場合に使用する構文の詳細は、
「IBM Informix SQL リファレンス・ガイド」の第 7 章を参照してください。ま
た、相関および無相関副問合せのパフォーマンスの影響については、本書
の第 4 章を参照してください。
ALL の使用法
戻されるすべての値について比較が true であるかどうかを判別するには、
キーワード ALL を副問合せの前に使用します。副問合せが値を戻さない場
合、検索条件は true です ( 値を戻さない場合、値はすべてのゼロ値になり、
条件は true になります )。
SELECT order_num, stock_num, manu_code, total_price
FROM items
WHERE total_price < ALL
(SELECT total_price FROM items
WHERE order_num = 1023)
この SELECT 文は、注文番号が 1023 であるすべての 品目の合計価格よりも
合計価格が小さい品目を含むすべての注文に対して、次の情報をリストし
ます。
order_num stock_num manu_code total_price
1003
1005
1006
1010
1013
1013
1018
3-30 高度な SELECT 文
9
6
6
6
5
6
302
ANZ
SMT
SMT
SMT
ANZ
SMT
KAR
$20.00
$36.00
$36.00
$36.00
$19.80
$36.00
$15.00
SELECT 文内の副問合せ
ANY の使用法
戻された値の少なくとも 1 つに対して比較が true であるかどうかを判別す
るには、キーワード ANY ( またはシノニム SOME) を副問合せの前に指定し
ます。副問合せが値を戻さない場合、検索条件は false です ( 値がないた
め、これらの 1 つに対して条件が true となることはありません )。
SELECT DISTINCT order_num
FROM items
WHERE total_price > ANY
(SELECT total_price
FROM items
WHERE order_num = 1005)
この問合せは、注文番号が 1005 である品目のいずれか 1 つ の合計価格より
も合計価格が大きい品目を含むすべての注文に対して、注文番号を検索し
ます。
order_num
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
高度な SELECT 文 3-31
SELECT 文内の副問合せ
一価副問合せ
副問合せが外部副問合せに必ず 1 つの値 を戻すことがわかっている場合は、
キーワード ALL または ANY を指定する必要はありません。必ず 1 つの値を
戻す副問合せは、関数と同様に処理することができます。通常、この種類
の副問合せには、常に単一の値を戻す集計関数が使用されます。
SELECT order_num FROM items
WHERE stock_num = 9
AND quantity =
(SELECT MAX (quantity)
FROM items
WHERE stock_num = 9)
この SELECT 文は、副問合せ内で集計関数 MAX を使用して、最大のバレー
ボール・ネット数を持つ注文の order_num を検索します。次の行が戻され
ます。
order_num
1012
次の例では、副問合せ内で集計関数 MIN を使用して、合計価格が最小価格
の 10 倍よりも大きい品目を選択します。
SELECT order_num, stock_num, manu_code, total_price
FROM items x
WHERE total_price >
(SELECT 10 * MIN (total_price)
FROM items
WHERE order_num = x.order_num)
次の行が抽出されます。
order_num stock_num manu_code
1003
1018
1018
1018
3-32 高度な SELECT 文
8
307
110
304
ANZ
PRC
PRC
HRO
total_price
$840.00
$500.00
$236.00
$280.00
SELECT 文内の副問合せ
相関副問合せ
次の相関副問合せの例は、orders 表内の項目のうち、出荷日が早い項目を
10 個戻します。副問合せ内には ORDER BY を指定することができないため、
この例では、副問合せの後に ORDER BY 節を配置して結果を並べ替えてい
ます。
SELECT po_num, ship_date FROM orders main
WHERE 10 >
(SELECT COUNT (DISTINCT ship_date)
FROM orders sub
WHERE sub.ship_date > main.ship_date)
AND ship_date IS NOT NULL
ORDER BY ship_date, po_num
副問合せが生成する数値は外部 SELECT によって生成される値
main.ship_date に依存するため、この副問合せは相関です。したがって、
外部問合せが各行を新規に処理するたびに、この副問合せを実行する必要
があります。
この副問合せは COUNT 関数を使用して、メインの問合せに値を戻します。
次に、ORDER BY 節を使用してデータを並べ替えます。この問合せは、最
新の 10 の出荷日から 13 の行を戻します。
po_num
ship_date
4745
278701
429Q
8052
B77897
LZ230
B77930
PC6782
DM354331
S22942
MA003
W2286
Z55709
C3288
KF2961
W9925
06/21/1991
06/29/1991
06/29/1991
07/03/1991
07/03/1991
07/06/1991
07/10/1991
07/12/1991
07/13/1991
07/13/1991
07/16/1991
07/16/1991
07/16/1991
07/25/1991
07/30/1991
07/30/1991
高度な SELECT 文 3-33
SELECT 文内の副問合せ
膨大な表に関してこの前の例のような相関副問合せを使用する場合、
ship_date 列を索引付けしてパフォーマンスを改善する必要があります。こ
のようにしないと、この SELECT 文は、表の各行ごとに副問合せを 1 回ずつ
実行するため、効率が低下する可能性があります。索引付けおよびパ
フォーマンスの問題については、本書の第 10 章を参照してください。
EXISTS の使用法
キーワード EXISTS を指定すると、外部 SELECT 文が行を少なくとも 1 つ検
索した場合にのみ副問合せが true になるため、このキーワードは存在作用
素 と呼ばれます。
SELECT UNIQUE manu_name, lead_time
FROM manufact
WHERE EXISTS
(SELECT * FROM stock
WHERE description MATCHES "*shoe*"
AND manufact.manu_code = stock.manu_code)
通常、IN を使用する問合せと同等の問合せを、EXISTS を使用して構築する
ことができます。IN の代わりに =ANY を使用することもできます。
SELECT UNIQUE manu_name, lead_time
FROM stock, manufact
WHERE manufact.manu_code IN
(SELECT manu_code FROM stock
WHERE description MATCHES "*shoe*")
AND stock.manu_code = manufact.manu_code
上記の問合せは、両方とも 2 つの行 ( 特定の種類の靴を製造するメーカー
およびこの製品の注文に関するリード・タイム ) を戻します。
manu_name
Anza
Hero
Karsten
Nikolus
ProCycle
Shimara
lead_time
5
4
21
8
9
30
TEXT または BYTE データ型を持つ列を含む副問合せには、述部 IN を使用
することはできません。
3-34 高度な SELECT 文
SELECT 文内の副問合せ
この前の問合せのいずれかと反対の検索条件を作成するには、キーワード
NOT を IN または EXISTS に追加します。NOT IN の代わりに !=ALL を使用す
ることもできます。
次に、同じ処理を行う 2 つの異なる方法を示します。データベースの設計
および表のサイズによっては、いずれかの方法を使用することで、もう 1
つの方法よりもデータベース・サーバーの作業量を少なくすることができ
ます。より適切な問合せを見つけるには、SET EXPLAIN コマンドを使用し
て、問合せ予定のリストを取得してください。SET EXPLAIN については、本
書の第 4 章、または「IBM Informix SQL リファレンス・ガイド」の第 7 章を参
照してください。
SELECT customer_num, company FROM customer
WHERE customer_num NOT IN
(SELECT customer_num FROM orders
WHERE customer.customer_num = orders.customer_num)
SELECT customer_num, company FROM customer
WHERE NOT EXISTS
(SELECT * FROM orders
WHERE customer.customer_num = orders.customer_num)
上記の文は両方とも、注文をまだ行っていないカスタマーを識別する、次
のような 11 の行を戻します。
customer_num company
102
103
105
107
108
109
113
114
118
125
128
Sports Spot
Phil’s Sports
Los Altos Sports
Athletic Supplies
Quinn’s Sports
Sport Stuff
Sportstown
Sporting Place
Blue Ribbon Sports
Total Fitness Sports
Phoenix University
キーワード EXISTS および IN は、積 と呼ばれる集合演算に使用され、キー
ワード NOT EXISTS および NOT IN は差 と呼ばれる集合演算に使用されます。
これらの概念については、本章の後半を参照してください。
高度な SELECT 文 3-35
SELECT 文内の副問合せ
次の SELECT 文は、items 表に関する副問合せを実行して、stock 表内の項
目のうち、まだ注文されていない項目をすべて識別します。
SELECT stock.* FROM stock
WHERE NOT EXISTS
(SELECT * FROM items
WHERE stock.stock_num = items.stock_num
AND stock.manu_code = items.manu_code)
次の行が戻されます。
stock_num manu_code description
101
102
102
105
106
107
108
109
110
110
112
113
201
202
203
205
205
301
301
301
301
302
303
305
306
308
309
310
310
311
312
312
313
313
PRC
SHM
PRC
PRC
PRC
PRC
SHM
SHM
ANZ
HRO
SHM
SHM
KAR
NKL
NKL
NKL
HRO
NKL
HRO
PRC
ANZ
HRO
KAR
HRO
PRC
PRC
SHM
SHM
ANZ
SHM
SHM
HRO
SHM
ANZ
bicycle tires
bicycle brakes
bicycle brakes
bicycle wheels
bicycle stem
bicycle saddle
crankset
pedal binding
helmet
helmet
12-spd, assmbld
18-spd, assmbld
golf shoes
metal woods
irons/wedge
3 golf balls
3 golf balls
running shoes
running shoes
running shoes
running shoes
ice pack
socks
first-aid kit
tandem adapter
twin jogger
ear drops
kick board
kick board
water gloves
racer goggles
racer goggles
swim cap
swim cap
unit_price unit unit_descr
$88.00
$220.00
$480.00
$53.00
$23.00
$70.00
$45.00
$200.00
$244.00
$260.00
$549.00
$685.90
$90.00
$174.00
$670.00
$312.00
$312.00
$97.00
$42.50
$75.00
$95.00
$4.50
$36.00
$48.00
$160.00
$280.00
$40.00
$80.00
$84.00
$48.00
$96.00
$72.00
$72.00
$60.00
box
case
case
pair
each
pair
each
case
case
case
each
each
each
case
case
case
case
each
each
each
each
each
box
case
each
each
case
case
case
box
box
box
box
box
4/box
4 sets/case
4 sets/case
pair
each
pair
each
4 pairs/case
4/case
4/case
each
each
each
2 sets/case
2 sets/case
24/case
24/case
each
each
each
each
each
24 pairs/box
4/case
each
each
20/case
10/case
12/case
4 pairs/box
12/box
12/box
12/box
12/box
SELECT 文内に指定できる副問合せの数に論理的には制限はありませんが、
文字列として考えた場合、文のサイズには物理的な制限があります。ただ
し、実際に構成する文がこの制限を超えることはほとんどありません。
3-36 高度な SELECT 文
集合演算
データベース内に情報が正しく格納されたかどうかをチェックする必要が
ある場合があります。データベース内のエラーを検出する方法の 1 つは、エ
ラーが存在するときにのみ出力を戻す問合せを記述することです。このタ
イプの副問合せは、1 種の監査問合せ として機能します。
SELECT * FROM items
WHERE total_price != quantity *
(SELECT unit_price FROM stock
WHERE stock.stock_num = items.stock_num
AND stock.manu_code = items.manu_code)
この SELECT 文は、特定の注文に関する品目合計価格が在庫単価と注文数
量の積に等しくない行のみを戻します。ディスカウントが適用されていな
い場合、これらの行はデータベースに正しく入力されていません。次に例
を示します。
item_num order_num stock_num manu_code quantity total_price
1
2
1004
1006
1 HRO
5 NRG
1
5
$960.00
$190.00
集合演算
標準の集合演算である和、積、および差 を使用すると、データベース情報
を操作することができます。上記の 3 つの関数により、SELECT 文を使用し
て更新、挿入、または削除を実行した後に、データベースの整合性を
チェックすることができます。これらは、データを履歴表に転送し、例え
ば、履歴表内に正しいデータが格納されていることを確認してから元の表
のデータを削除するときなどに便利です。
和
和を表す関数は UNION キーワードまたは演算子を使用して 2 つの問合せを
1 つの複合問合せ に結合します。2 つ以上の SELECT 文の間に UNION キー
ワードを使用すると、これらの和 をとって、元の表のいずれか、またはす
べてに格納されている行からなる一時表を作成できます ( 副問合せ内また
はビュー定義内では、UNION 演算子を使用できません )。図 3-5 に、和集
合演算を示します。
高度な SELECT 文 3-37
集合演算
SELECT DISTINCT stock_num, manu_code
FROM stock
WHERE unit_price < 25.00
quantity
UNION
SELECT stock_num, manu_code
FROM items
WHERE quantity > 3
unit_price
図 3-5
greater than
3
less than
or equal to
3
less than
25.00
qualifies
qualifies
greater than or
equal to 25.00
qualifies
unit_price < 25.00
quantity > 3
和集合演算
UNION キーワードは、2 つの問合せからすべての行を選択し、重複を削除し
て残りの行を戻します。問合せ結果は 1 つの結果に結合されるため、各問合
せの選択リストは列数が同じになります。また、各表から選択された対応
列は、データ型が同じ (CHARACTER 型の列は長さが同じ ) であり、すべて
の列で NULL を許可または不許可にする必要があります。
次に示す複合 SELECT 文は、stock および items 表内の stock_num および
manu_code 列に関して和を実行します。
SELECT DISTINCT stock_num, manu_code
FROM stock
WHERE unit_price < 25.00
UNION
SELECT stock_num, manu_code
FROM items
WHERE quantity > 3
3-38 高度な SELECT 文
集合演算
この SELECT 文は、単価が $25.00 未満の品目、または注文数量が 4 以上の
品目を選択して、これらの品目の stock_num および manu_code をリストし
ます。
stock_num manu_code
5
5
5
9
103
106
201
301
302
302
ANZ
NRG
SMT
ANZ
PRC
PRC
NKL
KAR
HRO
KAR
ORDER BY 節を指定する場合は、最後の SELECT 文の後に指定し、並べ替え
列の参照に識別子ではなく整数を使用する必要があります。並べ替えは集
合演算が完了した後に実行されます。
SELECT DISTINCT stock_num, manu_code
FROM stock
WHERE unit_price < 25.00
UNION
SELECT stock_num, manu_code
FROM items
WHERE quantity > 3
ORDER BY 2
この複合問合せは、この前の SELECT 文と同じ行を選択しますが、表示さ
れる行はメーカー・コード順に並べ替えられています。
stock_num manu_code
5
9
302
301
302
201
5
103
106
5
ANZ
ANZ
HRO
KAR
KAR
NKL
NRG
PRC
PRC
SMT
高度な SELECT 文 3-39
集合演算
デフォルトで、UNION キーワードは重複行を除外します。オプションの
キーワード ALL を追加すると、重複行が残されます。
SELECT stock_num, manu_code
FROM stock
WHERE unit_price < 25.00
UNION ALL
SELECT stock_num, manu_code
FROM items
WHERE quantity > 3
ORDER BY 2
INTO TEMP stockitem
この複合 SELECT 文は、UNION ALL キーワードを使用して 2 つの SELECT 文
の和をとり、最後の SELECT の後に INTO TEMP 節を追加して結果を一時表
に格納します。この前の例と同じ行が戻されますが、結果には重複行も含
まれます。
stock_num manu_code
9
5
9
5
9
5
5
5
302
302
301
201
5
5
103
106
5
5
3-40 高度な SELECT 文
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
ANZ
HRO
KAR
KAR
NKL
NRG
NRG
PRC
PRC
SMT
SMT
集合演算
複合問合せの選択リスト内の対応列はデータ型が同じである必要がありま
すが、これらの列に同じ識別子を使用する必要はありません。
SELECT DISTINCT state
FROM customer
WHERE customer_num BETWEEN 120 AND 125
UNION
SELECT DISTINCT code
FROM state
WHERE sname MATCHES "*a"
この SELECT 文は customer 表から state 列を選択し、state 表から対応する
code 列を選択します。カスタマー・コードが 120 ~ 125 、または sname の
末尾が A または a である都道府県の都道府県コードの省略形が戻されます。
state
AK
AL
AZ
CA
DE
FL
GA
IA
IN
LA
MA
MN
MT
NC
ND
NE
NJ
NV
OK
PA
SC
SD
VA
WV
複合問合せでは、最初の SELECT 文の列名または表示ラベルが結果内に表
示されます。したがって、次の例では、最初の SELECT 文の列名 state が使
用され、2 番目の列の名前 code は使用されません。
高度な SELECT 文 3-41
集合演算
次の SELECT 文は、3 つの表に関して和を実行します。和の最大数は、アプ
リケーションの実際の性能およびメモリー制限によって決まります。
SELECT stock_num, manu_code
FROM stock
WHERE unit_price > 600.00
UNION ALL
SELECT stock_num, manu_code
FROM catalog
WHERE catalog_num = 10025
UNION ALL
SELECT stock_num, manu_code
FROM items
WHERE quantity = 10
ORDER BY 2
この複合問合せは、stock 表内の unit_price が $600 より大きいか、catalog
表内の catalog_num が 10025 であるか、または items 表内の quantity が 10
である品目を選択して、manu_code 順に並べ替えます。
stock_num manu_code
5
9
8
4
1
203
5
106
113
ANZ
ANZ
ANZ
HSK
HSK
NKL
NRG
PRC
SHM
SELECT 文および UNION 演算子の構文の詳細は、
「IBM Informix SQL リファレ
ンス・ガイド」の第 7 章を参照してください。IBM Informix 4GL および
IBM Informix ESQL/C 製品、および INTO 節と複合問合せに関する制限事項に
ついては、本書の第 6 章、第 7 章、および製品のマニュアルを参照してく
ださい。
3-42 高度な SELECT 文
集合演算
次の例では、複合問合せを使用して、選択したデータを一時表に格納し、
さらに問合せを 1 つ追加してデータを並び替えて表示します。複合問合せ
と単純な問合せはセミコロンで分離する必要があります。
複合問合せでは、選択リストにリテラルを使用して和の部分の出力にタグ
を付けて、その後の部分と区別しています。タグにはラベル sortkey が設定
されます。単純な問合せでは、このタグをソート・キーとして使用し、抽
出した行を並べ替えます。
SELECT "1" sortkey, lname, fname, company,
city, state, phone
FROM customer x
WHERE state = "CA"
UNION
SELECT "2" sortkey, lname, fname, company,
city, state, phone
FROM customer y
WHERE state <> "CA"
INTO TEMP calcust;
SELECT * FROM calcust
ORDER BY 1
この問合せのペアは、カリフォルニア州のカスタマーのうち、電話による
問合せ件数が最も多い顧客から順に表示されるリストを作成します。
高度な SELECT 文 3-43
集合演算
3-44 高度な SELECT 文
sortkey
lname
fname
company
city
state
phone
1
Albertson
Frank
Sporting Place
Redwood City
CA
415-886-6677
sortkey
lname
fname
company
city
state
phone
1
Baxter
Dick
Blue Ribbon Sports
Oakland
CA
415-655-0011
sortkey
lname
fname
company
city
state
phone
1
Beatty
Lana
Sportstown
Menlo Park
CA
415-356-9982
sortkey
lname
fname
company
city
state
phone
1
Currie
Philip
Phil’s Sports
Palo Alto
CA
415-328-4543
sortkey
lname
fname
company
city
state
phone
.
.
.
sortkey
lname
fname
company
city
state
phone
1
Grant
Alfred
Gold Medal Sports
Menlo Park
CA
415-356-1123
2
Satifer
Kim
Big Blue Bike Shop
Blue Island
NY
312-944-5691
sortkey
lname
fname
company
city
state
phone
2
Shorter
Bob
The Triathletes Club
Cherry Hill
NJ
609-663-6079
sortkey
lname
fname
company
city
state
phone
2
Wallack
Jason
City Sports
Wilmington
DE
302-366-7511
集合演算
積
2 つの行の集合の積をとると、元の両方の表に存在する行を含む表が作成
されます。2 つの集合の積を示す副問合せを導入するには、キーワード
EXISTS または IN を使用します。図 3-6 に、積集合演算子を示します。
SELECT stock_num, manu_code, unit_price
FROM stock
WHERE stock_num IN
(SELECT stock_num FROM items)
ORDER BY stock_num
stock_num
stock_num
exists in
items table
exists in
stock table
not in items
table
stock table
qualifies
items table
not in stock
table
図 3-6
積集合演算子
次に示す入れ子状態の SELECT 文の例は、stock および items 表の積を示し
ます。
SELECT stock_num, manu_code, unit_price
FROM stock
WHERE stock_num IN
(SELECT stock_num FROM items)
ORDER BY stock_num
高度な SELECT 文 3-45
集合演算
この結果には、両方の集合に属するすべての要素が含まれ、次に示す 57 の
行が戻されます。
stock_num manu_code unit_price
1
1
1
2
3
3
4
4
5
5
5
6
6
7
8
9
101
101
103
104
105
105
109
109
110
110
110
110
110
111
114
201
201
201
202
202
204
205
205
205
301
301
301
301
301
301
302
302
303
303
304
304
306
306
307
309
309
3-46 高度な SELECT 文
HRO
HSK
SMT
HRO
HSK
SHM
HRO
HSK
ANZ
NRG
SMT
ANZ
SMT
HRO
ANZ
ANZ
PRC
SHM
PRC
PRC
PRC
SHM
PRC
SHM
ANZ
HRO
HSK
PRC
SHM
SHM
PRC
ANZ
KAR
NKL
KAR
NKL
KAR
ANZ
HRO
NKL
ANZ
HRO
KAR
NKL
PRC
SHM
HRO
KAR
KAR
PRC
ANZ
HRO
PRC
SHM
PRC
HRO
SHM
$250.00
$800.00
$450.00
$126.00
$240.00
$280.00
$480.00
$960.00
$19.80
$28.00
$25.00
$48.00
$36.00
$600.00
$840.00
$20.00
$88.00
$68.00
$20.00
$58.00
$53.00
$80.00
$30.00
$200.00
$244.00
$260.00
$308.00
$236.00
$228.00
$499.99
$120.00
$75.00
$90.00
$37.50
$230.00
$174.00
$45.00
$312.00
$312.00
$312.00
$95.00
$42.50
$87.00
$97.00
$75.00
$102.00
$4.50
$5.00
$36.00
$48.00
$170.00
$280.00
$160.00
$190.00
$250.00
$40.00
$40.00
集合演算
差
2 つの行の集合の差をとると、最初のセットのうち、2 番目のセットに含ま
れていない行を含む表が生成されます。2 つの集合間の差を示す副問合せ
を導入するには、キーワード NOT EXISTS または NOT IN を使用します。
図 3-7 に、差集合演算子を示します。
SELECT stock_num, manu_code, unit_price
FROM stock
WHERE stock_num NOT IN
(SELECT stock_num FROM items)
ORDER BY stock_num
stock_num
stock_num
exists in
items table
not in items
table
exists in
stock table
stock table
qualifies
items table
not in stock
table
図 3-7
差集合演算子
次に示す入れ子状態の SELECT 文は、stock 表と items 表の差を示します。
SELECT stock_num, manu_code, unit_price
FROM stock
WHERE stock_num NOT IN
(SELECT stock_num FROM items)
ORDER BY stock_num
高度な SELECT 文 3-47
サマリー
この結果には、最初のセットにのみ含まれているすべての要素が含まれ、
次に示す 17 の行が戻されます。
stock_num manu_code unit_price
102
102
106
107
108
112
113
203
305
308
310
310
311
312
312
313
313
PRC
SHM
PRC
PRC
SHM
SHM
SHM
NKL
HRO
PRC
ANZ
SHM
SHM
HRO
SHM
ANZ
SHM
$480.00
$220.00
$23.00
$70.00
$45.00
$549.00
$685.90
$670.00
$48.00
$280.00
$84.00
$80.00
$48.00
$72.00
$96.00
$60.00
$72.00
サマリー
本章では、第 2 章で導入した概念に基づいて説明しました。リレーショナ
ル・データベースで問合せを実行する場合に使用する SELECT 文の高度な
使用例を示す簡単な構文、およびその結果を示しました。本章の内容は、
次のとおりです。
• 集合とともに使用して行のグループを戻したり、これらのグループに条
件を適用できる GROUP BY 節および HAVING 節についての説明
• 行 ID を使用して表およびシステム・カタログ表から内部行 ID 番号を抽
出する方法、およびシリアル内部表識別子 ( 表識別子 ) についての説明
• 自己結合を使用して表をそれ自身に結合して、列内の値を同じ列内の他
の値と比較したり、重複を識別する方法についての説明
• キーワード OUTER を導入して、外部結合が複数の表を非対称に処理す
る方法、および 4 種類の外部結合の例についての説明
•
3-48 高度な SELECT 文
SELECT 文を別の SELECT 文内の WHERE 節の入れ子にして、相関および
無相関の副問合せを作成する方法、および副問合せ内での集合関数の使
用方法についての説明
サマリー
• 副問合せを作成する場合のキーワード ALL、ANY、EXISTS、IN、および
SOME の使用方法、およびキーワード NOT または関係演算子を追加した
場合の効果についての説明
• 和、積、差の集合演算についての説明
• UNION および UNION ALL のキーワードを使用して、複数の SELECT 文か
ら構成される複合問合せを作成する方法についての説明
高度な SELECT 文 3-49
問合せの最適化
概要 3
最適化手法 4
問題の検査 5
トータル・システムの考慮 5
アプリケーションについて 5
アプリケーションの測定 6
手動タイミング 6
オペレーティング・システム・コマンドからの
時間 6
プログラム言語からの時間 7
ギルティー関数の検索 7
広範囲な検査 7
問合せオプティマイザー 8
表の順序の重要性 8
フィルターを使用しない結合 8
列フィルターを使用した結合 10
インデックスの使用 12
ソート・マージ結合手法 13
オプティマイザーの機能 14
最適化レベルの選択 14
入力の提供 14
フィルターへのアクセス 15
表アクセス・パスの選択 17
問合せ予定の選択 18
予定の読取り 19
問合せの時間コスト 21
メモリー内の動作 21
ディスク・アクセス管理 21
ディスク・ページ 23
ページ・バッファー 23
第
4
章
行の読取りのコスト 24
順次アクセスのコスト 25
非順次アクセスのコスト 26
行 ID アクセスのコスト 26
インデックス・アクセスのコスト 26
小さな表のコスト 27
ネットワーク・アクセスのコスト 28
問合せの高速化 30
テスト環境の準備 31
データ・モデルの理解 32
問合せ予定の理解 32
問合せの再考 33
ビューを使用した結合の再書込み 33
ソートの回避と単純化 33
大きな表への順次アクセスの除去 34
順次アクセスを回避するための UNION の使用 35
自動作成されたインデックスへのインデックスの置換 36
複合インデックスの使用 36
疑わしいインデックスでの tbcheck の使用 36
更新後のインデックスの削除と再構築 36
相関副問合せの回避 37
困難な正規表現の回避 37
非初期サブ文字列の回避 38
問合せの速度を上げるための一時表の使用 39
複数ソートを回避するための一時表の使用 39
非順次アクセスの代替用ソートの使用 40
サマリー 45
4-2 問合せの最適化
概要
問合せにかかる時間はどのくらいでしょうか。コンピューターは、問合せ
の実行中にいくつのディスク操作を実行するのでしょうか。多くの問合せ
の場合、人間よりも早くコンピューターが情報を見つけることができれば
問題はありません。しかし、問合せによっては、限られた時間内で実行し、
限られた量のマシン能力だけを使用しなければならないものもあります。
この章では、問合せをより効率的にする技法について検討します。既存の
データベースを扱い、表の配置を変更できないことが想定されています。
( 信頼性とパフォーマンスのための新規データベースの設計技法は、本書の
第 8 章から第 11 章で説明します。)
この章では、以下のトピックについて説明します。
• ソフトウェアを最適化する技法の一般的な説明。任意の SQL 文を変更
する前に参照するものすべてに重点を置きます。
• 問合せの実行方法を決定するデータベース・サーバーの一部であるオプ
ティマイザー の説明。オプティマイザーによる問合せ予定の作成方法
が分かっている場合は、より効率的なものを作成できます。
• 問合せ中に時間がかかる操作の説明。これにより、高速操作か低速操作
かを選択できます。
• オプティマイザーが一番早い問合せの実行方法を選択するのに役立つ技
法の分類。
この章では、SQL パフォーマンスに焦点を置いて説明していますが、パ
フォーマンス上の問題は SQL 文が埋め込まれている問題の他の部分から生
じる可能性があります。パフォーマンスに関する一般的な問題について書
かれた 2 冊の書籍として、Kernighan と Ritchie (McGraw-Hill 1978) 共著の
「The Elements of Programming Style」と Jon Louis Bentley (Prentice-Hall1982) 著
の「WritingEfficient Programs」があります。Bentley のアドバイスのほとん
どは、SQL 文とデータベース設計に適用できます。
問合せの最適化 4-3
最適化手法
最適化手法
SQL 文の最適化を開始する前に、それらの文を、以下のコンポーネントを
含む、より大きなシステムの一部として考慮するようにしてください。
• 1 つまたは複数のプログラム
SQL 文が埋め込まれている 1 つまたは複数の言語で書かれた、保存済み
問合せ、コンパイル済みスクリーン・フォームとレポート、およびプロ
グラム。
• 1 つまたは複数のストアード・プロシージャー
データベース内の実行可能ファイルに格納される SQL および SPL ( 構造
化プロシージャー言語 ) の文で作成されたコンパイル済みのプロシー
ジャー。
• 1 つまたは複数のコンピューター
プログラムとデータベースを格納するマシン。
• 1 人または複数の保守管理者
プログラムのメンテナンスの責任者。
• 1 人または複数のユーザー
システムが拡大または単純化すると思われる作業を担当するユーザー。
• 1 つまたは複数の構成
コンピューターを所有して、実行する作業を選択するグループ。
これらの各コンポーネントが別々の組織であるような大きな企業で作業す
る場合があるかもしれません。または、デスクトップ・ワークステーション
の所有者、保守管理者、および唯一のユーザーである場合もあるかもしれ
ません。どのような場合でも、全体として、システムについての次の 2 つ
のポイントを認識しておくことが重要です。まず、このシステムの目的は、
そのユーザー の要求を満たすことです。プログラムを最適化するための努
力は、その結果がいくつかの点でユーザーにとって役立たなければ無駄に
なります。次に、SQL 文はシステムのごく一部でしかないということです。
しばしば、システムの他の部分に最も有効な改善点が見つかる場合があり
ます。
次の項では、コンピューターのパフォーマンス上の問題を分析する一般的
なプロシージャーの概要について説明します。解決策を見落とさないよう
にするには、このプロシージャーに従ってください。解決策には、パ
フォーマンス上の問題に最善の回答を提供する技術的とはいえないものも
含まれます。
4-4 問合せの最適化
最適化手法
問題の検査
SQL 文の最適化を開始する前に、そのプログラムに問題があることを確認
してください。プログラムを高速にすると、ユーザーにとってどのくらい
有効性が高まるのでしょうか。その答えが “ それほどでもない ” 場合は、他
の解決策を探してください。
トータル・システムの考慮
企業内のプログラム、コンピューター、およびユーザーのシステム全体を
考慮してください。スケジュールを変更したり、リソースを異なる方法で
管理することによって、より良い解決策を見つけることができます。おそ
らく、問題の操作は、異なる時間に、または異なるマシン上で、または同
時に実行される異なるジョブと共に実行されると高速になる場合がありま
す。または、その逆に高速にならないこともあります。最善のアクションを
判別する前に、これらの実現性を考慮する必要があります。
アプリケーションについて
アプリケーションのすべてを総括して学習します。データベース・アプリ
ケーションには、通常、保管済み問合せ、スクリーン・フォーム、レポー
ト仕様、およびプログラムなどの多くの部分があります。これらをユー
ザーのプロシージャーとともに考慮し、次の質問に答えてください。
• 何 が実行されているか ?
除去できる余分なステップや重複したステップを識別します。すべての
ステップまたはアクションが重要な場合でも、それらすべてとそれらの
使用順序を知っておくと役立ちます。
• なぜ 実行されているか ?
特に古いアプリケーションでは、何の目的も果たさないステップがある
場合があります。例えば、操作がデバッグのためにかなり前に入れら
れ、除去されていない場合です。
• 誰に対して 実行されているか ?
アプリケーションからのすべての出力が要求されており、それらがユー
ザーによって使用されていることを確認してください。誰も要求しなく
なった出力を見つけることがあります。または、その出力が、まれに必
要とされたり、より簡単なフォーマットで必要とされる場合もあります。
• どこが 遅い部分か ?
遅すぎるステップをできる限り分離します。時間も限られていますの
で、最善の結果を出せる部分に時間を使ってください。
問合せの最適化 4-5
最適化手法
アプリケーションを理解する時間を取ることによって、アプリケーション
のパーツのすべて、それらのパーツの使用方法、パーツのすべてが不可欠
かどうか、およびどのパーツが遅すぎるのかを知ることができます。
アプリケーションの測定
パフォーマンス上の問題を測定するまでは、パフォーマンス上の問題で有
意義な進展を期待することはできません。アプリケーションの遅い部分を
反復して量的に測定する方法を見つける必要があります。これは、次のよう
な理由で非常に重要です。
• 数字がなければ、ユーザーまたは企業に対して、問題を正確かつ詳細に
説明することができません。
問題を適切に伝えるには、
「レポートは 2 時間 38 分実行されます。」ま
たは「更新は平均して 13 秒かかりますが、ピーク時間には 49 秒かかり
ます。」などの測定値を判別する必要があります。
• 数字がなければ、意味のあるゴールを設定できません。
特定の測定値がある場合は、パフォーマンスに対する数値的目標の合意
が得られます。
• 数値がなければ、進行状況を測定して証明できません。
小さな改善点を検出して証明したり、代替策の中から選択するには、測
定が必要です。
手動タイミング
手動操作のストップウォッチを使用して、反復可能な測定が可能です。練
習すれば、ほとんどのユーザーは 1 秒の 10 分の 2 のタイミングで繰返し測
定できるようになります。手動タイミングは、少なくとも数秒しかかから
ない少数のイベントを測定する場合に効果的です。
オペレーティング・システム・コマンドからの時間
オペレーティング・システムには、通常、時間を表示するコマンドがあり
ます。コマンド・スクリプト内の 2 つの時間コマンドの間に時間を計る操
作を組み込めます。
4-6 問合せの最適化
最適化手法
プログラム言語からの時間
ほとんどのプログラム言語には、時間を表示するライブラリー関数があり
ます。ソース・コードへのアクセス権がある場合は、特定のアクションの
時間を測定する文を挿入できます。例えば、アプリケーションが 4GL で書
かれている場合は、CURRENT 関数を使用して、現行時間を DATETIME 値と
して取得することができます。4GL プログラムは、次のフラグメントに類
似したコードを使用して自動タイミングを実行できます。
DEFINE start_time DATETIME HOUR TO FRACTION(2),
elapsed INTERVAL MINUTE(4) TO FRACTION(2)
LET start_time = EXTEND(CURRENT,HOUR TO FRACTION(2))
{ -- here perform the operation to be timed -- }
LET elapsed = EXTEND(CURRENT,HOUR TO FRACTION(2))-start_time
DISPLAY "Elapsed time was ",elapsed
マルチプログラミング・システムまたはネットワーク環境において、経過
時間は実行時間と常に対応しているわけではありません。ほとんどの C ラ
イブラリーには、プログラムの CPU 時間を戻す関数が含まれ、C 関数は
4GL プログラムおよび ACE レポートから呼び出すことができます。
ギルティー関数の検索
ほとんどのプログラムでは、コードの非常に小さな断片 ( 通常 20% 以下 )
が、プログラム実行時間の大部分 ( 通常 80% 以上 ) を占めます。80-20 の法
則 は、その名のとおり、ほとんどの場合に当てはまります。この比率が大
きくなることもよくあります。タイミングのメカニズムを確立したら、そ
れを使用してアプリケーション内のホット・スポット、つまりほとんどの
時間を浪費する文を定義してください。
広範囲な検査
1 つの文が何千ものディスク・アクセスをトリガーできる埋込み SQL を使
用すると、ギルティー 20% にはいくつかの SQL が含まれる可能性がありま
す。ただし、これは決して確実なわけではありません。偏見のない広範囲
な検査を開始しなければ、相当な時間を浪費しているプログラムの部分を
簡単に見落としてしまいます。
操作が遅い理由が SQL によるものではない場合は、4-3 ページに引用された
ブックを参照してください。SQL 文がアテンションを必要とする場合、ユー
ザーは問合せオプティマイザーのアクションを理解する必要があります。
問合せの最適化 4-7
問合せオプティマイザー
問合せオプティマイザー
データベース・サーバーのオプティマイザー・コンポーネントは、問合せ
の実行方法を決定します。その最も重要なジョブは、それぞれの表の行を
検証する順序を決定することです。その決定を行うために、オプティマイ
ザー・コンポーネントは、行の順次走査、既存のインデックス、また一時
インデックスによって、それぞれの表にアクセスするために最も効率的な
方法を決定し、それぞれの表が最終結果に提供する行数を見積もらなけれ
ばなりません。
オプティマイザー設計は科学ではなく、オプティマイザーは、継続した開
発と改善が行われているデータベース・サーバーのパーツです。ここでは、
IBM Informix データベース・サーバーのバージョン 5.0 で使用されるオプ
ティマイザーを説明します。旧バージョンの IBM Informix データベース・
サーバーには、古くて簡単なオプティマイザーがあります。
表の順序の重要性
表が検証される順序は、結合操作の速度に多大な影響を与えます。このこ
とは、データベース・サーバーの作業方法を示すいくつかの例を使用して
明確にすることができます。
フィルターを使用しない結合
以下は、3 ウェイ結合を呼び出す SELECT 文です。
SELECT C.customer_num, O.order_num, SUM (items.total_price)
FROM customer C, orders O, items I
WHERE C.customer_num = O.customer_num
AND O.order_num = I.order_num
GROUP BY C.customer_num, O.order_num
ここで、インデックスが考案されなかった場合を考えてみましょう。イン
デックスがなければ、データベース・サーバーは、この操作を簡単な入れ
子ループを使用して実行する以外に方法はありません。2 つの実践的な問
合せ予定 のうちの 1 つは、図 4-1 のように、プログラミング疑似コードで
表されます。問合せ予定には、データベース・サーバーが表を検証する順
序と表にアクセスするメソッドが示されます。
4-8 問合せの最適化
問合せオプティマイザー
for each row in the customer table do:
read the row into C
for each row in the orders table do:
read the row into O
if O.customer_num = C.customer_num then
let Sum = 0
for each row in the items table do:
read the row into I
if I.order_num = O.order_num then
let Sum = Sum + I.total_price
end if
end for
prepare an output row from C,I,and Sum
end if
end for
end for
図 4-1
疑似コードでの問合せ予定
このプロシージャーでは、次の行を読み取ります。
• customer 表のすべての行を 1 回
• customer 表の行ごとに、orders 表のすべての行を 1 回
• 出力に表示される orders の行ごとに items 表のすべての行を 1 回 (orders
のすべての行は 1 回表示されなければなりません。
これは、唯一可能な問合せ予定ではありません。他の問合せ予定は、customer と orders の役割を orders の行ごとに反転させるだけで、customer の
すべての行を読み取り、一致する customer_num を探します。異なるシー
ケンスにある場合でも、同じ行数を読み取ります。
それぞれの表内の行数は、systables という名前のシステム・カタログ表に
保管されます。次の問合せを書き込み、図 4-1 の問合せ予定によって読み
取られる行の合計数を計算します。
SELECT C.nrows + C.nrows*O.nrows + O.nrows*I.nrows
FROM systables C, systables O, systables I
WHERE C.tabname = "customer"
AND O.tabname = "orders"
AND I.tabname = "items"
これは、特に、この問合せ予定によって必要とされる作業の量をオプティ
マイザーが予測する方法です。(systables の行カウントは、UPDATE STATISTICS コマンドが実行されるときにのみ更新されます。したがって、オプ
ティマイザーは、ときどき古い情報から作業します。)
問合せの最適化 4-9
問合せオプティマイザー
列フィルターを使用した結合
前述の例において、2 つの可能な問合せ予定によって実行される作業の量
に違いはありませんでした。ただし、列フィルターを使用することによっ
て、状況は変わります。列フィルターとは、表が結合操作に提供する行数
を削減する WHERE 式です。次には、フィルターが追加された前述の問合せ
を示します。
SELECT C.customer_num, O.order_num, SUM (items.total_price)
FROM customer C, orders O, items I
WHERE C.customer_num = O.customer_num
AND O.order_num = I.order_num
AND O.paid_date IS NULL
GROUP BY C.customer_num, O.order_num
O.paid_date IS NULL 式は、いくつかの行をフィルター・アウト して、使
用される行数を orders 表から削減します。以前のように、2 つの問合せ予
定が可能です。orders からの読取りによって起動する予定は、図 4-2 のよ
うに疑似コードで表示されます。
for each row in the orders table do:
read the row into O
if O.paid_date is null then
for each row in the customer table do:
read the row into C
if O.customer_num = C.customer_num then
let Sum = 0
for each row in the items table do:
read the row into I
if I.order_num = O.order_num then
let Sum = Sum + I.total_price
end if
end for
prepare an output row from C,I,and Sum
end if
end for
end if
end for
図 4-2
疑似コードの 2 つの問合せ予定のうちの 1 つ
pdnull が、フィルターを渡す orders 内の行数を表すとします。これは、次
の問合せが戻る数です。
SELECT COUNT(*) FROM orders WHERE paid_date IS NULL
4-10 問合せの最適化
問合せオプティマイザー
すべての発注につき 1 つの顧客しかいないと仮定します ( これは規定です )。
すなわち、図 4-2 の予定は以下の行を読み取ります。
• orders 表のすべての行を 1 回
• customer 表のすべての行を pdnull 回
• items 表のすべての行を pdnull 回
for each row in the customer table do:
read the row into C
for each row in the orders table do:
read the row into O
if O.paid_date is null and
O.customer_num = C.customer_num then
let Sum = 0
for each row in the items table do:
read the row into I
if I.order_num = O.order_num then
let Sum = Sum + I.total_price
end if
end for
prepare an output row from C,I,and Sum
end if
end for
図 4-3
疑似コードの代替問合せ予定
代替予定が、図 4-3 に示されています。この場合、customer から最初に読
み取ります。フィルターは最初のステップでは適用されないため、この予
定は以下の行を読み取ります。
• customer 表のすべての行を 1 回
• customer のすべての行ごとに、orders 表のすべての行を 1 回
• items 表のすべての行を pdnull 回
図 4-2 と図 4-3 の問合せ予定は、異なるシーケンスにあっても同じ出力を
出します。これらは、一方が表を pdnull 回読み取り、他方が表を
SELECT COUNT(*) FROM customer 回読み取る点で異なります。オプティ
マイザーがそのどちらを選択するかによって、実際のアプリケーション内
の何千ものディスク・アクセスに違いが生じます。
問合せの最適化 4-11
問合せオプティマイザー
インデックスの使用
前述の例では、インデックスまたは制約を使用しません。これは、現実的
ではありません。ほとんどすべての表に、1 つまたは複数のインデックスま
たは制約があり、これらによって問合せ予定で違いが生じます。図 4-4 に
は、前述の問合せをインデックスを使用して構成したときの問合せ予定の
概略が示されています。(4-29 ページの 『インデックスの構造』も参照して
ください。)
for each row in the customer table do:
read the row into C
look up C.customer_num in index on orders.customer_num
for each matching row in the orders table do:
read the row into O
if O.paid_date is null then
let Sum = 0
look up O.order_num in index on items.order_num
for each matching row in the items table do:
read the row into I
let Sum = Sum + I.total_price
end for
prepare an output row from C,I,and Sum
end if
end for
end for
図 4-4
疑似コードでインデックスを使用する問合せ予定
インデックス内のキーは、最初のマッチング・キーが見つかったときに、
それ以上検索しなくても同一キーを持つ他のすべての行を読み取るように
ソートされます。この問合せ予定は、次の行だけを読み取ります。
• customer 表のすべての行を 1 回
• orders 表のすべての行を 1 回
• orders からの pdnull 行に一致する items 表の行
この方法は、インデックスを使用しない予定と比較すると、労力が大きく
減少します。( 逆の予定、つまり orders を最初に読み取り、そのインデック
スによって customer 内の行をルックアップするのも同様に効果的です。)
ただし、インデックスを使用する予定は、行データを読み取るだけでなく、
ディスクからインデックス・データを読み取る必要があります。最近使用
されたインデックス・ページのいくつかがメモリーに保存されており、そ
れらが必要とされるときにそこで検出されるため、読み取られるインデッ
クス・ページ数を予測するのは困難です。(4-21 ページの 『ディスク・アク
セス管理』を参照してください。)
4-12 問合せの最適化
問合せオプティマイザー
表の物理的順序も、インデックス使用のコストに影響を与える可能性があ
ります。図 4-4 の問合せ予定は、物理的な順序で customer 表の行を読み取
ります。それが顧客番号順でもある場合は、顧客番号は
orders.customer_num 上に、インデックスの順序どおり表示されます。イン
デックスがソートされる結果として、インデックス・ページが続いて読み
取られます。まず間違いなく、それらは 1 回だけ読み取られます。
customer 表の物理的な順序は、クラスター・インデックスがその列にあれ
ば顧客番号順です。顧客番号がデータベース・サーバーによって生成され
た SERIAL 値である場合は、ほぼその順序です。
ただし、物理的な順序が顧客番号に関してランダムである場合、orders 上
のインデックスの検索を実行するごとに、インデックス・キーの異なる
ページに移動することがあります。これにより、インデックス・ページは
ほとんどすべての行に対して読み取られます。
ソート・マージ結合手法
バージョン 5.0 で実装されたソート・マージ表結合には、入れ子ループ表
結合の代替が用意されています。これにより、オプティマイザーは、でき
るかぎり最高速の結合を生み出すための実行の最適なパスを選択できます。
これは、ループ結合、ソート・マージ結合、またはその 2 つの組み合わせ
である場合があります。
ソート・マージ機能は、ソート・マージが使用されていないパフォーマン
スを低下させずに、特定の問合せの実行を最適化します。ソート・マージ
結合は、少なくとも 1 つの結合のフィルターが等演算子である場合に自動
的に生じます。
ソート・マージ結合によって、オプティマイザーの基本的なストラテジー
が変わることはありません。むしろ、一時的なインデックスを使用して入
れ子ループ結合のより良い代替セットが提供され、ORDER BY パスと
GROUP BY パスの解析方法が変更されます。オプティマイザーによって選
択されたパスは、SET EXPLAIN ON 文が実行されるときに出力に表示されま
す。このことは、
「IBM Informix SQL リファレンス・ガイド」および 4-19 ページ
の 『予定の読取り』で説明されています。
問合せの最適化 4-13
問合せオプティマイザー
オプティマイザーの機能
バージョン 4.0 以降の IBM Informix データベース・サーバーのオプティマイ
ザーは、可能なすべての問合せ予定を定式化します。予定ごとに、検証す
る表の行数、読み取るディスク・ページ、および (IBM Informix STAR 機能
がインストールされている場合 ) 予定が必要とするネットワーク・アクセ
スを見積もります。次に、最少の見積りを持つ予定を選択します。
最適化レベルの選択
バージョン 5.0 では、SET OPTIMIZATION 文を使用して、データベース・
サーバーの最適化レベルを高位か低位かに指定できます。この文は、
「IBM Informix SQL リファレンス・ガイド」に詳しく説明されています。
デフォルト ( 高位 ) の最適化レベルは、すべての妥当な選択肢を検証して総
合的に最適な代替を選択する、洗練されたコスト・ベースのストラテジー
です。ただし、大きな結合の場合、このレベルは必要以上に大きなオー
バーヘッドが発生する場合があります。極端な例では、性能低下が激しく
なります。最適化レベルを低くすると、見込みのない結合ストラテジーを
早い段階で除去し、最適化中に使われる時間とリソースの量を減らします。
このレベルのリスクとしては、最適なストラテジーが早い段階の考慮事項
から除去されたために、その最適なストラテジーが選択されないというこ
とを挙げることができます。通常、デフォルトの最適化レベルを使用して、
最適な総合的パフォーマンスが得られます。アプリケーションを試して、
最適化レベルを低くするのが最善であることが分かった場合は、最適化レ
ベルを低く設定してください。
入力の提供
オプティマイザーは、見積りが正確である場合にのみ正常終了できます。
( 絶対項で正確である必要はありませんが、悪い予定よりも良い予定の方が
見積りを少なく出すように比較的正確である必要があります。) ただし、オ
プティマイザーは限定された情報しか保持しません。オプティマイザーは、
その独自の作業を実行時間のうちの少しの部分だけに抑えておくために、
システム・カタログ表内の情報およびその他の要約情報で間に合わせなけ
ればなりません。例えば、オプティマイザーが SELECT COUNT(*) 操作を実
行して表内に行の正確なカウント数を得る時間はありません。
4-14 問合せの最適化
問合せオプティマイザー
オプティマイザーで利用できる情報は、システム・カタログ表から入手す
ることができます。( システム・カタログ表の詳細については、
「IBM Informix SQL リファレンス・ガイド」を参照してください。) すべての
IBM Informix データベース・サーバーにおいて、この情報には次の項目が
含まれています。
• 表内の行数 ( 最新の UPDATE STATISTICS コマンドの時点 )
• 列が一意なものと制約されているかどうか
• 表に存在するインデックス。これには、含む列、昇順か降順か、および
クラスター化済みかどうかが含まれる。
IBM Informix OnLine によって管理されるシステム・カタログ表は、次の追
加の入力を提供します。
• 行データが占めるディスク・ページ数
• インデックス B + ツリー構造体の深さ ( インデックス・ルックアップの
実行に必要な作業量の測定 )
• インデックス項目が占めるディスク・ページ数
• インデックス内の一意な入力の数 ( 行数で除算。これによって指定の
キーに合う行数を提案します。)
• インデックス付き列内で 2 番目に大きなキー値と 2 番目に小さなキー値
最高値が特殊な範囲外シグナルである可能性があるために、2 番目に大き
なキー値と 2 番目に小さなキー値だけが注目されます。データベース・
サーバーでは、キー値が 2 番目に大きな値と 2 番目に小さな値との間でス
ムーズに分散されることが想定されています。これらのキーの最初の 4 バ
イトのみが格納されます。
フィルターへのアクセス
オプティマイザーは、まず、フィルターを探すことによって WHERE 節内の
表現式を検証します。オプティマイザーは、検出したフィルターごとの選
択の水準を見積もります。その選択の水準は、0 から 1 までの数値で、オプ
ティマイザーがフィルターが渡すと判断する行の小数部を示します。非常
に少ない行を渡す大変選択的なフィルターには 0 に近い選択の水準が割り
当てられ、ほとんどの行を渡すフィルターには 1 に近い選択の水準が割り
当てられます。このプロセスの詳細については、4-17 ページの 『フィル
ター選択の水準の割り当て』を参照してください。
オプティマイザーは、問合せについてのその他の情報にも注目します。例
えば、インデックスが十分であるかどうかなどです。インデックス付き列
が選択されている場合は、インデックス・ページを読み込み、行はまった
く読み取らない方が速くなります。( これは、しばしば、副問合せの場合に
当てはまります。)
問合せの最適化 4-15
問合せオプティマイザー
また、オプティマイザーは、インデックスをフィルターの評価に使用でき
るかどうかに注目します。この目的の場合、インデックス付き列とは、イ
ンデックスを持つ列、または複合インデックス内で最初に名前付けされる
列です。次のように、考慮すべきケースがいくつかあります。
• インデックス付き列が、リテラル、ホスト変数、または非相関副問合せ
と比較されるとき、データベース・サーバーは、行を読み取る代わりに
インデックス内の一致する値をルックアップできます。
• インデックス付き列が別の表内の列と比較されるときに ( 結合式 )、問合
せ予定が別の表から先に行を読み取るよう要求すると、データベース・
サーバーは、そのインデックスを使用して一致する値を検出できま
す。次に、その結合式の例を示します。
WHERE customer.customer_num = orders.customer_num
customer の行が最初に読み取られると、customer_num の値を
orders.customer_num 上のインデックスでルックアップできます。
• インデックスを ORDER BY 節の処理に使用できるかどうか。節にあるす
べての列が同じシーケンス内の 1 つのインデックス内に表示される場
合、データベース・サーバーは、そのインデックスを使用して順序付け
されたシーケンス内の行を読み取ります。この場合、ソートは回避され
ます。
• インデックスを GROUPBY 節の処理に使用できるかどうか。節にあるす
べての列が同じシーケンス内の 1 つのインデックス内に表示される場
合、データベース・サーバーはソートを必要とせずに、インデックスか
ら同等キーを持つグループを読み込むことができます。
4-16 問合せの最適化
問合せオプティマイザー
フィルター選択の水準の割り当て
次の表に、オプティマイザーが異なるタイプのフィルターに割り当てるいくつかの選択の
水準をリストします。これは完全なリストではなく、今後他の式のフォームが追加される
可能性があります。
表現式
indexed-col = literal-value
indexed-col = host-variable
indexed-col IS NULL
tab1.indexed-col = tab2.indexed-col
indexed-col > literal-value
indexed-col < literal-value
any-col IS NULL
any-col = any-expression
any-col > any-expression
any-col < any-expression
any-col MATCHES any-expression
any-col LIKE any-expression
選択の水準 (F)
F = 1/( インデックス内の独立キー数 )
F = 1/( 大きなインデックス内の独立キー数 )
F = (2nd-max - literal-value)/(2nd-max - 2nd-min)
F = (literal-value - 2nd-min)/(2nd-max - 2nd-min)
F = 1/10
F = 1/3
F = 1/5
EXISTS subquery
subquery が >0 行を戻すことを見積もった場合は F = 1、そうでない
場合は 0
NOT expression
expr1 AND expr2
expr1 OR expr2
F = 1 - F(expression)
F = F(expr1) ¥ F(expr2)
F = F(expr1) + F(expr2) - F(expr1) ¥ F(expr2)
any-col IN list
any-col relop ANY subquery
anycol = item1 OR…OR anycol =itemn として扱う
副問合せ n の見積もりサイズの場合は、any-col relop value1 OR…OR
anycol relop valuen として扱う
キー :
indexed-col: インデックス内の最初または唯一の列 (IBM Informix OnLine のみ )
2nd-max、2nd-min: インデックス付き列内で 2 番目に大きなキー値と 2 番目に小さなキー値
(IBM Informix OnLine のみ )
any-col: 前述の式でカバーされなかった任意の列
表アクセス・パスの選択
オプティマイザーは、次に、問合せで名前付けされたそれぞれの表にアク
セスする方法で最も効率的であると見積もったものを選択します。この場
合、次の 4 つの選択肢があります。
• 表の行を連続して読み取る
• 表のインデックスの 1 つを読み取り、そのインデックスが指す行を読み
取る
• 一時的なインデックスを作成して使用する
問合せの最適化 4-17
問合せオプティマイザー
• ソート・マージを実行する
最初の 2 つのオプション間の選択は、フィルター式の存在に大部分依存し
ます。インデックス付き列にフィルターがある場合は、データベース・サー
バーはそのインデックスを使用して選択済み行を選択し、それらの行だけ
を処理します。
フィルターがない場合でも、データベース・サーバーはすべての行を読み
取る必要があります。普通、インデックスのページを読み取ってから行を
読み取るよりも、単純に行を読み取る方が速くなります。ただし、ソート
された順で行が必要な場合、インデックスを読み取ってからそのインデッ
クスを使ってソートされた順に行を読み取るネット・セービングがある場
合があります。
次の 2 つのケースでは、オプティマイザーが 3 つ目のオプションを選択し、
一時的なインデックスを作成する場合があります。結合内のいずれの表に
も結合列上にインデックスがなく、いずれの表も十分大きい場合、オプ
ティマイザーは、1 つの表を使用してもう 1 つの表のそれぞれの列を連続し
て読み取るよりも、1 つの表に対してインデックスを作成する方が迅速で
あると判別する場合があります。また、一時的なインデックスは、ソート
済みまたはグループ化済みのシーケンスで行を生成するために使用するこ
ともできます。( また、出力行を一時表に書き込んで、それをソートしま
す。)
オプティマイザーには、ソート・マージを実行する 4 つ目のオプションが
あり、これは一時的なインデックスを必要としません。これは、少なくと
も 1 つの結合のフィルターが等演算子である場合に自動的に生じます。
問合せ予定の選択
利用できるこのすべての情報を使用して、オプティマイザーは表をペアで
結合させるために可能なすべての問合せ予定を生成します。次に、2 つ以
上の表を結合する場合、オプティマイザーは、最良の 2 つの表の予定を使
用して、2 つの表を 3 つ目の表に、3 つの表を 4 つ目の表にと結合させて、
すべての予定を形成します。
オプティマイザーは、任意の最終作業を完了した結合予定に追加します。
例えば、ORDER BY 節または GROUP BY 節があり、予定が順序付けされた
シーケンスで行を作成しない場合、オプティマイザーは、その予定に出力
をソートするコストの見積りを追加します。ソートについては、4-22 ペー
ジの 『ソートの時間コスト』を参照してください。
最後に、オプティマイザーは、最少量の作業を期待できる予定を選択し、
実行するデータベース・サーバーの主要な部分に渡します。
4-18 問合せの最適化
問合せオプティマイザー
予定の読取り
オプティマイザーが実行する選択は、秘密にしておく必要はありません。
ユーザーは、オプティマイザーがどの問合せ予定を選択するかを正確に確
認できます。問合せを実行する前に、SET EXPLAIN ON を実行します。次の
問合せから始めて、オプティマイザーは問合せ予定の説明を特定のファイ
ルに書き込みます ( ファイル名およびその位置は使用中のオペレーティン
グ・システムによって異なります )。標準的な説明を、図 4-5 に示します。
問合せを繰り返した後、オプティマイザーは、完了される作業の見積り
( 図 4-5 の 104) を任意の単位で表示します。単一ディスク・アクセスが 1
単位で、他のアクションはそれに合わせて見積もられます。この問合せ予
定は、他の予定と比較して、見積りが最低であったために選択されます。
QUERY:
-----SELECT C.customer_num, O.order_num, SUM (I.total_price)
FROM customer C, orders O, items I
WHERE C.customer_num = O.customer_num
AND O.order_num = I.order_num
GROUP BY C.customer_num, O.order_num;
Estimated Cost: 104
Estimated # of Rows Returned: 2
1) pubs.o: INDEX PATH
(1) Index Keys: order_num
2) pubs.c: INDEX PATH
(1) Index Keys: customer_num (Key-Only)
Lower Index Filter: pubs.c.customer_num = pubs.o.customer_num
3) pubs.i: INDEX PATH
(1) Index Keys: order_num
Lower Index Filter: pubs.i.order_num = pubs.o.order_num
図 4-5
SET EXPLAIN ON を使用してオプティマイザーによって作成される標準出力
問合せの最適化 4-19
問合せオプティマイザー
オプティマイザーは、問合せによって作成される行数の見積りも明らかに
します。図 4-5 では、オプティマイザーは、誤って 2 と見積もっています。
オプティマイザーは GROUP BY 節が作成するグループ数を見分ける有効な
方法を持っていないため、この見積りは誤りです。ユーザーは orders 表内
のすべての行にグループが 1 つあることを確認できますが、オプティマイ
ザーはこれを認識することができません。
説明本文では、オプティマイザーは、表にアクセスする順序とそのメソッ
ド、またはそれぞれの表を読み取るために使用するアクセス・パスをリス
トします。次に、この予定を分かりやすく説明します。
1. orders 表が最初に読み取られます。order_num 上のインデックスが使用
されます。この場合、行は order_num シーケンスで読み取られます。
すべての行が読み取られるため、表を連続して読み込む場合には実際そ
れほど労力は必要ありません。ただし、order_num シーケンス内の行を
取得すると、最終のソートを使用しないで、GROUP BY 節を実行させる
ことができます。
2. orders の行ごとに、customer 表内で一致する行に対して検索が実行され
ます。検索は、customer_num 上のインデックスを使用します。
表記 Key-Only は、customer_num 列のみが出力に使用されるため、イン
デックスのみが使用され、行は表から読み取られないことを意味しま
す。
3. 一致する customer_num を持つ orders の行ごとに、order_num 上のイン
デックスを使用して、items 表で検索が実行されます。
オプティマイザーがその選択を行う理由が常に明白であるとは限りません。
問合せ中のいくつかのバリエーションによって作成された予定を比較する
ことによって、通常、そのロジックのいくつかを導き出すことができます。
ただし、これこそオプティマイザーが実行する ことであると認めている説
明ファイルを読むことをお勧めします。そうすると、なぜ それを選択する
かを確かめる必要はありません。
4-20 問合せの最適化
問合せの時間コスト
問合せの時間コスト
問合せを実行するために、データベース・サーバーはその時間のほとんど
を、2 つのタイプの操作、つまりディスクからのデータ読取りと列値の比
較を実行するために使用します。この 2 つのうち、データの読取りははる
かに時間のかかるタスクです。このセクションでは、データベース・サー
バーが時間を費す部分を検証します。次のセクションでは、問合せを高速
にする影響を調査します。
メモリー内の動作
データベース・サーバーは、メモリー内のデータしか処理することができ
ません。フィルター式を使用して行をテストできるようにするには、その
行をメモリー内へ読み取っておく必要があります。結合条件をテストできる
ようにするには、行を両方の表から読み取っておく必要があります。デー
タベース・サーバーは、選択した列をメモリー内の他の行からアセンブル
することによって、メモリー内に出力行を用意します。
これらの動作のほとんどは非常に高速です。コンピューターによっては、
データベース・サーバーは 1 秒に数百または数千もの比較を実行すること
ができます。結果として、メモリー内作業に使った時間は、普通、実行時
間全体のわずかな部分でしかありません。
2 つのメモリー内動作に、かなりの時間がかかることがあります。1 つは
ソートで、これは 4-22 ページの 『ソートの時間コスト』に記載されていま
す。もう 1 つの動作は、LIKE と MATCHES を使用した比較、特に、値の最
初または中間で “ ゼロまたはそれ以上 ” の文字をテストする比較の処理で
す。
ディスク・アクセス管理
ディスクから行を読み取るのは、メモリー内で行を検証するのに比べてか
なりの時間がかかります。オプティマイザーの主要な目標は、ディスクか
ら読み取る必要のあるデータ量を削減することですが、最も明白な非能率
部分だけを除去できます。
問合せの最適化 4-21
問合せの時間コスト
ソートの時間コスト
ソートには、メモリー内の作業とディスク作業の両方が必要です。
メモリー内の作業は、c*w*n*log2(n) に比例します。ここで、各項目
は以下のとおりです。
c
注文されている列数。行から列値を抽出して、それらの値
をソート・キーに連結させるコストを表す。
w
結合されたソート・キーのバイト単位の幅に比例し、1 つ
のソート・キーをコピーまたは比較する作業を表す。w の
数値は、使用中のコンピューター・ハードウェアにかなり
依存します。
n*log2(n)
n 行の表をソート中に作成される比較の数。
ディスク作業は、2*n*m に比例し、n は、ここでも行数を表します。
係数 m は、ソートで使用する必要があるマージのレベル の数値を表
します。この係数は、メモリー内に保留できるソート・キーの数に依
存します。
すべてのキーをメモリー内に保留できる場合、m=1 およびディスク作
業は、2n に比例します。つまり、行は読み取られ、メモリー内で
ソートされて、書き込まれます。( インデックスの作成時は、イン
デックス・ページだけが書き込まれます。)
普通のサイズから大きなサイズまでの表の場合、行はメモリー内に収
まるバッチ内でソートされ、その後、そのバッチはマージされます。
m=2 の場合、行はバッチ内で読み取られ、ソートされて書き込まれま
す。その後、バッチは再び読み取られ、マージされて書き込まれ、結
果として、ディスク作業は 4n に比例することになります。非常に大
きな表の場合、バッチはバッチ内に分割される必要があります。この
場合、ディスク作業は 6n に比例します。つまり、表のサイズが大き
くなれば、ソート内のディスク作業の量は、2n から 4n、6n と突然かつ
不連続的に変更されます。これらのステップで生じる表のサイズは、
多くの要因により、それらのうち 1 つだけ ( キー・サイズ ) はユー
ザーが制御できます。
ソートのコストを削減する一番良い方法は、n が両方の式を支配する
ため、あまり多くの行をソートしないで済む方法を探すことです。こ
れが無理な場合は、数を少なく幅を狭くした列でソートする方法を探
してください。これによって、係数 c および w が削減されるだけでな
く、そのステップが次のマージ・レベルへ延期されます。
4-22 問合せの最適化
問合せの時間コスト
ディスク・ページ
データベース・サーバーは、ページ と呼ばれる単位内のディスク装置を扱
います。ページは、固定されたサイズのブロックです。1 つのデータベー
ス・サーバーによって管理されるすべてのデータベース用に、同サイズが
使用されます。インデックスもページ・サイズ単位で格納されます。
ページのサイズは、データベース・サーバーによって異なります。
IBM Informix OnLine を使用すると、ページ・サイズは OnLine が初期化され
るときにセットされます。これは普通 2 KB (2,048 バイト ) ですが、何が選
択されたかを確認するには、OnLine のインストールを行ったユーザーに連
絡してください。他の IBM Informix データベース・サーバーは、ホスト・
オペレーティング・システムのファイル記憶域を使用するため、これらの
ページ・サイズはホスト・オペレーティング・システムによって使用され
るブロック・サイズです。1 KB (1,024 バイト ) が標準サイズですが、使用
するオペレーティング・システムに応じて、そのサイズを検査しなければ
なりません。
1 行で 1 ページが埋められる程度に幅広く表を定義することができます
( データベース・サーバーによっては、ページのサイズを超える行が認めら
れます )。ただし、標準の行サイズは 50 バイトから 200 バイトであるため、
標準的な表では、ディスク・ページには 5 行から 50 行が入ります。イン
デックス項目は、キー値と 4 バイトのポインターで構成されているため、
インデックス・ページには通常 50 から 500 の項目が含まれています。
ページ・バッファー
データベース・サーバーは、最近読み取ったディスク・ページのコピーを
保管するメモリー領域のセットを保持します。これらのページは再度必要
になるために、データベース・サーバーはこのようにします。ページが必
要となった場合、データベース・サーバーはディスクからそれらのページ
を読み取る必要がなくなります。
ディスク・ページのサイズと同様、これらのページ・バッファー数はデー
タベース・サーバーとホスト・オペレーティング・システムによって異な
ります。
問合せの最適化 4-23
問合せの時間コスト
行の読取りのコスト
データベース・サーバーは、まだメモリーにない行を検証する必要がある
場合、その行をディスクから読み取る必要があります。1 行だけを読み取
ることはしません。その行が含まれるすべてのページを読み取ります。
(1 行が 1 ページより大きい場合、必要なだけ多くのページ全体を読み取り
ます。) 1 ページを読み取るコストは、オプティマイザーがその計算のため
に使用する作業の基本単位です。
ページを読み取る実際のコストは変動しやすく、予測困難です。これは、
次の要因の組合せになります。
バッファリング 必要なページはすでにページ・バッファーにある可能性が
あり、この場合はアクセスのコストはほとんどかかりませ
ん。
競合
複数のアプリケーションがディスク・ハードウェアの使用
で競合している場合、データベース・サーバー要求の処理
は遅れがちです。
シーク時間
ディスクが実行する最も遅いアクションが、シーク、つま
り、データを保留しているトラックにアクセス・アームを
移動させることです。シーク時間は、ディスクの速度と操
作起動時のディスク・アームの位置によって異なります。
シーク時間は、ゼロから、1 秒以下の小数部後半まで変動
します。
待ち時間
転送は、ページの先頭がアクセス・アームの下でローテー
ションを行うまで開始できません。この待ち時間、つまり
回転待ちは、ディスクの速度と操作起動時のディスクの位
置によって異なります。待ち時間は、ゼロから数ミリ秒ま
で変動します。
ページの読み取りの時間コストは、マイクロ秒 ( バッファー内のページに
場合 ) から、数ミリ秒 ( 競合がゼロで、ディスク・アームがすでに位置にあ
る場合 )、数百ミリ秒まで変動します。
4-24 問合せの最適化
問合せの時間コスト
順次アクセスのコスト
ディスク・コストは、データベース・サーバーが表の行を物理的な順序で
読み取るときが最も安くなります。ページの最初の行が要求されると、その
ディスク・ページが読み取られます。後続の行の要求は、ページ全体が使
用されるまでバッファーから実行されます。結果として、それぞれのペー
ジは 1 回しか読み取られません。
データベース・サーバーがディスクを使用する唯一のプログラムであると
すれば、シーク時間コストも最小化されます。連続した行のディスク・
ページは、普通、ディスク上の連続した位置にあるため、アクセス・アー
ムはページから次のページへにかけてほとんど移動しません。このことが
当てはまらない場合でも、連続したページのグループは、普通、ロング・
シークが少ししか必要とされないように一緒に配置されています。例えば、
IBM Informix OnLine は、ディスク領域をマルチページ・エクステント 内の
表に割り当てます。エクステントはディスク上で離れている場合がありま
すが、エクステントがなければページ同士が接近します。
ページが連続して読み取られている場合、さらに待ち時間コストも最低に
なる場合があります。これは、ハードウェアによって異なり、オペレー
ティング・システム・ファイルが使用されているときはオペレーティン
グ・システムのメソッドによって異なります。ディスクは、普通、ページ
が連続して読み取られるときに待ち時間が最小化されるようにセットアッ
プされます。一方で、完全ローテーションがそれぞれの連続ページの間で
生じるようにディスクをセットアップすることもできます。これにより、
連続アクセスは非常に遅くなります。
問合せの最適化 4-25
問合せの時間コスト
非順次アクセスのコスト
ディスク・コストは、表の行が物理的な順序には無関係な順序で呼び出さ
れる場合に高くなります。実際の表は通常データベース・サーバーのペー
ジ・バッファーよりもかなり大きいため、表ページの少しの部分しかメモ
リーに保留できません。表が非順次の順序で読み取られるときは、少数の
行がバッファー付きページ内に検出されます。普通、要求される行ごとに、
1 つのディスク・ページが読み取られます。
ページはディスクから連続的に読み取られないために、通常は、それぞれ
のページを読み取ることができるようになる場合、シーク待ちと回転待ち
の両方があります。つまり、表が非連続的に読み取られるときは、ディス
ク・アクセス時間は、連続的に読み取られるときよりもかなり長くなりま
す。
行 ID アクセスのコスト
非順次アクセスの最も簡単なフォームは、その行 ID 値に基づいた行を選択
することです。(SELECT 文での行 ID の使用については、第 3 章を参照して
ください。データベース設計での行 ID の使用については、第 10 章を参照
してください。) 行 ID 値は、行およびそのページの物理位置を指定します。
データベース・サーバーはページを読み取るだけですが、すでに明記した
コストがかかります。
インデックス・アクセスのコスト
インデックスを使用した行の検索に関係する追加のコストがあります。イ
ンデックス自体はディスク上に格納されますが、そのページはメモリー内
に読み込まれる必要があります。
データベース・サーバーは、2 つの方法でインデックスを使用します。1 つ
目は、キー値を与えられた行をルックアップする方法です。これは、次に
示すステートメントのように、2 つの表を結合するときに使用されるルッ
クアップの種類です。
SELECT company, order_num
FROM customer, orders
WHERE customer.customer_num = orders.customer_num
1 つの表、おそらく customer は連続して読み取られます。customer_num の
値は、orders の customer_num 列上のインデックスを検索するために使用
されます。一致が検索されると、orders のその行が読み取られます。
4-26 問合せの最適化
問合せの時間コスト
インデックス・ルックアップは、ルート・ページからリーフ・ページに向
かって下方向に機能します。(4-29 ページの 『インデックスの構造』を参照
してください。) ルート・ページは、非常によく使用されるため、ほとんど
いつでもページ・バッファーに存在します。バッファー内のリーフ・ペー
ジの検索の可能性は、インデックスのサイズに依存します。表のサイズが
大きくなるほど、その可能性は少なくなります。
表が非常に大きく、インデックス・リーフ・ページの数がバッファー領域
よりもかなり大きい場合、ほとんどすべての検索によって、行を含むペー
ジに加えリーフ・ページが読み取られます。読み取られたページ数は、概
算で r です。ここで、r はルックアップされる行数です。コストは高くなり
ますが、この種類のアクセスはまだ条件が良い方です。というのも、代替
策では、r 2 に比例するディスク・コストで orders 表全体を読み込み、それ
ぞれのルックアップを実行しなければならないからです。
データベース・サーバーがインデックスを使用するもう 1 つの方法は、連
続的にインデックスを読み取ることです。データベース・サーバーは、物
理的な順序以外の特定の順序で表の行を取り出すために、この方法を実行
します。この種のアクセスの場合、データベース・サーバーは順序どおり
リーフ・ページを読み取り、それらのページをキー・シーケンス内の行の
リストとして扱います。インデックス・ページは 1 回しか読み取られない
ため、ディスク操作の合計は r+i に比例します。ここで、i はインデックス
内のリーフ・ページ数です。
小さな表のコスト
これまでのパラグラフから導きだせる 1 つの結論は、小さな表は遅くなら
ないということです。表はほとんどページを取らないために、表がペー
ジ・バッファー内で完全に保存できる場合には、その表は “ 小さい ” といえ
ます。4 ページ以下のページに収まる表は、この意味で確実に “ 小さい ” とい
えます。
stores5 データベースでは、省略形を状態の名前に関連付けるステート・
テーブルは、1,000 バイト以下の合計サイズを保持します。これは、最大で
2 ページに収まります。また、これを、ほとんどコストがかからずにどの
問合せにも含めることができます。このテーブルは何度も連続して読み取
られるなど、使用される方法に関係なく、多くとも 2 つのディスク・アク
セスしか必要ではありません。
問合せの最適化 4-27
問合せの時間コスト
ネットワーク・アクセスのコスト
データがネットワーク上を移動する場合は、さらに遅延が生じます。ネッ
トワークは、次の 2 つのコンテキストで使用されます。
•
IBM Informix NET を使用して、アプリケーションはネットワークを介し
て別のマシンにあるデータベース・サーバーまで問合せを送信します。
データベース・サーバーは、ローカル接続したディスクを使用して問合
せを実行します。出力行は、ネットワークを介してアプリケーションま
で戻されます。
•
IBM Informix OnLine の IBM Informix STAR ( 分散型データ ) コンポーネント
を使用して、あるマシン上のデータベース・サーバーは、もう 1 つのマ
シン上のデータベース内の表から行を読み取って更新することができま
す。
両方のコンテキストを適用できます。つまり、IBM Informix NET を使用し
て、IBM Informix OnLine サーバーを呼び出し、そのサーバーに他のサーバー
でも表を使用することができる問合せを送信することができます。
ネットワークを経由して送信されたデータは、コマンド・メッセージと行
データのバッファー・サイズのブロックで構成されています。2 つのコン
テキスト間の詳細に多くの相違がある一方、これらをシンプル・モデルの
下で同一に扱うこともできます。このモデルでは、送信側 であるマシンが
応答側 であるもう 1 つのマシンに要求を送信し、応答側マシンが表から
データのブロックを戻します。
データがネットワークを介して交換される場合は、常に次のような状態で
遅延が必然的に生じます。
• ネットワークがビジー状態の場合、送信側マシンは転送する順番を待つ
必要があります。通常、このような遅延は短く、ミリ秒以下です。ただ
し、負荷の多いネットワークでは、指数的に 1 秒の 10 分の 1 以上まで
増える可能性があります。
• 応答側マシンは、複数の送信側マシンから要求を取り扱っている場合が
あるため、要求は到着するとキューに入れられ、ミリ秒から数秒までの
間待機することがあります。
4-28 問合せの最適化
問合せの時間コスト
インデックスの構造
インデックスは、次の図に表すように、ページの階層 ( 技術的には B+
ツリー ) として配置されます。下位レベルでは、リーフ・ページ の
シーケンスに表の行のインデックス・キー値が含まれ、それぞれがそ
の値を含む行の位置を指すポインターを持ちます。リーフ・ページ内
のキーは、キー・シーケンス内にあります。
レベルが 1 つ高くなるごとに、ページには、次の下位レベルにあるそ
れぞれのページで検出される最も高いキーの値がリストされています。
最上位のレベルは単一のルート・ページ で、ここからインデックスの
その他のページを見つけることができます。
ルート・ページ
...
...
リーフ・ページ
...
...
リーフ・ページ
...
1 つのエントリーのサイズは、バイト単位のインデックス付き列の幅
に 4 を足したものです。その数値とページ・サイズが分かっている場
合は、ページごとのエントリー数を見積もることができます。この見
積りは、キーの保管時にデータ圧縮され、すべてのページがフルとい
うわけではないため、概算にしかすぎません。
レベル数は、インデックス付けされる行数およびページごとのエント
リー数によって決まります。例えば、ページが 100 のキーを保留する
とします。この場合、100 行を持つ表は、単一のインデックス・ペー
ジ、つまりルート・ページを持ちます。101 から 10,000 までの行を持
つ表は、ルート・ページおよび 2 から 100 までのリーフ・ページで構
成される 2 レベルのインデックスを持ちます。1,000,000 行もある表は、
3 レベルのインデックスしか持ちません ( したがって、前述のインデッ
クスは、かなりのサイズの表に属します。)
問合せの最適化 4-29
問合せの高速化
• 応答側マシンが要求に基づいてアクションを取るときは、前述のトピッ
クで説明したとおり、ディスク・アクセスとメモリー内操作の時間コス
トが必要となります。
• 応答の送信は、再びネットワーク遅延の影響を受けます。
ネットワーク・アクセスの重要ポイントは、非常に変わりやすいというこ
とです。最適な場合は、ネットワークも応答側マシンもビジー状態には
なっていない場合で、送信待ちおよびキューイング待ちはわずかで、応答
側マシンはローカル・データベース・サーバーが行うのとほとんど同じく
らい迅速に行を送信します。また、送信側マシンが 2 つ目の行を要求する
場合、そのページはおそらくまだ応答側マシンのページ・バッファーにあ
ります。
残念ながら、ネットワーク負荷が上がると、これらのすべての要因は同時
に悪くなる傾向にあります。送信の遅延が両方向で生じます。応答側マシ
ンのキューが長くなります。また、ページが応答側マシンのバッファーに
残る確率が低くなります。したがって、ネットワーク・アクセス・コスト
は、「非常に低い」から「極めて高い」に突然変更される可能性がありま
す。
IBM Informix OnLine が使用するオプティマイザーでは、ネットワークを介
して行へアクセスする方が、ローカル・データベース内の行にアクセスす
るよりも時間がかかることが想定されています。オプティマイザーは、変
化するネットワーク負荷を説明する手段がないため、悲観的になることも、
また楽観的になることもあります。
問合せの高速化
一般に、次のことができるように問合せを変更することによって、速度を
上げることができます。
• 行の読み取りを少なくする
• ソートを回避したり、ソートする行を少なくしたり、簡単なキーでソー
トする
• 非連続的ではなく連続的に行を読み取る
これらを達成する方法は、いつも明白であるとは限りません。固有のメ
ソッドは、アプリケーションおよびデータベース設計の詳細によって決ま
ります。次のパラグラフで、一般的なアプローチについて提案します。こ
こでは、限定された環境で適用されるいくつかの技法についても説明しま
す。
4-30 問合せの最適化
問合せの高速化
テスト環境の準備
最初に、遅すぎる問合せを 1 つ選択します。次に、その問合せの予測可能
で反復可能なタイミングをとることができる環境をセットアップします。
この環境がなければ、変更が役立ったかどうかを確認することはできませ
ん。
マルチユーザー・システムまたはネットワークを使用している場合、シス
テム負荷が時間ごとに幅広く変わるように、毎日同じ時間に試験して反復
可能な結果を得る必要があります。夜も作業する必要があるかもしれませ
ん。
問合せが現在複雑なプログラム内に埋め込まれている場合には、SELECT 文
を取り出して対話的に実行するか、またはもっと簡単なプログラムに埋め
込むことを考慮してください。
実際の問合せの完了に何分も何時間もかかる場合は、テストをより迅速に
実行できるように、スケール・ダウンされたデータベースを準備すると良
いかもしれません。この方法は役立ちますが、次の 2 つの潜在的な問題に
注意しておく必要があります。
• オプティマイザーは、表の相対的なサイズが同じ場合でも、大きなデー
タベース内とは異なる選択を小さなデータベース内で行うことができま
す。問合せ予定が、実際のデータベースとモデリング・データベースで
同じであることを確認してください。
• 実行時間は、まれに表サイズの線形関数であることがあります。例え
ば、インデックスが 2 レベルから 3 レベルに上がるときにインデック
ス・アクセスのコストも増えるように、ソート時間は表サイズよりも速
く増えます。また、スケール・ダウンされた環境内で大きな改善だと思
えるものでも、完全データベースに適用するとわずかなものである可能
性があります。
したがって、モデリング・データベースでのテスト結果として出す結論は、
大きなデータベースで確認するまでは仮の結論です。
問合せの最適化 4-31
問合せの高速化
データ・モデルの理解
データベース内で使用されるすべての表、ビュー、およびインデックスの
定義方法を説明します。詳細については、DB-Access または IBM Informix
SQL の表オプションを使用して対話的に検証できます。存在するインデッ
クス、結合条件で整列のために使用される列のデータ型、およびビューの
存在に特別な注意を払ってください。この章は、ユーザーがデータ・モデル
を変更できないことを想定して書かれています。しかし、このモデルを理
解すればするほど、オプティマイザーが選択する問合せ予定をより深く理
解できるようになります。
データ型とビューの詳細については、それぞれ、本書の第 9 章と第 11 章を
参照してください。
問合せ予定の理解
使用されている問合せ予定を判別するには、SETEXPLAIN ON を使用します。
特に調べるべき項目のいくつかを、次に示します。
• 予期しない表が結合されます。ビューに対する問合せによって、しばし
ば、予期した以上に多くの表が結合されます。
• 一時ファイル と呼ばれるのは、出力が一時表に現在書き込まれており、
その後でソートされることを意味します。ディスク・アクセス数は、少
なくとも、ソートが必要とされなかった場合の 2 倍になります。
• 結合内の 2 つ目またはそれ以降の表に順次アクセス・パスを使用する
と、その表は、予定内でその表に先行するすべての表のすべての選択済
み行のために、完全に読み取られることを意味します。
• 自動作成されたインデックス・パスを使用すると、データベース・サー
バーは、複数の順次アクセスを回避する方法として、インデックスを構
築するための時間をとることがあります。
• 結合内の最初の表に順次アクセス・パスを使用すると、その行のわずか
な部分しか出力に表示されないため無駄な場合があります。
4-32 問合せの最適化
問合せの高速化
問合せの再考
ここまでで、問合せによって実行されることについては理解しました。次
は、あまり苦労しないで同じ出力を得る方法を探してみてください。次の
提案は、上述のリストと対応しています。
ビューを使用した結合の再書込み
問合せによって、それ自身が結合であるビューに表を結合することができ
ます。より少数の表に直接結合する問合せを再書込みする場合、より簡単
な問合せ予定を作成することができます。
ソートの回避と単純化
ソートは必ずしも否定すべきものではありません。データベース・サー
バーのソート・アルゴリズムは、高度に調整され、非常に有効なものです。
同じデータに適用する任意の外部ソート・プログラムとほぼ同じ速さです。
ソートがほとんど実行されなかったり、比較的少数の出力行に対して実行
される場合は、ソートを回避する必要はありません。
ただし、大きな表の反復されるソートは回避または単純化するようにして
ください。オプティマイザーは、インデックスを使用して正しい順序で自
動的に出力を作成できるときは、常にソート・ステップを回避します。オ
プティマイザーのインデックス使用を妨げるいくつかの要因を、次に示し
ます。
• 1 つまたは複数の順序付けされた列がインデックスに含まれていない。
• インデックスおよび ORDER BY 節または GROUP BY 節で、異なるシーケ
ンスで列に名前が付けられている。
• 順序付けされた列が異なる表から取られている。
ソートを回避する他の方法は、4-39 ページの 『問合せの速度を上げるため
の一時表の使用』に説明されています。
ソートが必要な場合は、ソートを単純化する方法を探してください。4-22
ページの 『ソートの時間コスト』に記載されているとおり、ソートは、少
数または狭い列でソートできる場合には高速になります。
問合せの最適化 4-33
問合せの高速化
大きな表への順次アクセスの除去
予定内の最初の表以外の表への順次アクセスは、その表のすべての行を前
の表から選択されたすべての行ごとに 1 回読み込むことを強要します。そ
れが何回であるかを確認することができます。わずかな場合もあれば、何
百または何千かもしれません。
小さな表の場合は、何度読み込んでも問題はありません。つまり、表は完
全にメモリー内に常駐します。メモリー内の表の順次検索は、インデック
スを使用して同じ表を検索するよりも高速になります。特に、メモリー内
にインデックス・ページがあるときは、他の役立つページがバッファーか
ら押し出されるため高速になります。
ただし、表が数ページよりも大きい場合、反復順次アクセスはパフォーマ
ンスにとって致命的です。これを回避する 1 つの方法は、表の結合に使用
されている列にインデックスを提供することです。
インデックス機能の主題については、10-21 ページの 『インデックスの管
理』のデータベース設計のコンテキストに記載されています。ただし、
Resource アクセス権を持つユーザーは、追加のインデックスを作成するこ
とができます。インデックスを作成するには、CREATE INDEX コマンドを使
用します。
インデックスは、キー値の幅と行数に比例してディスク領域を消費します。
(4-29 ページの 『インデックスの構造』を参照してください。) また、デー
タベース・サーバーは、行が挿入、削除、または更新されるときは常にイ
ンデックスを更新する必要があります。これによって、これらの操作は遅
くなります。必要な場合、DROP INDEX を使用して、一連の問合せの後にイ
ンデックスを解放できます。この場合、領域が解放され、表をより簡単に
更新することができます。
4-34 問合せの最適化
問合せの高速化
順次アクセスを回避するための UNION の使用
WHERE 節の特定のフォームは、インデックスがすべてのテスト済み列に存
在する場合でも、順次アクセスを使用することをオプティマイザーに強制
します。次の問合せは、orders 表への順次アクセスを強制実行します。
SELECT * FROM orders
WHERE (customer_num = 104 AND order_num > 1001)
OR order_num = 1008
キー・エレメントは、2 つ ( またはそれ以上 ) の行の分離セットが検索され
るということです。これらのセットは、OR で接続された関係式によって定
義済みです。例では、次の 1 セットがこのテストによって選択されていま
す。
(customer_num = 104 AND order_num > 1001)
もう 1 つのセットがこのテストによって選択されています。
order_num = 1008
オプティマイザーは、customer_num 列と order_num 列にインデックスが
ある場合でも、順次アクセス・パスを使用します。
この形式の問合せは、UNION 問合せに変換することによって速度を上げる
ことができます。行のセットごとに独立した SELECT 文を書き込み、それ
らを UNION キーワードを使用して接続します。このように再書込みする
と、上述の例は次のようになります。
SELECT * FROM orders
WHERE (customer_num = 104 AND order_num > 1001)
UNION
SELECT * FROM orders
WHERE order_num = 1008
オプティマイザーは、問合せごとにインデックス・パスを使用します。
問合せの最適化 4-35
問合せの高速化
自動作成されたインデックスへのインデックスの置換
問合せ予定に大きな表への自動作成されたインデックス・パスが含まれて
いる場合は、インデックスがその列上になければならないというオプティ
マイザーからの推奨事項としてとらえてください。問合せをほとんど実行
しない場合は、データベース・サーバーにインデックスを作成させて破棄
させるのが合理的ですが、問合せが毎日行われる場合は、永久インデック
スを作成して時間を節約してください。
複合インデックスの使用
オプティマイザーは、複合インデックス ( 複数の列をカバーするインデッ
クス ) をいくつかの方法で使用することができます。列 abc の値が一意であ
ると、保証する通常の関数に加え、列 a、b、および c ( この順序 ) 上のイン
デックスは、次の方法で使用できます。
• 列 a でフィルター式を評価する
• 列 a を別の表に結合する
• ORDER BY または GROUP BY を、列 a、ab、または abc (b、c、ac、または
bc 以外 ) 上で実装する
アプリケーションがいくつかの長い問合せを実行しており、それらのどの
問合せにも同じ列上にソートが含まれている場合、それらの列上に複合イ
ンデックスを作成して時間を節約することができます。実際、ソートを 1
回実行して、その出力をすべての問合せで使用できるように保存します。
疑わしいインデックスでの tbcheck の使用
いくつかのデータベース・サーバーを使用すると、インデックスは、内部
で破損されたために無効になる可能性があります。インデックスを使用す
る問合せが非常にスローダウンした場合には、bcheck ユーティリティーを
使用してインデックスの整合性を検査し、必要があればそれを修復してく
ださい。(bcheck ユーティリティーは、IBM Informix SE 用にも同じジョブを
実行します。)
更新後のインデックスの削除と再構築
多くの更新を行った後 ( 表の行を 4 回以上置換した後 )、インデックスの構
造が非効率になる可能性があります。インデックスが通常よりも効率が悪
くなってきたように見えても、bcheck がエラーを記録しない場合は、その
インデックスを削除してもう一度作成してください。
4-36 問合せの最適化
問合せの高速化
相関副問合せの回避
相関副問合せでは、列レベルが、メインの問合せの選択リストと副問合せ
の WHERE 節の両方に表示されます。副問合せの結果はデータベース・サー
バーが検証する行ごとに異なることがあるため、副問合せは、現行の照合
値が以前の値と異なる場合はすべての行に対して新しく実行されます。オ
プティマイザーは、照合値上のインデックスを使用して、同一値を一緒に
クラスター化しようと試みます。このプロシージャーは、非常に時間がか
かる可能性があります。残念ながら、いくつかの問合せは、相関副問合せ
を使用しなければ、SQL で示すことはできません。
時間のかかる SELECT 文に副問合せがある場合、それが相関しているかどう
かを確認してください。( メインの問合せからの行の値が副問合せ内でテス
トされない非相関副問合せは 1 回しか実行されません。) この場合、それを
回避するために問合せを再作成してみてください。問合せを再作成できな
い場合は、検証する行数を削減する方法を探してみてください。例えば、
他のフィルター式を WHERE 節に追加したり、行のサブセットを一時表へ選
択して、行のサブセットだけを検索してみてください。
困難な正規表現の回避
MATCHES および LIKE のキーワードは、ワイルドカード・マッチ ( 専門的
には正規表現 と呼ばれる ) をサポートします。— 正規表現には、データ
ベース・サーバーが処理する他の正規表現よりも難しいものがあります。
次の例 ( ファーストネームが y で終わらない顧客を検索 ) では、最初の位置
にあるワイルドカードは、データベース・サーバーに列内のすべての値を
検証することを強制します。
SELECT * FROM customer WHERE fname NOT LIKE "%y"
オプティマイザーは、インデックスが存在しても、このようなフィルター
のためにインデックスを使用しません。オプティマイザーは、表の順次ア
クセスを強制実行します。表が 2 つ目以降の結合内の表の場合、問合せは
遅くなります。
正規表現の困難なテストが不可欠な場合は、結合と組み合わせないように
してください。まず最初に、単一の表を処理して、必要な行を選択するた
めに正規表現のテストを適用します。結果を一時表に保存して、その表を
他の表に結合します。
問合せの最適化 4-37
問合せの高速化
オペランドの中間または最後にのみワイルドカードが付く正規表現テスト
では、インデックスが存在する場合、そのインデックスの使用は妨げられ
ません。ただし、それでも実行が遅い場合があります。列内のデータに
よっては、いくつかの表現式を関係演算子を使用した範囲テストに変換で
きます。次に、SELECT 文の例を示します。
SELECT * FROM customer WHERE zipcode LIKE "98_ _ _"
関係演算子を使用して、この SELECT 文を再書込みできます。
SELECT * FROM customer WHERE zipcode >= "98000"
非初期サブ文字列の回避
列の非初期サブ文字列を基にしたフィルターもまた、列内のすべての値を
テストする必要があります。次に、例を示します。
SELECT * FROM customer
WHERE zipcode[4,5] > "50"
オプティマイザーは、インデックスが存在する場合でも、インデックスを
使用してこのようなフィルターを評価しません。
オプティマイザーは、インデックスを使用して、インデックス付き列の初
期サブ文字列をテストするフィルターを処理します。ただし、サブ文字列
テストがあるために、サブ文字列列と別の列の両方をテストするための複
合インデックスの使用が妨げられる可能性があります。
初期サブ文字列のテストは、しばしば、列全体における関係型テストまた
は BETWEEN テストとして再書込みすることができ、完了すると高速にな
ることがあります。
4-38 問合せの最適化
問合せの高速化
問合せの速度を上げるための一時表の使用
一時的に順序付けされた表のサブセットを作成することによって、時々問
合せが速くなることがあります。これは、複数ソート操作を回避する場合
に役立ち、オプティマイザーの作業を他の方法で単純化することができま
す。
複数ソートを回避するための一時表の使用
例えば、使用しているアプリケーションで、未払いの収支がある顧客につ
いての一連のレポートを、主要な郵便区域ごとに、顧客名順に作成してい
るとします。つまり、次のフォームのような一連の問合せがあります ( 仮
の表と列名を使用 )。
SELECT cust.name, rcvbles.balance, ...other columns...
FROM cust, rcvbles
WHERE cust.customer_id = rcvbles.customer_id
AND rcvbls.balance > 0
AND cust.postcode LIKE "98_ _ _"
ORDER BY cust.name
この問合せは、cust 表全体を読み取ります。正しい郵便番号を持つすべて
の行に対し、データベース・サーバーは rcvbles.customer_id 上のインデッ
クスを検索し、一致したものすべてに対して非順次ディスク・アクセスを
実行します。行は、一時ファイルに書き込まれてソートされます。
このプロシージャーは、問合せが 1 回だけ実行される場合に許容できます
が、この例には、それぞれが同じ量の作業を負う一連の問合せが含まれて
います。
代替方法では、未払いの収支があるすべての顧客を選択し、一時表に入れ
て、顧客名順に順序付けします。次のようになります。
SELECT cust.name, rcvbles.balance, ...other columns...
FROM cust, rcvbles
WHERE cust.customer_id = rcvbles.customer_id
AND cvbls.balance > 0
ORDER BY cust.name
INTO TEMP cust_with_balance
問合せの最適化 4-39
問合せの高速化
これで、次のようなフォームで、一時表に対して問合せを送信できるよう
になりました。
SELECT *
FROM cust_with_balance
WHERE postcode LIKE "98_ _ _"
それぞれの問合せは連続して一時表を読み取りますが、その表には主表ほ
ど行はありません。非順次ディスク・アクセスは実行されません。表の物
理的順序が望ましい順序であるため、ソートは必要ありません。以前と比
べて、かかる労力が全体的にかなり少なくなります。
潜在的な欠点が 1 つあります。一時表が作成された後に主表に加えられた
変更は、出力に反映されません。これはほとんどのアプリケーションでは
問題にはなりませんが、問題になるアプリケーションもあります。
非順次アクセスの代替用ソートの使用
非順次ディスク・アクセスは、最も遅い種類です。SQL 言語は、この事実を
隠して、非順次に膨大なページ数にアクセスする問合せの書込みを容易に
します。データベース・サーバーのソート機能の代わりに非順次アクセス
を使用することによって、問合せの効率を改善することができる場合もあ
ります。次の例で、このことについて示します。また、問合せ予定のコス
トの数値見積りを作成する方法についても説明します。
図 4-6 の図式に示される 3 つの表を含むデータベースを持つ大きな製造会
社を想像してみてください。( このフォームの表の図は、本書の第 8 章に説
明されています。すべての列が表示されるわけではありません。)
最初の表 part には、会社の製品に使用されるパーツが含まれています。
2 番目の表 vendor には、それらのパーツを供給するベンダーについての
データが含まれています。3 番目の表 parven には、どのベンダーからどの
パーツが使用できるか、およびその価格が記録されています。
図 4-6
4-40 問合せの最適化
製造データベースからの 3 つの表
問合せの高速化
part
part_num
vendor
part_desc
vendor_num
pk
100,000
999,999
vendor_name
pk
spiral spanner
spotted paint
9,100,000
9,999,999
Wrenchers SA
Spottiswode
parven
part_num
vendor_num
pk、fk
100,000
999,999
pk、fk
9,100,000
9,999,999
金額
$14.98
$0.066
次の問合せは、これらの表に対して定期的に実行され、利用できるすべて
の価格のレポートを作成します。
SELECT part_desc, vendor_name, price
FROM part, vendor, parven
WHERE part.part_num = parven.part_num
AND parven.vendor_num = vendor.vendor_num
ORDER BY part.part_num
比較的単純な 3 つの表結合に見えますが、問合せにはかなりの時間がかか
ります。調査の一部として、表およびそのインデックスの概算サイズを
ページ単位で示す表を準備します。この表は、図 4-7 のように表されます。
これは、4,096 バイトのディスク・ページ・サイズを基にしています。近似
値だけが使用されます。行の実際の数値はしばしば変わり、いかなる場合
にも見積り計算だけが実行されます。
さらに調査すると、part_num 上のインデックスがクラスター化されること
が分かります。そのため、part 表は part_num によって物理的な順序に並
びます。同じように、vendor 表は、vendor_num によって物理的な順序に
並びます。parven 表は、特定の順序で並びません。これらの表のサイズ
は、バッファー・ページからの非順次アクセスの正常終了の可能性が非常
に薄いことを示します。
この問合せ ( オプティマイザーが選択するものでなくてもよい ) の最善の問
合せ予定は、part 表を最初に連続して読み取り、次に part_num の値を使
用して parven の一致する行 ( パーツにつき約 1.5) にアクセスし、parven.vendor_num の値を使用してインデックスを介して vendor にアクセス
します。
問合せの最適化 4-41
問合せの高速化
表
行サイズ
行カウント
150
150
13
10,000
1,000
15,000
part
vendor
parven
インデックス
part_num
vendor_num
parven ( 複合 )
図 4-7
行 / ページ
25
25
300
データ・ページ
400
40
50
キー・サイズ キー / ページ リーフ・ページ
4
4
8
500
500
250
20
2
60
表とインデックスのサイズ ( ページ単位 ) の文書化
ディスク・アクセスの結果値は、次のようにして見積もることができます。
• part から連続して読み取られた 400 ページ
• parven 表への 10,000 の非順次アクセス、各 2 ページ (1 インデックス・
リーフ・ページ、1 データ・ページ )、または 20,000 ディスク・ページ
• vendor 表への 15,000 の非順次アクセス、または 30,000 のディスク・
ページ
適切にインデックス付けされた表における単純結合でさえ、50,400 のディ
スク読込みコストがかかる可能性があります。ただし、図 4-8 に示すよう
に、一時表を使用して問合せを 3 つのステップに分けることによって、こ
れを改善することができます。( 次の解決策は、W.H. Inmon 氏のもので、
著書 「Optimizing Performancein DB2 Software, Prentice-Hall 1988」にある例か
らの抜粋です。)
4-42 問合せの最適化
問合せの高速化
ディスク・ページ
5,000
10,000
15,000
20,000
25,000
30,000
35,000
40,000
45,000
50,000
順次と非順次のディスク・アクセス
part
parven
vendor
400 ページ
20,000 ページ
30,000 ページ
一時表を使用したディスク・アクセス
pv_by_vn
pvvn_by_pn
最終の問合せ
図 4-8
300 ページ
892 ページ
580 ページ
一時表を使用した、問合せの 3 つのステップへの分割
最初のステップは、vendor_num の順序で parven 表のデータを入手するこ
とです。
SELECT part_num, vendor_num, price
FROM parven
ORDER BY vendor_num
INTO TEMP pv_by_vn
この文は、parven (50 ページ ) を連続して読み込み、一時表 (50 ページ ) を
書き込み、ソートします。ソートのコストは、1 つのマージ・レベルを想
定して、合計 300 ページの場合、約 200 ページです。
この一時表を vendor に結合させて、その結果を part_num によって順序付
けられた別の一時表に入れます。
SELECT pv_by_vn.*, vendor.vendor_name
FROM pv_by_vn, vendor
WHERE pv_by_vn.vendor_num = vendor.vendor_num
ORDER BY pv_by_vn.part_num
INTO TEMP pvvn_by_pn;
DROP TABLE pv_by_vn
問合せの最適化 4-43
問合せの高速化
この問合せは、pv_by_vn を連続して読み取ります (50 ページ )。問合せは、
インデックスを使用して vendor に 15,000 回アクセスしますが、キーが
vendor_num シーケンスで表示されるため、結果として、インデックスを
使用して vendor を連続して読み取ります (42 ページ )。
vendor_name フィールドが 32 バイトの長さの場合、出力表には 1 ページに
つき約 95 行が含まれ、約 160 ページを占めます。これらのページは、書き
込まれてからソートされ、5 × 160=800 ページの書込みと読込みが生じま
す。したがって、この問合せは、全部で 892 ページの読取りまたは書込み
を行います。ここで、その出力を最終結果の part に結合します。
SELECT pvvn_by_pn.*, part.part_desc
FROM pvvn_by_pn, part
WHERE pvvn_by_pn.part_num = part.part_num;
DROP TABLE pvvn_by_pn
この問合せは、pvvn_by_pn を連続して読み取ります (160 ページ )。問合せ
は、インデックスを使用して part に 15,000 回アクセスしますが、再びキー
が part_num シーケンスで表示されるため、結果として、インデックス (42
ページ ) を使用して part を連続して (400 ページ ) 読み取ります。出力は、
ソートされた順で作成されます。
問合せを 3 つのステップに分割してインデックス・アクセスの代わりに
ソートを使用することによって、50,400 ページを読み取る問合せは、30 対
1 の割合で概算 1772 ページを読み取って書き込む問合せに変換されます。
注 : バージョン 4.1 以前の IBM Informix データベース・サーバーでは、
ORDERBY 節と INTO TEMP 節を同じ問合せで使用することができません。こ
れらのデータベース・サーバーを使用して整列せずに INTO TEMP を選択し、
その後、クラスター化されたインデックスを介して望ましい整列を適用す
ることによって、前の解決策を実現することができます。改善率は、30 対
1 ではなく、最高でも 15 対 1 です。
4-44 問合せの最適化
サマリー
サマリー
パフォーマンスの低さは多くの原因から生じており、プログラム内の SQL
操作だけが原因ではありません。コード改善する前に、次のことを行って
ください。
• マシン、閲覧者、プロシージャー、および構成の観点からアプリケー
ションを検証する。
• アプリケーションが何を、誰に対して、なぜ実行するかを正確に理解す
る。
• 専門的でない解決策を、周辺のコンテキストから探す。
• アプリケーションのパフォーマンスを繰返し量的に測定する方法を開発
する。
• 時間浪費の部分をできるだけ分離させる。
個別の問合せのパフォーマンスは、オプティマイザーによって決定されま
す。オプティマイザーは、問合せ予定、つまり表がディスクから読み取ら
れる順序を定式化するデータベース・サーバーの一部です。オプティマイ
ザーは、問合せ予定をすべてリストし、それぞれの予定によって引き起こ
される作業量を見積もります。次に、最も見積り量が少ない予定をデータ
ベース・サーバーに渡して実行します。
次の操作は、問合せの結果に時間がかかります。
• ディスクから連続的に、ROWID を使用して非連続的に、インデックス
を使用して非連続的に行を読み取る
• ネットワークを介して行を読み取る
• ソート
• 正規表現での一致による難しい操作をいくつか実行する
問合せを速くする一般的な方法は、まず、SETEXPLAIN ON 機能によって文
書化されたオプティマイザーの問合せ予定を理解することです。次に、
データベースが以下の操作を行うように問合せを変更します。
• ディスクから読み込むデータのページを少なくする
• 非連続的ではなく連続してページを読み取る
• ソートを回避、ソートする行を削減、または幅の狭い列でソートする
このような方法で、驚くほど時間を節約することができます。時間が節約
されない場合でも、アプリケーションと問合せについて理解することに
よって、少なくとも時間がどこで使われているのかが明確になります。
問合せの最適化 4-45
サマリー
4-46 問合せの最適化
データを修正する文
概要 3
データを修正する文 4
行の削除 4
表のすべての行の削除 4
行数が既知の行の削除 5
行数が不明の行の削除 5
複雑な削除条件 6
行の挿入 7
単一行 7
複数の行および式 9
行の更新 11
更新する行の選択 12
一様値による更新 13
不可能な更新 13
選択値による更新 14
データベース・アクセス権 15
表アクセス権の表示 16
データ整合性 17
実体整合性 18
意味整合性 18
参照整合性 19
中断された修正 21
トランザクション 22
トランザクション・ログ 22
トランザクションの指定 23
第
5
章
アーカイブおよびログ 24
単純なデータベースのアーカイブ (IBM Informix SE) 24
IBM Informix OnLine のアーカイブ 25
同時実行性およびロック 26
サマリー 26
5-2 データを修正する文
概要
データの修正は、データの問合せと基本的に異なります。データの問合せ
では、表の内容を検証します。データの修正では、表の内容の変更 を含み
ます。
問合せ中にシステムのハードウェアまたはソフトウェアに障害が発生する
と、どのような事態になるかを考えてください。この場合、アプリケー
ションに大きな影響が及ぶことはあっても、データベース自体は損傷しま
せん。ただし、修正中にシステムに障害が起こると、データベース自体の
状態が不正確になります。この場合の影響は、明らかに広い範囲に及ぶこ
とがあります。データベースの行を削除、挿入、または更新する前に、次
のことを確認してください。
• データベースおよび表へのユーザー・アクセスが安全であるか、つま
り、特定のユーザーに対してデータベース・レベルおよび表レベルのア
クセス権が制限されているか。
• データを修正しても、データベースの既存の整合は保持されるか。
• システムまたはハードウェアの障害をもたらす可能性のある外部イベン
トからデータベースを保護するシステムが組み込まれているか。
上記の各質問に「はい」と答えることができなくても、大きな問題にはな
りません。データベース・サーバーには、上記のすべての問題に対するソ
リューションが組み込まれています。この章では、データを修正する文を
示した後、これらのソリューションについて説明します。このマニュアル
の第 8 ~ 11 章では、これらのトピックについてより詳しく説明します。
データの修正 5-3
データを修正する文
データを修正する文
次に示す 3 つの文は、データを修正します。
•
•
•
DELETE
INSERT
UPDATE
これらの SQL 文は、より高度な SELECT 文と比べると比較的単純ですが、
データベースの内容を変更する文であるため、注意して使用してください。
行の削除
DELETE 文は、表から特定の行または複数の行を削除します。トランザク
ションのコミット後に削除された行は、復旧できません ( トランザクショ
ンについては、5-21 ページの 『中断された修正』を参照してください。こ
こでは、トランザクションと文は同じものであると想定します)
。
行を削除するときは、削除する行に依存する他の表のすべての行も、注意
して削除する必要があります。ただし、データベースに参照制約が適用さ
れている場合は、他の行が依存している行を削除することはできません。
参照制約の詳細については、セクション 5-19 ページの 『参照整合性』を参
照してください。
表のすべての行の削除
DELETE 文は表を指定する文であり、通常は、表から削除する 1 つまたは複
数の行を指定する WHERE 節を含みます。WHERE 節を指定しないと、すべ
ての行が削除されます。次の文は実行しないでください。
DELETE FROM customer
この DELETE 文には WHERE 節が含まれていないため、customer 表内のすべ
ての行が削除されます。
DB-Access または IBM Informix SQL メニュー・オプションを使用して無条件
に削除する場合は、警告および確認メッセージが表示されます。ただし、
プログラム内から無条件削除を実行する場合は、警告が表示されません。
5-4 データの修正
データを修正する文
行数が既知の行の削除
DELETE 文内の WHERE 節は、SELECT 文内の WHERE 節と書式が同じです。
この節を使用すると、削除する行を正確に指定できます。例えば、特定の
カスタマー番号を持つカスタマーを削除できます。
DELETE FROM customer WHERE customer_num = 175
この例では、customer_num 列に一意性制約が設定されているため、最大で
も 1 行しか削除されません。
行数が不明の行の削除
インデックスの付いていない列に基づいて、例えば次のように行を選択す
ることもできます。
DELETE FROM customer WHERE company = "Druid Cyclery"
テスト対象の列には一意性制約が設定されていないため、この文を実行す
ると複数の行が削除されることがあります (Druid Cyclery には、名前が同じ
でカスタマー番号が異なる店舗が 2 つあります )。
DELETE 文の影響を受ける行数を調べるには、customer 表で、値が Druid
Cyclery である行数をカウントします。
SELECT COUNT(*) FROM customer WHERE company = "Druid Cyclery"
目的の行を選択して表示し、削除する必要がある行であることを確認する
こともできます。
ただし、複数のユーザーがデータベースを並行使用できる場合は、SELECT
文をテストとして使用しても、おおよそのデータしか得られません。ユー
ザーが SELECT 文を実行してから DELETE 文を実行するまでの間に、他の
ユーザーが表を修正して、結果が変わることがあるためです。この例では、
別のユーザーが次の操作を行うことがあります。
• Druid Cyclery という名前の別のカスタマーに関する新規の行を挿入す
る。
• ユーザーよりも先に、Druid Cyclery の行を 1 つ以上削除する。
• Druid Cyclery の行を新規の会社名に更新するか、または他のカスタマー
の会社名を Druid Cyclery に更新する。
データの修正 5-5
データを修正する文
この短期間に他のユーザーがこれらの操作を行う可能性はほとんどありま
せん が、まったくないわけではありません。これと同じ問題は、UPDATE
文にも影響します。この問題の解決方法については、5-26 ページの 『同時
実行性およびロック』で説明し、詳細についてはこのマニュアルの 第 7 章
で説明します。
文が終了する前に、ハードウェアまたはソフトウェア障害が発生する場合
もあります。この場合には、行が削除されていないか、一部の行が削除さ
れているか、または指定された行がすべて削除されている可能性がありま
す。データベースの状態 は不明であり、この状況は望ましくありません。
この状況を防ぐには、トランザクション・ログ機能を使用します (5-21 ペー
ジの 『中断された修正』を参照 )。
複雑な削除条件
DELETE 文内の WHERE 節は SELECT 文内の場合と同じくらい複雑になるこ
とがあります。この節には、複数の条件を AND および OR で接続して指定
したり、副問合せを指定することができます。
stock 表の行の一部に不正なメーカー・コードが入力されていたことを見つ
けたとします。これらの行を更新する代わりに、削除して再入力するとし
ます。お分かりのように、これらの行は、正しい行と異なり、manufact 表
内に一致する行がありません。このため、ユーザーは次の DELETE 文を作
成することができます。
DELETE FROM stock
WHERE 0 = (SELECT COUNT(*) FROM manufact
WHERE manufact.manu_code = stock.manu_code)
副問合せは一致する manufact の行数をカウントします。正しい stock 行の
場合、カウントは 1、不正な行の場合、カウントは 0 です。正しくない行が
削除対象として選択されます。
複雑な条件を含む DELETE 文を作成する方法の 1 つは、まず最初に、削除
する行を正確に戻す SELECT 文を作成することです。この文は SELECT * の
ように記述します。この文が目的の行セットを戻す場合は、SELECT * を
DELETE に変更して、もう 1 度実行します。
DELETE 文の WHERE 節では、同じ表をテストする副問合せを使用すること
ができません。つまり、stock 表の行を削除する場合は、WHERE 節内で、
stock の行を選択する副問合せを使用できません。
このルールで重要なのは、FROM 節です。表の名前が DELETE 文の FROM 節
で指定されている場合は、この名前を DELETE 文の副問合せの FROM 節に
も使用することができません。
5-6 データの修正
データを修正する文
行の挿入
INSERT 文は、表に新規の行を 1 つまたは複数追加します。この文には 2 つ
の基本的な機能があります。1 つは、指定された列の値を使用して新規の
単一行を作成すること、もう 1 つは、他の表から選択されたデータを使用
して新規の行グループを作成することです。
単一行
最も単純な書式では、INSERT 文は列値のリストから新規の行を 1 つ作成し
て、表に格納します。次に、stock 表に単一行を追加する例を示します。
INSERT INTO stock
VALUES(115, "PRC", "tire pump", 108, "box", "6/box")
stock 表には次の列があります。
•
•
•
•
•
•
stock_num ( 商品のタイプを識別する数値)
manu_code (manufact 表への外部キー )
description
unit_price
unit ( 計測単位 )
unit_descr ( 計測単位の特徴 )
この前の例の VALUES 節にリストされた値は、この表の列と 1 対 1 の対応
関係にあることにご注意ください。VALUES 節を作成する場合は、表の列、
および最初の列から最後の列までの順番を把握しておく必要があります。
可能な列値
VALUES 節は定数値のみ を受け入れ、式は受け入れません。指定できる値
は、以下のとおりです。
•
•
•
•
•
•
•
•
リテラル番号
リテラル日時 (DATETIME) 型値
リテラル時間隔 (INTERVAL) 型値
引用符付き文字列
NULL 値を表す単語 NULL
今日の日付を表す単語 TODAY
現在の日時を表す単語 CURRENT
ユーザー名を表す単語 USER
データの修正 5-7
データを修正する文
• データベース・サーバーが実行されているコンピューター名を表す
DBSERVERNAME ( または SITENAME)
表の列の中には、NULL 値が許可されていないものがあります。このよう
な列に NULL を挿入しようとしても、拒否されます。また、表の列の中に
は、重複値が許可されていないものもあります。このような列に含まれる
既存の値と重複する値を指定しても、拒否されます。列の中には、使用が
許可されている列値も制限する ものがあります。これらの制限は、データ
整合性制約を使用して列に適用されます。データ制限の詳細については、
5-15 ページの 『データベースのアクセス権』を参照してください。
SERIAL データ型を設定できるのは、表内の 1 つの列のみです。シリアル列
の値は、データベース・サーバーによって生成されます。シリアル列の値
を生成するには、シリアル列に値ゼロを指定し、次の実際の値をデータ
ベース・サーバーに順々に生成させます。シリアル列では、NULL 値が許
可されません。
シリアル列に非ゼロ値を指定して ( 列内の重複値または既存の値でない場
合 )、データベース・サーバーでこの値を使用することができます。ただ
し、この非ゼロ値によって、データベース・サーバーが生成する値に新し
い開始値が設定される場合があります。データベース・サーバーが生成す
る次の値は、列内の最大値より 1 大きい値になります。
金額値を含む列には、通貨記号を指定しないでください。金額を表す数値
のみを指定してください。
データベース・サーバーは数値と文字のデータ型間でデータを変換できま
す。数値型の列の値には、数字の文字列を指定できます ("-0075.6" など )。
指定した数字は、データベース・サーバーによって数値に変換されます。
指定した文字列が数値を表さない場合にのみ、エラーが発生します。
文字型の列の値には、数値または日付を指定できます。指定した数値また
は日付は、データベース・サーバーによって文字列に変換されます。例え
ば、文字型の列の値として TODAY を指定すると、今日の日付を表す文字列
が使用されます ( 使用される書式は、DBDATE 環境変数で指定されます )。
特定の列名のリスト作成
すべての列の値を指定する必要はありません。その代わりに、表名の後に
列名をリストして、名前を挙げた列の値のみを指定することができます。
次の例では、stock 表に新規の行が挿入されています。
INSERT INTO stock (stock_num, description, unit_price, manu_code)
VALUES (115, "tyre pump", 114, "SHM")
5-8 データの修正
データを修正する文
指定するデータは在庫番号、説明、単価、およびメーカー・コードのデー
タのみであることにご注意ください。残りの列の値は、データベース・
サーバーによって設定されます。
• リストされていないシリアル列には、シリアル番号が生成されます。
• 特定のデフォルトが関連づけられている列には、デフォルト値が生成さ
れます。
• NULL が許可されていてデフォルト値が指定されていない列、または
NULL がデフォルト値として 指定されている列には、NULL 値が生成さ
れます。
つまり、デフォルト値が指定されていない列、または NULL 値が許可され
ていないすべての列に対して、値をリストし、指定する必要があります。
ただし、リスト内の列とそれらの値の順序が同じであれば、列は任意の順
序でリストできます。
INSERT 文の実行後に、次の新規行が stock 表に挿入されます。
stock_num
manu_code
description
unit_price
115
SHM
tyre pump
114
unit
unit_descr
unit および unit_descr が両方とも空白であるため、
この 2 つの列には NULL
値が設定されます。unit 列には NULL 値が許可されているため、購入した
タイヤ・ポンプの金額は $114 であったと推測することのみが可能です。も
ちろん、この列のデフォルト値が “ 箱 ” に指定されている場合は、“ 箱 ” が計
測単位になります。いずれの場合も、表の特定の列に値を挿入する場合は、
この行に意味を持たせるにはどんなデータが必要かについて、特に注意す
る必要があります。
複数の行および式
INSERT 文のその他の主要な書式では、VALUES 節を SELECT 文で置き換え
て使用します。この機能を使用すると、次のデータを挿入できます。
• 1 つの文による複数行の挿入 (SELECT 文によって戻される行ごとに、1
行ずつ挿入する )。
• 計算値の挿入 (VALUES 節は定数のみを許可 ) 。選択リストには式を指定
できます。
データの修正 5-9
データを修正する文
例えば、支払があったにもかかわらず出荷されていないすべての注文に対
して、フォローアップ・コールが必要であるとします。次の INSERT 文はこ
れらの注文を検索して、注文ごとに cust_calls に 1 行ずつ挿入します。
INSERT INTO cust_calls (customer_num, call_descript)
SELECT customer_num, order_num FROM orders
WHERE paid_date IS NOT NULL
AND ship_date IS NULL
この SELECT 文は、2 つの列を戻します。これらの列のデータ ( 選択された
各行 ) は、名前が指定された cust_calls 表の列に挿入されます。次に、注文
番号 ( シリアル型列である order_num のデータ ) が、文字型列であるコー
ル説明に挿入されます。データベース・サーバーによって、文字型列への
整数値の挿入が許可されることにご注意ください。シリアル番号は 10 進数
の文字列に自動的に変換されます。
挿入選択に関する制限
SELECT 文には、4 つの制限があります。
• INTO 節を含むことができない。
• INTO TEMP 節を含むことができない。
• ORDER BY 節を含むことができない。
• 行の挿入先となる表を参照できない。
INTO、INTO TEMP、および ORDER BY 節に関する制限は、マイナーな制限
です。INTO 節はこのコンテキストでは役立ちません ( このマニュアルの第
6 章で説明 ) 。INTO TEMP 節の制限を回避するには、まず一時表に挿入する
データを選択してから、INSERT 文を使用して一時表のデータを挿入しま
す。同様に、ORDER BY 節を省略しても、大きな影響はありません。表内
で新規行を物理的に並べ替える必要がある場合は、まず一時表内で行を選
択し、並べ替えてから一時表の行を挿入します。あるいは、すべての挿入
処理の後に、クラスター・インデックスを使用して、表を物理的に並べ替
えることもできます。
4 番目の制限によって、INSERT 文の INTO 節と SELECT 文の FROM 節の両方
に同じ 表を指定できなくなるため、この制限はより重要です ( この制限に
より、データベース・サーバーはエンドレス・ループを回避し、挿入され
た各行が再選択され再挿入されることがないようにします )。ただし、場合
によっては、この処理を行った方がよいこともあります。例えば、Nikolus
社が Anza 社と同じ製品を半額で提供しているという情報を入手したとしま
す。stock 表に行を追加して、この情報を反映させる必要があります。最善
5-10 データの修正
データを修正する文
の方法は、Anza の在庫に関する行のデータをすべて選択し、Nikolus メー
カー・コードを設定して再挿入することです。ただし、挿入先の表と同じ
表からデータを選択することはできません。
この制限を回避する方法があります。挿入するデータを一次表内で選択し
ます。次に、INSERT 文内で一次表のデータを選択します。この処理を行う
には、次の 3 つの文が必要です。
SELECT stock_num, "NKL" temp_manu, description, unit_price/2
half_price, unit, unit_descr FROM stock
WHERE manu_code = "ANZ"
INTO TEMP anzrows
INSERT INTO stock SELECT * FROM anzrows
DROP TABLE anzrows
この SELECT 文は、stock の既存の行を取り出して、メーカー・コードをリ
テラル値で、単価を計算値で置換します。次に、これらの行を一次表
(anzrows) に保存して、ただちに stock 表に挿入します。
複数行を挿入する場合は、いずれかの行に無効なデータが含まれているこ
とにより、データベース・サーバーがエラーを報告するというリスクがあ
ります。エラーが発生すると、文は早期に終了します。エラーが発生しな
くても、文の実行中にハードウェアまたはソフトウェアに障害が発生する
リスクがわずかにあります ( ディスクがいっぱいになるなど )。
いずれの場合も、挿入された新規行の数は容易に判別できません。文全体
をそのまま繰り返すと、重複行が作成されたり、作成されなかったりしま
す。データベース状態が不明であるため、ユーザーは対処法を判別できま
せん。この問題を解決するには、トランザクションを使用します (5-21 ペー
ジの 『中断された修正』を参照 )。
行の更新
表の 1 つ以上の既存行内で、1 つ以上の列の内容を変更するには、UPDATE
文を使用します。この文は、基本的に異なる 2 つの書式があります。1 つ
は、列に特定の値を割り当てるときに名前を使用し、もう 1 つは、列のリス
トに値リストを割り当てます ( 値リストは SELECT 文によって戻されます )。
いずれの場合も、更新中の行の列の一部にデータ整合性制約が設定されて
いる場合、変更したデータはこれらの列に設定された制約に従う必要があ
ります。詳細については、5-15 ページの 『データベースのアクセス権』の
セクションを参照してください。
データの修正 5-11
データを修正する文
更新する行の選択
UPDATE 文のいずれの書式も、末尾に、変更する行を決定する WHERE 節を
指定できます。この節を省略すると、すべての行が変更されます。変更が
必要な行セットを正確に選択する場合は、WHERE 節が非常に複雑になるこ
とがあります。この節に関する唯一の制限は、更新対象の表を副問合せの
FROM 節内で指定できないことです。
UPDATE 文の最初の書式では、一連の代入節を使用して、新規の列値を指
定します。次に例を示します。
UPDATE customer
SET fname = "Barnaby", lname = "Dorfler"
WHERE customer_num = 103
WHERE 節は、更新する行を選択します。stores5 データベースでは、customer.customer_num 列が表の主キーであるため、この文は最大で 1 行しか更
新できません。
WHERE 節内では副問合せも使用できます。Anza 社が自社製テニス・ボー
ルの安全性に関してリコールを発表するとします。その結果、メーカー
ANZ の在庫番号 6 を含むすべての未出荷注文は、バック・オーダーにする
必要があります。
UPDATE orders
SET backlog = "y"
WHERE ship_date IS NULL
AND order_num IN
(SELECT DISTINCT items.order_num FROM items
WHERE items.stock_num = 6
AND items.manu_code = "ANZ")
この副問合せは、注文番号の列 (0 個以上 ) を戻します。UPDATE 文は
orders の各行をリストと比較して、行が一致する場合は更新します。
5-12 データの修正
データを修正する文
一様値による更新
キーワード SET の後の各割り当ては、列の新しい値を指定します。この値
は、更新されるすべての行に一様に適用されます。この前のセクションの
例では、新しい値は定数でしたが、列値自体に基づく式を含めて、任意の
式を割り当てることができます。メーカー・コード HRO がすべての価格を
5 % 値上げしたため、この変更を反映するように stock 表を更新する必要が
あると仮定します。
UPDATE stock
SET unit_price = unit_price * 1.05
WHERE manu_code = "HRO"
割り当て値の一部として、副問合せを使用することもできます。副問合せ
を要素として使用する式は、1 つの値 (1 つの列および 1 つの行 ) のみを戻
す必要があります。すべての在庫番号に対して、この製品のどのメーカー
よりも高い価格を設定する必要があるとします。すべての未出荷注文の価
格を更新する必要があります。
UPDATE items
SET total_price = quantity *
(SELECT MAX (unit_price) FROM stock
WHERE stock.stock_num = items.stock_num)
WHERE items.order_num IN
(SELECT order_num FROM orders
WHERE ship_date IS NULL)
最初の SELECT 文は、特定の製品に関して stock 表内で最も高い価格を表す
値を 1 つ戻します。この問合せは相関副問合せです。items の値が WHERE
節内で使用されているため、更新される行ごとにこの問合せを実行する必
要があります。
2 番目の SELECT 文は、未出荷注文の注文番号リストを作成します。これは
非相関副問合せであり、1 度実行されます。
不可能な更新
データを変更する場合は、副問合せの使用が制限されます。特に、変更中
の表に対しては問合せを実行できません。unit_price 列の値を 5 % 増加させ
た例のように、式内の列値を参照することができます 。stock 表を更新する
例 (items 表を更新して items.stock_num を結合式内で使用する ) のように、
副問合せの WHERE 節内の列値を参照することができます 。
データの修正 5-13
データを修正する文
設計が優れたデータベースでは、通常は表に更新と問合せを同時に行う必
要はありません ( データベース設計については、このマニュアルの第 8 ~
11 章を参照 )。ただし、データベースを最初に開発する場合は、設計の詳
細を検討する前に、この機能を盛り込むことができます。通常、問題が発
生するのは、表内の一部の行において、一意であるはずの列に不注意によ
り誤って重複値が設定されている場合です。重複行を削除したり、重複行
のみを更新することはできます。いずれの方法でも、重複行をテストする
場合は、UPDATE 文または DELETE 文で許可されていない副問合せが必要に
なります。第 7 章では、UPDATE カーソル を使用してこの種類の修正を実
行する方法について説明します。
選択値による更新
UPDATE 文の 2 番目の書式は、割当てリストの代わりに、列リストが値リ
ストと等しくなるように設定されている単一のバルク割当てを使用します。
値が単純な定数の場合、この書式は、次の例のように、この前の例の各要
素を並べ替えたものにしかすぎません。
UPDATE customer
SET (fname, lname) = ("Barnaby", "Dorfler")
WHERE customer_num = 103
このような文を作成する利点はありません。実際、値と列の割当て関係が
明確でないため、読みにくくなっています。
ただし、割り当てる値が単一の SELECT 文である場合、この書式は有用で
す。複数のカスタマーの住所を変更するとします。変更が報告されるたび
に、customer 表を更新する代わりに、新住所を newaddr という名前の 1 つ
の一時表に集めます。この一時表には、カスタマー番号を表す列、および
customer 表内の住所に関係するフィールドが含まれます。これによって、
すべての新住所を一度に適用することができます。( ルーチン的な変更内容
を別の表に集めて、それらを忙しくない時間帯に一括適用するという考え
方は、パフォーマンスを上げるための技術の 1 つです。このマニュアルの
第 10 章を参照してください。)
UPDATE customer
SET (address1, address2, city, state, zipcode) =
(SELECT address1, address2, city, state, zipcode
FROM newaddr
WHERE newaddr.customer_num = customer.customer_num)
WHERE customer_num IN
(SELECT customer_num FROM newaddr)
5-14 データの修正
データベースのアクセス権
1 つの SELECT 文によって、複数の列値が生成される点に注意してくださ
い。この例を、更新する列ごとに割り当てを行う別の書式で記述し直す場
合は、更新する列ごとに 5 つの SELECT 文を記述する必要があります。この
ような文は、記述するのに手間がかかるだけでなく、実行にも時間がかか
ります。
注: IBM Informix 4GL および埋込み SQL プログラムでは、レコードまたはホ
スト変数を使用して値を更新できます。詳細については、このマニュアル
の第 6 章を参照してください。
データベースのアクセス権
データベースのアクセス権には、データベース・レベル・アクセス権と表
レベル・アクセス権の 2 つのレベルがあります。データベースを作成する
場合は、データベースの所有者 ( または DBA) がデータベース・レベル・ア
クセス権を付与しない限り、他のユーザーはデータベースにアクセスでき
ません。ANSI に準拠しないデータベース内に表を作成する場合は、表の所
有者が特定のユーザーに対して表レベル・アクセス権を取り消さない限り、
すべてのユーザーに表へのアクセス権が設定されます。
次に、3 つのデータベース・レベル・アクセス権を示します。
• Connect アクセス権。データベースのオープン、問合せの発行、および
一時表のインデックスの作成や適用を行うことができます。
• Resource アクセス権。永続表を作成できます。
• DBA アクセス権。データベース管理者として多数の追加機能を実行で
きます。
次に、7 つの表レベル・アクセス権を示します。ただし、ここで説明する
のは最初の 4 つのみです。
• SELECT アクセス権。表単位で付与され、表の行を選択できます
( このアクセス権の対象は、表内の特定の列に限定できます )。
• Delete アクセス権。行を削除できます。
• Insert アクセス権。行を挿入できます。
• Update アクセス権。既存の行を更新できます
( つまり内容を変更できます )。
データベースおよび表を作成するユーザーは、通常、Connect および
SELECT アクセス権をパブリック に付与して、すべてのユーザーにこれら
のアクセス権を設定します。表に問合せを実行できる場合は、少なくとも
目的のデータベースおよび表に関する Connect および SELECT アクセス権
が付与されています。
データの修正 5-15
データベースのアクセス権
他の表レベル・アクセス権は、データを変更する場合に必要です。通常は、
表の所有者がこれらのアクセス権を保持するか、または特定のユーザーに
限定して付与します。その結果、表に対して問合せを自由に実行できるに
もかかわらず、変更できない場合があります。
これらのアクセス権は表単位で付与されるため、特定の表に関しては Insert
アクセス権のみを持ち、別の表に関しては Update アクセス権のみを持つこ
とがあります。Update アクセス権は、表内 の特定の列を対象とするように
さらに制限することができます。
このマニュアルの第 11 章では、データベース設計者の観点から、アクセス
権の付与について詳細に説明します。アクセス権の完全なリスト、および
GRANT や REVOKE 文のサマリーについては、IBM Informix SQL リファレンス・
ガイド の第 7 章を参照してください。
表アクセス権の表示
表の所有者 ( 作成者 ) には、その表に対するすべてのアクセス権がありま
す。所有者以外のユーザーは、システム・カタログに問い合わせて、特定
の表に対して自分が付与されているアクセス権を確認することができます。
システム・カタログは、データベース構造を記述するシステム表からなり
ます。各表に付与されたアクセス権は、systabauth システム表に記録され
ます。これらのアクセス権を表示するには、この表の一意の ID 番号を取得
する必要もあります。この番号は、systables システム表内で指定されてい
ます。したがって、orders 表に付与されているアクセス権を表示するには、
次の SELECT 文を入力します。
SELECT * FROM systabauth
WHERE tabid = (SELECT tabid FROM systables
WHERE tabname = "orders")
この問合せの出力は、次のようになります。
grantor
grantee
tabid
tabauth
tfecit
tfecit
tfecit
mutator
procrustes
public
101
101
101
su-i-xs--idxs--i-x-
grantor ( 権限授与者 ) はアクセス権を付与した ユーザーです。通常、権限
授与者は表の所有者ですが、権限授与者から権限を与えられた他のユー
ザーが権限授与者になることもあります。grantee ( 被権限授与者 ) はアクセ
5-16 データの修正
データ整合性
ス権を付与されたユーザーであり、被権限授与者 public は “Connect アクセ
ス権を持つすべてのユーザー ” を意味します。ユーザー名が表示されない
ユーザーには、パブリックに付与されたアクセス権しかありません。
tabauth 列は、付与されたアクセス権を示します。この列の各行の文字はア
クセス権の名前の頭文字を表しますが、例外的に i は挿入 (Insert) を意味し、
x はインデックス (Index) を意味します。この例では、public には Select、
Insert、および Index アクセス権が付与されています。Update アクセス権を
持つのはユーザー mutator のみで、Delete アクセス権を持つのは ユーザー
procrustes のみです。
データベース・サーバーは、ユーザーのアクション (DELETE 文など ) を実
行する前に、この前の問合せと同様な問合せを実行します。表の所有者以
外が問合せを行った場合、その表に対して必要なアクセス権がそのユー
ザー名またはパブリックに設定されていないと、データベース・サーバー
は処理の実行を拒否します。
データ整合性
INSERT、UPDATE、および DELETE 文は、既存データベース内のデータを修
正します。既存データを修正すると、データの整合性 が影響を受けます。
例えば、存在しない製品に関する注文が orders 表に入力されることがあり
ます。未解決の注文を発注したカスタマーが customer 表から削除されるこ
ともあります。また、orders 表の注文番号が更新され、items 表の注文番号
が更新されない こともあります。いずれの場合も、保管データの整合性が
失われます。
データ整合性は、実際には 3 つの部分で構成されます。
• 実体整合性
表の各行には一意の ID があります。
• 意味整合性
列のデータには、設計時に列に保持するように指定された情報タイプが
正しく反映されます 。
• 参照整合性
表と表の関係を適用します。
優れた設計のデータベースにはこれらの原則が組み込まれているため、
データを修正する場合、データ整合性を損ねる操作はデータベース自体に
よって禁止されます。
データの修正 5-17
データ整合性
実体整合性
エンティティー ( 実体 ) はデータベースに記録されたすべての人物、場所、
またはその他の情報です。各エンティティーは表を表し、表の各行はエン
ティティーのインスタンスを表します。例えば、注文 はエンティティーで
あり、orders 表は注文の概念を、表内の各行 は特定の注文を表します。
表の各行を識別するには、表に主キーを設定する必要があります。主キー
は、各行を識別する一意の値です。この要件は、実体整合性制約 と呼ばれ
ます。
例えば、orders 表の主キーは order_num です。order_num 列は、表内の行
ごとに、システムによって生成された一意の注文番号を保持します。
orders 表のデータ行にアクセスする場合は、次の SELECT 文を使用できま
す。
SELECT * FROM orders WHERE order_num = 1001
各行は注文番号によって一意に識別されるため、この文の WHERE 節で注
文番号を使用すると、特定の行に簡単にアクセスできます。この表の他の
すべての列に重複値が許可されているため、重複する注文番号が許可され
ている場合は、特定の単一行にアクセスすることはほとんど不可能です。
主キーおよび実体整合性の詳細については、このマニュアルの第 8 章を参
照してください。
意味整合性
意味整合性により、特定の行に入力されたデータには、その行で許容され
ている値が反映されます。つまり、その列には定義域 内の値、または一連
の許容値を入力する必要があります。例えば、items 表の quantity 列では、
数値のみが許可されます。定義域外の値を列に入力すると、データの意味
整合性に違反します。
意味整合性は、次の制約によって実行されます。
• データ型
データ型は、列に格納できる値のタイプを定義します。例えば、データ
型が SMALLINT の場合は、-32,767 ~ 32,767 の値を列に入力できます。
• デフォルト値
デフォルト値は、値が明示的に指定されていない場合に、列に挿入され
る値です。例えば、cust_calls 表の user_id 列に名前を入力しない場合、
デフォルト値はユーザーのログイン名です。
5-18 データの修正
データ整合性
• チェック制約
チェック制約は、列に挿入されるデータの条件を指定します。表に挿入
された各行は、これらの条件を満たす必要があります。例えば、items
表の quantity 列は、数量が 1 以上であるかどうかをチェックできます。
データベース設計時の意味整合性制約の使用法については、9-3 ページ
の 『ドメインの定義』を参照してください。
参照整合性
参照整合性は、表間 の関係を表します。データベースの各表には必ず主
キーが設定されているため、これらの表内のデータに関係がある場合は、
他の表にこの主キーが表示されることがあります。ある表の主キーが別の
表に表示されている場合、この主キーは外部キーと呼ばれます。
外部キーは、複数の表を結合 し、表間の依存関係を確立します。表の依存
関係を階層的に作成して、ある表の行を変更または削除した場合、他の表
の行の意味が破壊されることがあります。例えば、stores5 データベースで
は、customer 表の customer_num 列は主キーであり、かつ orders および
cust_call 表の外部キーです。カスタマー番号 106 の George Watson は、
orders および cust_calls の両方の表で参照 されます。カスタマー 106 を
customer 表から削除すると、3 つの表とこの特定のカスタマーとのリンク
が失われます。
データの修正 5-19
データ整合性
customer Table
(detail)
customer_num
fname
lname
103
Philip
Currie
106
George
Watson
orders Table
(detail)
order_num
order_date
customer_num
1002
05/21/1991
101
1003
05/22/1991
104
1004
05/22/1991
106
cust_calls Table
(detail)
customer_num
call_dtime
user_id
106
1991-06-12 8:20
maryj
110
1991-07-07 10:24
richc
119
1991-07-01 15:00
richc
主キーを含む行を削除するか、または別の主キーに更新すると、この値を
外部キーとして含むすべての行の意味が失われます。参照制約は、主キー
に関する外部キーの論理的な依存関係を示します。外部キーを含む行の整
合性 は、参照先 の行 ( 一致する主キーを含む行 ) の整合性に依存します。
主キーおよび外部キー、およびそれらの関係を識別するには、CREATE
TABLE および ALTERTABLE 文を使用します。これらの文の詳細について
は、IBM Informix SQL リファレンス・ガイド の第 7 章を参照してください。外
部キーおよび主キーによるデータ・モデルの構築方法については、このマ
ニュアルの第 8 章を参照してください。
5-20 データの修正
中断された修正
中断された修正
すべてのソフトウェアがエラー・フリーで、かつすべてのハードウェアが
完全に信頼できるものであっても、コンピューター外部からさまざまな干
渉を受けることがあります。建物に落雷して停電が発生し、UPDATE 文の
途中でコンピューターが停止することがあります。より可能性があるのは、
ディスクがいっぱいになるか、またはオペレーターが不正なデータを入力
したことにより、複数行の挿入作業中にエラーが発生して停止してしまう
ことです。いずれの場合も、データを変更するときは、不測のイベントに
よって修正が中断されることを想定する必要があります。
外部要因によって修正が中断された場合、ユーザーは処理がどこまで完了
したかを把握することができません。単一行に関する操作の場合でも、
データがディスクに到達したのか、またはインデックスが適切に更新され
たのかどうかを確認することはできません。
複数行の修正に問題がある場合には、複数の文の変更にはより多くの問題
があります。通常は文がプログラムに埋め込まれており、実行中の各 SQL
文を確認できないので、役立ちません。例えば、stores5 データベースに新
規注文を入力する作業では、次のステップを行う必要があります。
• orders 表に行を挿入する ( これにより行番号が生成されます )。
• 注文された品目ごとに、items 表に 1 行挿入する。
注文入力アプリケーションをプログラムする方法は、2 つあります。まず 1
つは、処理開始直後にまず行を挿入し、その後、オペレーターがデータを
入力するときに各品目を挿入できるように、プログラムを完全な対話型に
する方法です。ただし、この方法では、カスタマーからの電話の切断、オ
ペレーターの誤入力、オペレーターによる端末電源の切断などの不測のイ
ベントが処理中に多数発生する可能性があるため、適切ではありません。
注文入力アプリケーションを構築する正しい方法は、次のとおりです。
• すべてのデータを対話式に受け入れる。
• データを検証し、展開する ( そのために、例えば、stock および
manufact のコードを参照する )。
• 検査用の情報を画面に表示する。
• オペレーターが最終コミットメントを行うまで待機する。
• すべての追加作業をできるだけ短時間で実行する。
この条件を満たしていても、何らかの不測の事態によって、注文を挿入し
てから品目を挿入するまでの間にプログラムが停止することがあります。
このような場合には、データベースは予測不能な状態になり、データ整合
性 が損なわれます。
データの修正 5-21
中断された修正
トランザクション
このような潜在的なすべての問題に対する解決方法は、トランザクション
と呼ばれます。トランザクションは、完全に実行されるか、またはまった
く実行されない、一連の修正操作です。データベース・サーバーは、トラ
ンザクション境界内で実行された処理を完全かつ正確にディスクにコミッ
トしたり、またはデータベースをトランザクション開始前の状態に復元す
ることのいずれかを確実に実行します。
トランザクションは単に不測の障害から保護するだけではなく、プログラ
ムが論理エラーを検出した場合に回避する方法も提供します ( この機能に
ついては、このマニュアルの第 7 章を参照してください )。
トランザクション・ログ
データベース・サーバーは、トランザクション中にデータベースに行われ
た各変更のジャーナルを保持できます。トランザクションをキャンセルす
る何らかの事態が発生すると、データベース・サーバーはジャーナル内の
データを自動的に使用して、変更を元に戻します。
このジャーナルはトランザクション・ログ と呼ばれます。このログは、通
常はデータベースと別のディスク・ファイルです。トランザクションを最
新に保つ操作は、トランザクション・ログ機能 と呼ばれます。
トランザクションに失敗すると、データベース・サーバーはログの内容を
使用して、トランザクション開始時に行われたすべての修正を元に戻しま
す。トランザクションは、さまざまな原因により失敗することがあります。
SQL 文を発行するプログラムがクラッシュしたり停止し、システムの他の
コンポーネントにハードウェア障害またはソフトウェア障害が発生するこ
とがあります。データベース・サーバーは、トランザクションの失敗を検
出するとすぐに ( コンピューターおよびデータベース・サーバーの再起動
後のみ )、データベースをトランザクション開始前の状態に戻します。
データベースはトランザクション・ログを自動的に保持しません。データ
ベース管理者は、データベース内でトランザクション・ログ機能を使用す
るかどうかを決定する必要があります。この決定を行わないと、トランザ
クションは使用できません。
5-22 データの修正
中断された修正
トランザクションの指定
トランザクションの境界は、SQL 文で指定します。この指定方法には 2 つ
のスタイルがあります。一般的なスタイルでは、BEGIN WORK 文を実行し
て、複数の文からなるトランザクションの開始を指定します。MODE ANSI
オプションを使用して作成されたデータベースでは、トランザクションの
開始をマークする必要はありません。トランザクションは常に有効であり、
ユーザーは各トランザクションの終了を指示するだけです。
両方のスタイルでトランザクションの正常終了を指定するには、COMMIT
WORK 文を実行します。この文は、データベース・サーバーに、すべて正
常実行する必要がある一連の文の末尾に到達したことを伝えます。データ
ベース・サーバーは、すべての修正を適切に完了してディスクにコミット
するために必要な処理をすべて実行します。
プログラムはトランザクションを故意にキャンセルすることもできます。
そのためには、ROLLBACK WORK 文を使用します。この文は、データベー
ス・サーバーに、現在のトランザクションをキャンセルして変更を元に戻
すように要求します。
例えば、新規注文を作成する場合、注文入力アプリケーションは次のよう
にトランザクションを使用できます。
•
•
•
•
•
すべてのデータを対話式に受け入れる。
データを検証し、展開する。
オペレーターが最終コミットメントを行うまで待機する。
BEGIN WORK を実行する。
orders および items 表に行を挿入して、データベース・サーバーから戻
されるエラー・コードをチェックする。
• エラーがない場合は、COMMITWORK を実行し、エラーがある場合は、
ROLLBACKWORK を実行する。
外部の障害によりトランザクションを完了できない場合は、システムの再
起動時に部分的なトランザクションがロールバックされます。すべての場
合において、データベースは予測可能な状態であり、新規注文が完全に入
力されるか、またはまったく入力ません。
データの修正 5-23
アーカイブおよびログ
アーカイブおよびログ
トランザクションを使用することにより、データベースを常に一貫した状
態に保ち、修正をディスクに適切に記録することができます。ただし、
ディスク自体が完全に安全性を保つことができるわけではありません。機
械的な障害、および洪水、火災、地震などを避けることはできません。安
全性を保つには、データのコピーを複数保持する必要があります。これら
の冗長コピーは、アーカイブ ・コピーといいます。
トランザクション・ログは、データベースのアーカイブ・ログを補足する
ものです。トランザクション・ログの内容は、データベースが最後にアー
カイブされた後に発生したすべての修正履歴です。データベースをアーカ
イブ・コピーから復元する必要がある場合は、トランザクション・ログを
使用して、データベースを最新状態にロール・フォワードできます。
単純なデータベースのアーカイブ (IBM Informix SE)
データベースがオペレーティング・システム・ファイルに格納されている
場合 (IBM Informix SE)、アーカイブ・コピーはオペレーティング・システム
内でバックアップ・コピーを作成する通常の方法を使用して作成されます。
データベースに関する考慮事項は 2 つのみです。
1 番目の考慮事項は、データベースのサイズは大きくなることがあるとい
う実際的なものです。データベースはシステム内で巨大ファイルになった
り、複数のファイルになる場合があります。また、このファイルのコピー
を作成する作業は面倒であったり、時間がかかることがあります。データ
ベースをコピーするには、通常のバックアップ手順と異なる特殊な手順が
必要になることがあり、この作業は頻繁には実行されないことがあります。
2 番目の考慮事項は、データベースとトランザクション・ログ・ファイル
の特殊な関係に関するものです。アーカイブ・コピーは、特定の時点にお
けるデータベースのイメージです。ログ・ファイルには、特定の時点以降
に行われた修正履歴が格納されます。これらの 2 つの時点は同じであるこ
とに注意してください。つまり、データベースのアーカイブ・コピーの作
成直後に、新規のトランザクション・ログ・ファイルが開始されます。
アーカイブ・テープからデータベースを復元する必要がある場合は、トラ
ンザクション・ログに格納されている正確な履歴を使用して、データベー
スをその時点から最新の更新まで、時間的に新しい状態に移行することが
できます。
復元されたデータベースにログを適用する文は、ROLLFORWARD DATABASE です。新規ログ・ファイルを開始するには、ファイルを削除して空の
ファイルを再作成するか、またはファイルの長さを単にゼロに設定するた
めに必要なすべてのオペレーティング・システム・コマンドを使用します。
5-24 データの修正
アーカイブおよびログ
トランザクション・ログはサイズが非常に大きくなることがあります。あ
る行を 10 回更新した場合、データベースに存在するのは 1 行のみですが、
ログ・ファイルには 10 個の更新イベントが記録されます。ログ・ファイル
のサイズが問題になる場合は、フレッシュ・ログを開始できます。データ
ベースが更新されていない ( トランザクションがアクティブでない ) 時間を
選択し、既存のログを別のメディアにコピーします。このコピーは、特定
の期間におけるすべての修正を表します。注意して保管してください。次
に、新規ログ・ファイルを開始します。データベースを復元する必要があ
る場合は、すべてのログ・ファイルを正しい順序で適用する必要がありま
す。
IBM Informix OnLine のアーカイブ
IBM Informix OnLine データベース・サーバーには、アーカイブおよびロギ
ングをサポートするための精巧な機能があります。これらの機能について
は、IBM Informix OnLine 管理者ガイド を参照してください。
概念的には、IBM Informix OnLine の機能はここですでに説明した機能と似
ていますが、次の理由からより精巧です。
•
IBM Informix OnLine には、パフォーマンスおよび信頼性を高めるために
非常に厳格な要件がある ( データベースの使用中におけるアーカイブ・
コピーの作成のサポートなど )。
• 独自のディスク領域を管理する。
• 少数のログ・デバイス・セットを使用して、すべてのデータベースにロ
ギングを並行実行する。
これらの機能は、通常は中央管理されるため、データベースのユーザーは
これらを意識する必要はありません。
IBM Informix OnLine によって保持される単一データベースまたは表の個人
的なアーカイブ・コピーを作成する場合は、tbunload ユーティリティーを
使用できます。このプログラムは、表またはデータベースをテープにコ
ピーします。出力は、IBM Informix OnLine が保持していたディスク・ペー
ジのバイナリー・イメージから成ります。その結果、コピーを短時間で作
成でき、対応する tbload プログラムはファイルを短時間で復元できます。
ただし、データ・フォーマットは他のどのプログラムでも使用できません。
データの修正 5-25
同時実行性およびロック
同時実行性およびロック
ご使用のデータベースがシングルユーザー・ワークステーションに格納さ
れており、そのワークステーションと他のマシンがネットワーク接続され
ていない場合、ユーザーは同時実行性を考慮する必要はありません。ただ
し、その他のすべての場合では、使用中のプログラムがデータを修正して
いる間に、別のプログラムが同じデータを読み込んだり、修正する可能性
を考慮する必要があります。これは同時実行性 と呼ばれ、同じデータを複
数の独立したプログラムで同時に使用できます。
高度な同時実行性は、マルチユーザー・データベース・システムのパ
フォーマンスを高めるために重要です。ただし、データの使用を制御しな
い場合には、同時実行性によってさまざまな悪影響が発生することがあり
ます。プログラムが古いデータを読み込んだり、正常に入力されたと思わ
れる修正データが失われることがあります。
データベース・サーバーはこれらの種類のエラーを防ぐために、ロック ・
システムを導入しています。ロックは、プログラムが一部のデータに設定
できるクレームまたは予約のことです。データベース・サーバーは、ロッ
クされているデータが他のプログラムによって変更されないことを保証し
ます。別のプログラムがデータを要求すると、データベース・サーバーは
プログラムを待機させるか、またはエラーと共に要求を戻します。
データ・アクセスに対するロックの効果を制御するには、SET LOCK MODE
および SET ISOLATION の 2 つのコマンドを使用します。これらの文の詳細を
理解するには、まず、プログラム内でのカーソル の使用法に関する説明を
参照してください ( このマニュアルの第 6 章および第 7 章を参照 )。
サマリー
データベース・アクセスは、データベース所有者から付与されるアクセス
権によって規制されます。通常、データの問合せを許可するアクセス権は
自動的に付与されますが、データの修正は、表単位で付与される特定の
Insert、Delete、および Update アクセス権によって規制されます。
データ整合性制約がデータベースに設定されている場合は、これらの制約
によってデータの修正が制限されます。データの修正方法および修正でき
る時期は、データベース・レベルおよび表レベルのアクセス権、および
データ制約によって制御されます。
表から行を 1 つまたは複数削除するには、DELETE 文を使用します。この
文内の WHERE 節は行を選択します。削除内容を確認するには、同じ節を指
定した SELECT 文を使用します。
5-26 データの修正
サマリー
行を表に追加するには、INSERT 文を使用します。特定の列値を含む単一行
を挿入したり、SELECT 文によって生成された行ブロックを挿入することが
できます。
UPDATE 文を使用して、既存の行の内容を修正することができます。副問
合せを含むことができる式を使用して新規の内容を指定すると、他の表に
基づくデータを使用したり、表自体を更新することができます。この文に
は 2 つの書式があり、列単位で新規の値を指定したり、新規の値を SELECT
文のセットまたはレコード変数として生成することができます。
修正中の不測の割り込みによってデータベースが不確定な状態にならない
ようにするには、トランザクションを使用します。トランザクション内で
修正を実行すると、エラーが発生した場合にロールバックします。トラン
ザクション・ログを使用すると、定期的に作成されるデータベースのアー
カイブ・コピーを拡張することもでき、データベースを復元する必要があ
る場合に、最新状態に正しく戻すことができます。
データの修正 5-27
サマリー
5-28 データの修正
プログラム内の SQL
概要 3
プログラム内の SQL 4
静的埋込み 5
動的文 5
プログラム変数とホスト変数 5
データベース・サーバーの呼び出し 7
SQL 通信領域 8
SQLCODE フィールド 11
データの終わり 11
負数コード 11
SQLERRD 配列 12
SQLAWARN 配列 12
単一行の抽出 13
データ型の変換 14
NULL データの処理 15
エラーの処理 16
データの終わり 17
重大なエラー 18
デフォルト値の使用 18
複数行の抽出 19
カーソルの宣言 20
カーソルの開始 20
行の取り出し 21
データの終わりの検出 22
INTO 節の位置決め 22
カーソル入力モード 23
第
6
章
カーソルのアクティブ・セット 24
アクティブ・セットの作成 24
順カーソルのアクティブ・セット 25
スクロール・カーソルのアクティブ・セット 25
アクティブ セットと同時実行性 25
カーソルの使用 : 部品展開 26
動的 SQL 29
PREPARE 文での処理 29
PREPARE 文で処理された SQL の実行 32
PREPARE 文で処理された SELECT 文の使用 32
動的ホスト変数 34
PREPARE 文で処理された文の解放 34
高速実行 35
埋込みデータ定義 35
GRANT 文と REVOKE 文のアクセス権の埋込み 35
サマリー 38
6-2 プログラム内の SQL
概要
これまでの章における例では、SQL は、対話型コンピューター言語である
かのように、つまり、SELECT 文を直接データベース・サーバーに入力し、
データの行をユーザーに戻すことができるかのように扱われています。
もちろん、このように機能するわけではありません。ソフトウェアの多く
の階層が、ユーザーとデータベース・サーバーとの間に位置します。デー
タベース・サーバーは、バイナリー形式でデータを保存します。このデー
タを表示するにはフォーマットを行う必要があります。データベース・
サーバーは、大量のデータを一度には戻しません。あるプログラムが要求
すると、一度に 1 行を戻します。
DB-Access と IBM Informix SQL は、この要求を実行してデータをフォーマッ
トおよび表示するための 2 つのプログラムです。これらは、ユーザーが
SQL への対話型アクセスを使用できるように設計されています。その他の
プログラムは、特定のアプリケーション用に作成されています。このよう
なプログラムは、いくつかの言語のうちの任意の言語で作成することがで
きます。
ほとんどすべてのプログラムに、SQL 文を含めて、それらを実行し、データ
ベース・サーバーからデータを抽出することができます。この章では、こ
れらの動作の実行方法、およびこれらの動作を実行するプログラムの作成
方法について説明します。
この章では、任意の言語で書かれた SQL プログラミングに共通の概念の序
文のみについて説明します。特定のプログラム言語で正常なプログラムを
作成するには、あらかじめその言語に精通しておく必要があります。また、
処理の詳細は言語ごとにわずかに異なるため、その言語固有の
IBM Informix 埋込み SQL (ESQL) 製品の説明書を熟読しておく必要もありま
す。
プログラム内の SQL 6-3
プログラム内の SQL
プログラム内の SQL
プログラムはいくつかの言語のうちのどの言語でも作成することができ、
SQL 文をそのプログラミング言語の通常の文であるかのように、プログラ
ムの他の文の間に混合させることができます。SQL 文は、プログラムに埋め
込まれて いると言われ、そのプログラムには 埋込み SQL、しばしば省略し
て ESQL が含まれていると言われます。
IBM では、以下のプログラム言語用の IBM Informix ESQL 製品を提供してい
ます。
•
•
C
COBOL
すべての ESQL 製品は、図 6-1 に示されているように機能します。SQL 文を
実行可能コードとして取り扱うソース・プログラムを作成します。ソー
ス・プログラムは、ESQL プリプロセッサー、つまり組込み SQL 文を格納す
るプログラムによって処理され、それらの文を一連のプロシージャー呼出
しと特定のデータ構造に変換します。 ESQL ソース
プログラム
図 6-1
ESQL
プリプロセッサー
ソース・プログラム
プロシージャー
呼出し使用
言語
コンパイラー
実行可能ファイル
プログラム
埋込み SQL 文を使用したプログラム処理の概要
変換されたソース・プログラムは、その後、プログラム言語コンパイラーを
通過します。コンパイラー出力は、ESQL プロシージャーのライブラリーとリ
ンクした後に、実行可能プログラムになります。プログラムが実行されると、
ESQL ライブラリー・プロシージャーが呼び出されます。これらは、データ
ベース・サーバーとの通信をセットアップして、SQL 操作を実行します。
ESQL 製品によって SQL をホスト言語に埋め込むことができるのに対して、
SQL を文のセットの自然な部分として持つ言語もあります。4GL は、SQL 言
語を、サポートする第 4 世代言語の自然な部分として組み込みます。Informix ストアード・プロシージャー言語 (SPL) の場合も、SQL がその文のセッ
トの自然な部分として使用されます。アプリケーション・プログラムを作
成するには、4GL または ESQL 製品を使用します。データベースと共に格納
され、アプリケーション・プログラムから呼び出されるプロシージャーを
作成するには、SPL を使用します。
6-4 プログラム内の SQL
プログラム内の SQL
静的埋込み
SQL 文をプログラムに導入するには、2 つの方法があります。より簡単でよ
り一般的な方法は、静的埋込み によるものです。静的埋込みとは、SQL 文
がソース・プログラムのテキストの一部として書き込まれることを意味し
ます。これらの文は、ソース・テキストの固定部分であるため、静的 にな
ります。
動的文
アプリケーションのなかには、ユーザー入力に応答して SQL 文を構成でき
る機能を必要とするものがあります。例えば、ユーザーが必要とするもの
によって、プログラムは異なる列を選択したり、異なる基準を行に適用し
たりしなければなりません。
これは、動的 SQL を使用して実行できます。動的 SQL では、プログラムは
SQL 文をメモリー内に文字の列として構成し、それをデータベース・サー
バーに受け渡して実行します。動的文は、ソース・テキストの一部ではな
く、実行中にメモリー内に構築されます。
プログラム変数とホスト変数
アプリケーション・プログラムは、プログラム変数を SQL 文の内部で使用
できます。
IBM Informix 4GL と SPL において、プログラム変数を構文が許可するとおり
に SQL 文に書き込みます。例えば、DELETE 文は、プログラム変数を WHERE
節で使用することができます。図 6-2 に、IBM Informix 4GL でのプログラム
変数を示します。
MAIN
.
.
.
DEFINE drop_number INT
LET drop_number = 108
DELETE FROM items WHERE order_num = drop_number
.
.
.
図 6-2
IBM Informix 4GL でのプログラム変数の使用
プログラム内の SQL 6-5
プログラム内の SQL
図 6-3 に、SPL でのプログラム変数を示します。
CREATE PROCEDURE delete_item (drop_number INT)
.
.
.
DELETE FROM items WHERE order_num = drop_number
.
.
.
図 6-3
SPL でのプログラム変数の使用
埋込み SQL 文を使用するアプリケーションにおいて、SQL 文がプログラム
変数の内容を参照する可能性があります。埋込み SQL 文で名前が付けられ
たプログラム変数は、その SQL 文がプログラム内で “ ゲスト ” として考えら
れるために、ホスト変数 と呼ばれます。
次は、COBOL ソース・プログラムに埋め込まれる場合に表示されることが
ある DELETE 文です。
EXEC SQL
DELETE FROM items
WHERE order_num = :o-num
END-EXEC.
最初と最後の行は、通常の COBOL 文から埋込み SQL 文を区別します。それ
らに挟まれる文は、通常の DELETE 文で、これは第 5 章で説明しました。
COBOL プログラムのこの部分が実行されると、items 表の 1 つまたは複数の
行が削除されます。
文には、新機能が 1 つ含まれます。これは、order_num 列を、:o-num とし
て書き込まれた項目と比較します。:o-num は、ホスト変数の名前です。
それぞれの ESQL 製品には、ホスト変数が SQL 文のコンテキストに表示さ
れるときに、そのホスト変数の名前を範囲設定する方法があります。
COBOL では、ホスト変数名は、先頭にコロンを付けて指定されます。例の
文では、データベース・サーバーに、オーダー番号がホスト変数 :o-num の
現行内容と等しい行を削除するよう要求します。これは、おそらく、プロ
グラムで初期に宣言されて値を割り当てた数値変数です。
IBM Informix ESQL/C では、SQL 文を、先頭に通貨記号または単語 EXEC SQL
のいずれかを使用して導入できます。
6-6 プログラム内の SQL
データベース・サーバーの呼出し
ただし、これらの構文にはほとんど差はありません。すべての言語 ( 埋め
込み言語、IBM Informix 4GL または SPL) における不可欠なポイントは、次
のとおりです。
•
SQL 文は、ホスト言語の実行可能文であるかのようにソース・プログラ
ムに埋め込むことができます。
•
SQL 表現式のプログラム変数を定数値が使用されるように使用できま
す。
プログラミング経験があれば、すぐにその可能性が分かります。例では、
削除されるオーダー番号は、変数 onum 内に渡されます。その値は、プロ
グラムが使用できる任意のソースからの値です。この値をファイルから読
み取ったり、プログラムがユーザーにその値を入力するように促すプロン
プトを出したり、その値をデータベースから読み取ったりすることができ
ます。DELETE 文自体は、サブルーチンの一部になることができ (onum がサ
ブルーチンのパラメーターになることができる場合 )、そのサブルーチンは
1 回または繰り返し呼び出すことができます。
つまり、SQL 文をプログラムに埋め込む場合、ホスト言語のすべての機能
をそれらの文に適用できます。SQL を多数のインターフェースの下に隠し
て、さまざまな方法でその機能を装飾することもできます。
データベース・サーバーの呼出し
SQL 文を実行すると、データベース・サーバーがサブルーチンとして必ず
呼び出されます。情報は、プログラムからデータベース・サーバーに渡さ
れて、その後戻される必要があります。
この通信のいくつかは、ホスト変数を使用して実行されます。SQL 文で名前
が付けられたホスト変数を、データベース・サーバーへのプロシージャー
呼出しのパラメーターとみなすことができます。上述の例では、ホスト変
数は、WHERE 節のパラメーターとして機能します。また、後のセクション
で示すように、ホスト変数はデータベース・サーバーによって戻される
データを受け取ります。
プログラム内の SQL 6-7
データベース・サーバーの呼出し
SQL 通信領域
データベース・サーバーは、SQL 通信領域 (SQLCA) と呼ばれるデータ構造
体に常に結果コードを戻します。また、操作の結果についての他の情報を
戻す場合もあります。データベース・サーバーが、ストアード・プロシー
ジャーで SQL 文を実行する場合、呼出しアプリケーションの SQLCA には、
そのプロシージャーで SQL 文によってトリガーされた値が含まれます。
SQLCA の基本フィールドは、図 6-4 と図 6-5 にリストされています。
SQLCA など、データ構造を説明するために使用する構文は、そのなかの
フィールドを参照するために使用する構文と同様、使用しているプログラ
ミング言語によって異なります。
6-8 プログラム内の SQL
データベース・サーバーの呼出し
整数
SQLCODE
0
100
負数
6 整数の
配列
正常終了。
これ以上のデータなし / 未検出。
エラー・コード。
SQLERRD
1 番目
SELECT、UPDATE、INSERT、または DELETE の文の準備が正常終了した後、または
選択カーソルがオープンされた後、このフィールドに影響を受けた行数の見積りが含
まれます。
2 番目
SQLCODE にエラー・コードが含まれる場合、このフィールドには、ゼロまたは追加の
エラー・コード (ISAM エラー・コード ) のいずれかが含まれ、メイン・エラーの原因
が説明されます。
単一行の挿入操作が正常終了したら、このフィールドにその行の生成されたシリアル
番号の値が含まれます。
複数行挿入、更新、または削除操作が正常終了したら、このフィールドに処理された
行数が含まれます。
エラーで終了した複数行挿入、更新、または削除操作の後は、このフィールドにエ
ラーが検出される前に正常に処理された行数が含まれます。
SELECT、UPDATE、INSERT、または DELETE の文の準備が正常終了した後、または
選択カーソルがオープンされた後、このフィールドにディスク・アクセス数と処理さ
れた行の総数の加重値の見積りが含まれます。
3 番目
4 番目
5 番目
PREPARE 文でのエラーの後は、このフィールドに、エラーが検出された文のテキスト
にオフセットが含まれます。(PREPARE 文は、6-29 ページの 『PREPARE 文での処理』
に説明されています。)
6 番目
選択した行の取り出し、または挿入、更新または削除の操作が正常終了したら、この
フィールドに、処理された最終行の行 ID ( 物理的アドレス ) が含まれます。
文字
(8)
SQLERRP
内部使用のみ。
図 6-4
SQLCODE と SQLERRD の使用
プログラム内の SQL 6-9
データベース・サーバーの呼出し
8 文字の
配列
SQLAWARN
データベースの開始時 :
1 番目
2 番目
3 番目
4 番目
5 番目
6 番目
7 番目
8 番目
任意のフィールドが W に設定されているときは、W に設定されます。このフィールドが空
白の場合、他のフィールドをチェックする必要はありません。
現在オープンしているデータベースがトランザクション・ログを使用する場合に、W に設定
されます。
現在オープンしているデータベースが ANSI 標準準拠である場合に、W に設定されます。
データベース・サーバーが IBM Informix OnLine である場合に、W に設定されます。
データベース・サーバー が 10 進数 (DECIMAL) 型フォームに実数 (FLOAT) データ型を格納す
る場合に、W に設定されます ( ホスト・システムに 実数 (FLOAT) 型のサポートがない場合 )。
使用されません。
使用されません。
使用されません。
他のすべての操作 :
1 番目
他のフィールドが W に設定されているときは、W に設定されます。
2 番目
列値がホスト変数に取り出され、列値が切り捨てられる場合に W に設定されます。
3 番目
集計関数が NULL 値を実行する場合に、W に設定されます。
4 番目
選択時、またはカーソルのオープン時に、選択リスト内の項目数が、それを受け取るための
INTO 節で与えられたホスト変数の数と同じでない場合に W に設定されます。 5 番目
UPDATE または DELETE 文を PREPARE 文で処理した後、PREPARE 文で処理された文が
WHERE 節を持たないため表全体が影響を受けるときに W に設定されます。 6 番目
ANSI 標準の SQL 構文を使用しない文の実行 (DBANSIWARN 環境変数が設定されていると
いう条件の下 ) の後に、W に設定されます。
7 番目
使用されません。
8 番目
使用されません。
文字
(71)
SQLERRM
エラー・メッセージが含まれます。
図 6-5
SQLAWARN の使用
6-10 プログラム内の SQL
データベース・サーバーの呼出し
特に、SQLERRD 配列と SQLAWARN 配列の 1 つの要素に名前を付けるサブス
クリプトは異なります。つまり、配列要素は、IBM Informix ESQL/C ではゼ
ロで始まる番号が付きますが、他の言語ではゼロで始まりません。この
ディスカッションでは、フィールドが third などの明白な単語を使用して名
前が付けられており、使用しているプログラミング言語の構文に変換する
必要があります。
SQLCODE フィールド
SQLCODE フィールドは、データベース・サーバーの 1 次戻りコードです。
すべての SQL 文の後に、SQLCODE は 図 6-4 に示される整数値に設定され
ます。その値がゼロである場合、文はエラーなく実行されます。特に、文
がホスト変数にデータを戻すことになっている場合、ゼロのコードは、
データが戻されて使用されたということを意味します。非ゼロのコードは
その反対、つまり、有効なデータがホスト変数に戻されなかったというこ
とを意味します。
4GL では、SQLCODE は STATUS という名前の下でもアクセスできます。
データの終わり
データベース・サーバーは、文は正しく実行されたが行が検出されなかっ
た場合、SQLCODE を 100 に設定します。例えば、プログラムが SELECT 文
が作成できるすべての行を取り出した後に、データベース・サーバーは
SQLCODE を 100 に設定して、データの終わり を示します。ANSI 標準準拠
データベースでは、DELETE、INSERT、または UPDATE の各文の WHERE 節
がどの行にも一致しない場合、100 が設定されてどの行も検出されなかっ
たことが示されます。
負数コード
予期されなかった要素が文の実行中に生じた場合、データベース・サー
バーは、SQLCODE に負の数値を戻して問題があることを示します。これら
のコードの意味は、IBM Informix エラー・メッセージ の説明書とオンライン・
エラー・メッセージ・ファイルで文書化されています。
SQLCODE で報告できるいくつかのエラー・コードは、一般的な問題を反映
します。そして、データベース・サーバーは、より詳細なコードを
SQLERRD の 2 番目のフィールドに設定できます。この 2 番目のコードは、
データベース・サーバーの I/O ルーチンまたは基礎となるオペレーティン
グ・システムによって実行された低レベル・エラーを示します。
プログラム内の SQL 6-11
データベース・サーバーの呼出し
SQLERRD 配列
SQLERRD と呼ばれる配列内の整数は、異なる文に続く異なる値に設定され
ます。配列の 1 番目および 4 番目の要素は、IBM Informix 4GL、IBM Informix
ESQL/C、および IBM Informix ESQL/COBOL でのみ使用されます。フィール
ドは、図 6-4 で示すように使用されます。
これらの追加の詳細は、非常に有効である場合があります。例えば、3 番
目のフィールドの値を使用して、削除または更新された行を報告すること
ができます。プログラムが、ユーザーによって入力された SQL 文を PREPARE 文で処理してエラーが検出される場合、5 番目のフィールドの値を使
用すると、エラーの正確なポイントをユーザーに表示することができます。
(DB-Access と IBM Informix SQL は、ユーザーがエラー後に文を修正するよう
要求するときに、この機能を使用してカーソルを配置します。)
SQLAWARN 配列
SQLAWARN 配列の 8 文字フィールドは、ブランクまたは W のいずれかに設
定されて、多様な特殊条件を示します。先頭の 6 つだけが使用されます。
これらの意味は、実行されたばかりの文によって異なります。
データベースがオープンされたばかりのとき、つまり、DATABASE または
CREATE DATABASE 文の後に表示される、1 セットの警告フラグがありま
す。これらのフラグは、全体としてデータベースのいくつかの特性を伝え
ます。
フラグの 2 番目のセットは、他の任意の文に続いて表示されます。これら
のフラグは、文の実行中の誤ったイベント、つまり、SQLCODE によって反
映されないことがあるイベントを反映します。
SQLAWARN 値の両方のセットは、図 6-5 に要約されています。
6-12 プログラム内の SQL
単一行の抽出
単一行の抽出
埋込み SELECT 文を使用して、データベースからの単一行をホスト変数に
抽出することができます。ただし、SELECT 文が 1 行以上のデータを戻す場
合は、プログラムはより複雑なメソッドを使用して 1 度に複数の行を取り
出す必要があります。複数行選択操作については、この章の後半で説明し
ます。
単一行のデータを抽出するには、単に SELECT 文をプログラムに埋め込み
ます。次に、IBM Informix ESQL/C を使用して書き込むことができる場合の
例を示します。
$
select avg (total_price)
into $avg_price
from items
where order_num in
(select order_num from orders
where order_date < date("6/1/91"));
INTO 節は、このステートメントを第 2 章または第 3 章における例と区別す
る唯一の詳細です。この節には、作成されるデータを受け取るためのホス
ト変数が指定されます。
プログラムが埋込み SELECT 文を実行すると、データベース・サーバーは
問合せを実行します。例の文では、集計関数値を選択するため、ちょうど
1 行のデータが作成されます。その行は、単一列のみを持ち、その値は
avg_price と呼ばれるホスト変数に配置されます。プログラムの後続の行
は、その変数を使用することができます。
この種の文を使用して、データの単一行をホスト変数に抽出できます。単
一行は、必要なだけ多くの列を持つことができます。この IBM Informix 4GL
例では、ホスト変数は 2 つの方法、つまりデータの受任者として、および
WHERE 節において使用されます。
DEFINE cfname, clname, ccompany CHAR(20)
DEFINE cnumbr INTEGER
LET cnumbr = 104
SELECT fname, lname, company
INTO cfname, clname, ccompany
FROM customer
WHERE customer_num = cnumbr
プログラム内の SQL 6-13
単一行の抽出
customer_num 列が一意性インデックス ( 制約を通して実装された ) を持つ
場合、この問合せによって 1 行だけが戻されます。問合せによって 1 行以
上のデータが作成される場合、データベース・サーバーは全くデータを戻
すことができません。その代わりに、エラー・コードを戻します。
選択リストに複数の項目があるできるだけ多くの INTO 節内のホスト変数を
リストしなければなりません。偶然にもこれらのリストが異なる長さで
あった場合、データベース・サーバーはできるだけ多くの値を戻し、SQLAWARN の 4 番目のフィールドに警告フラグを設定します。
データ型の変換
この例は、それ自体が 10 進数 (DECIMAL) 型値である 10 進数 (DECIMAL) 型列
の平均を抽出します。ただし、配置される先のホスト変数は、そのデータ
型を持つために必要ではありません。
$
select avg (total_price) into $avg_price
from items;
受け取る変数 avg_price の宣言は、ESQL/C コードのこの例では、表示され
ません。次の定義のいずれかである可能性があります。
$
$
$
$
int avg_price;
double avg_price;
char avg_price[16];
dec_t avg_price; /* typedef of decimal number structure */
文で使用されるそれぞれのホスト変数のデータ型が示され、文と一緒に
データベース・サーバーに渡されます。データベース・サーバーは、列
データを、受け取る変数によって使用される形式に変換するために最善を
尽くします。精度の損失を引き起こす変換もありますが、ほとんどすべて
の変換が許可されます。上述の例の結果は、次のリストで説明するとおり、
受け取るホスト変数のデータ型によって異なります。
6-14 プログラム内の SQL
単一行の抽出
実数 (FLOAT) 型
データベース・サーバーは、10 進数値の結果を、
いくつかの小数桁を切り捨てる場合もある実数
(FLOAT) 型に変換します。
10 進数値の絶対値が 実数 (FLOAT) 型フォーマットの
最大絶対値を超える場合、エラーが戻されます。
整数 (INTEGER) 型
データベース・サーバーは、結果を整数に変換し、
必要に応じて小数桁を切り捨てます。
変換した数値の整数部分が受け取る変数と合わない
場合、エラーが生じます。
文字 (CHARACTER) 型
データベース・サーバーは、10 進数値を文字列に
変換します。
受け取る変数用に文字列が長すぎる場合は切り捨て
られ、SQLAWARN の 2 番目のフィールドに W が設
定されます。
NULL データの処理
問題によって NULL 値が抽出された場合はどうしたらよいのでしょうか。
NULL 値はデータベースに格納できますが、プログラミング言語によって
サポートされたデータ型は NULL 値を認識しません。プログラムは、デー
タとして NULL の項目を処理することを回避するために、NULL の項目を
認識するいくつかの方法を保持する必要があります。
標識変数 は、埋込み言語製品でこのニーズを満たします。標識変数とは、
NULL の項目を受け取るホスト変数と関連付けられた追加の変数です。
データベース・サーバーは、主変数にデータを書き込むときに、データが
NULL であるかどうかを示すために標識変数にも特殊値を書き込みます。
$
select paid_date
into $op_date:op_d_ind
from orders
where order_num = $the_order;
if (op_d_ind < 0) /* data was null */
rstrdate ("01/01/1900", &op_date);
この IBM Informix ESQL/C 例では、単一行が選択され、単一値がホスト変数
op_date に抽出されます。値が NULL である場合があるために、標識変数
op_d_ind がホスト変数と関連付けられます。( これは、プログラム内のど
こかに短整数として宣言される必要があります。)
プログラム内の SQL 6-15
単一行の抽出
SELECT 文の実行に続いて、プログラムは負数値の標識変数をテストしま
す。負の数値 ( 普通 -1) は、主変数に抽出された値が NULL であることを意
味します。この場合、このプログラムは C 関数を使用してデフォルト値を
ホスト変数に割り当てます。( rstrdate 関数は、IBM Informix ESQL/C 製品に
含まれています。)
標識変数を関連付けるために使用する構文は使用する言語によって異なり
ますが、原則は全体的に同じです。ただし、標識変数は 4GL または SPL で
は明示的に使用されません。これは、これらの言語では NULL 値が変数と
してサポートされていないためです。4GL では、上述の例は次のように書
き込まれます。
SELECT paid_date
INTO op_date
FROM orders
WHERE order_num = the_order
IF op_date IS NULL THEN
LET op_date = date ("01/01/1900")
END IF
エラーの処理
データベース・サーバーは自動的にデータ型とデータ型の間の変換を処理
しますが、それでも、いくつかのものが SELECT 文を使用するとうまくい
かない場合があります。SQL プログラミングでは、任意の種類のプログラ
ミング内で、エラーを予期してすべてのポイントでその準備をしておく必
要があります。
6-16 プログラム内の SQL
単一行の抽出
データの終わり
1 つの共通イベントとして、どの行も問合せを満たさないことを挙げるこ
とができます。これは、SELECT 文に続いて、SQLCODE 内の 100 のコード
( または ESQL/C でも認識される sqlca.sqlcode) によって示されます。この
コードは、エラーまたは標準イベントを指示し、全体的にアプリケーショ
ンによって異なります。例えば、別の表の行から読み込んだばかりのキー
値を使用して行を読み込んでいる場合など、1 つまたは複数の行があるこ
とが確実である場合、データの終わりコードは、プログラムのロジック内
の重大な障害を表します。その反対に、ユーザー提供のキー、またはプロ
グラムより信頼性の低い他のいくつかのソースによって提供されたキーを
基にした行を選択している場合、データの不足が標準イベントになること
があります。
集計関数のデータの終わり
使用しているデータベースが ANSI 標準準拠でない場合、データの終わ
りの復帰コード 100 は SELECT 文に続く SQLCODE にのみ設定されます。
(INSERT、UPDATE、および DELETE などの他の文は、それらの文に
よって影響を受けた行数を表示するように SQLERRD の 3 つ目の要素を
設定します。このトピックは、本書の第 7 章で説明されています。)
SUM、MIN、または AVG などの集計関数を選択する SELECT 文は、常
に、少なくとも 1 行のデータを正常に戻します。これは、WHERE 節の
条件を満たす行がない場合でも当てはまります。つまり、行の空の
セットを基にした集計関数値が NULL でも、その値は存在します。
ただし、集計関数値は、すべてに NULL 値が含まれる 1 つまたは複数
の行を基にしている場合も NULL になります。基にする行を持たない
集計関数値と、すべてが NULL であるいくつかの行を基にしている集
計関数値との間の違いを検出できる必要がある場合は、文に COUNT 関
数を、集計関数値に標識変数を含める必要があります。その後、次の
3 つのケースを処理できます。
カウント値
標識
0
>0
-1
-1
>0
0
ケース
ゼロ行が選択されました。
すべて NULL のいくつかの行が選択され
ました。
非 NULL のいくつかの行が選択されまし
た。
プログラム内の SQL 6-17
単一行の抽出
重大なエラー
データベース・サーバーは、重大な問題をほとんどレポートしません。負
数の戻り値は、予期しないときにごくまれに生じますが、そのために無視
することはできません。
例えば、問合せは、エラー 206 を戻します。これは、表名がデータベース
にないことを意味します。このことは、プログラムが作成されてから他の
ユーザーが表を削除したか、またはロジックのエラーまたは入力ミスに
よってプログラムが誤ったデータベースをオープンしたときに生じます。
このようなエラーが生じる可能性がありますが、この場合には、プログラ
ムはこれらを処理する必要があります。
デフォルト値の使用
これらの必然的なエラーを処理する方法は数多くあります。いくつかのア
プリケーションでは、標準状態を処理するよりもエラーを処理するコード
の行のほうが多くある場合があります。ただし、このセクションの例にお
いては、最も簡単なメソッドの 1 つ、つまりデフォルト値が機能します。
avg_price = 0; /* set default for errors */
$
SELECT AVG (total_price)
INTO $avg_price:null_flag
FROM items;
if (null_flag < 0) /* probably no rows */
avg_price = 0; /* set default for 0 rows */
この例では、次の考慮事項を扱います。
• 問合せがいくつかの非 NULL の行を選択する場合、正確な値が戻されて
使用されます。これは、予期されている最も頻繁な結果です。
• 問合せがどの行も選択しない場合、または NULL 値を持つ行のみを
total_price 列 (NULL になることはない列 ) で選択するというあまり発生
する見込みのないイベントにおいては、標識変数が設定され、デフォル
ト値が割り当てられます。
• 重大なエラーが生じた場合、ホスト変数は未変更のまま残されます。こ
れには、初期に設定されたデフォルト値が含まれます。プログラムのこ
のポイントで、プログラマーはこのようなエラーをトラップしてレポー
トする必要はありません。
6-18 プログラム内の SQL
複数行の抽出
次に、上述の IBM Informix 4GL 例の拡張例を示します。この例では、ユー
ザーが要求する企業が検出できない場合にデフォルト値を表示します。
DEFINE cfname, clname, ccompany CHAR(20)
DEFINE cnumbr INTEGER
PROMPT "Enter the customer number: " FOR cnumbr
LET cfname = "unknown"
LET clname = "person"
LET ccompany = "noplace"
SELECT fname, lname, company
INTO cfname, clname, ccompany
WHERE customer_num = cnumbr
DISPLAY cfname, " ", clname, " at ", ccompany
この問合せは、集計関数を使用しません。そのため、ユーザー指定の顧客
番号に一致する行がない場合は、SQLCODE が 100 に設定され、ホスト変数
は未変更のまま残されます。
複数行の抽出
問合せによって 1 行以上の行が戻される可能性がある場合、プログラムは
その問合せを異なる方法で実行する必要があります。複数行問合せは、2
段階で処理されます。最初は、プログラムが問合せを開始します。データ
は即時には戻されません。次に、プログラムは一度にデータの複数の行を
要求します。
これらの操作は、カーソル と呼ばれる特別なデータ・オブジェクトを使用
して実行されます。カーソルは、問合せの現行状態を表すデータ構造体で
す。プログラム操作の一般的なシーケンスは、次のとおりです。
1. プログラムは、カーソルとそれに関連した SELECT 文を宣言 します。こ
れは、単にカーソルを保留するための記憶域を割り当てるだけです。
2. プログラムは、カーソルをオープン します。これによって、関連した
SELECT 文の実行が起動し、その中にエラーが検出されます。
3. プログラムは、1 行のデータをホスト変数に取り出 して処理します。
4. プログラムは、最後の行が取り出された後にカーソルをクローズ しま
す。
これらの操作は、DECLARE、OPEN、FETCH、および CLOSE と呼ばれる SQL
文を使用して実行されます。
プログラム内の SQL 6-19
複数行の抽出
カーソルの宣言
カーソルは、DECLARE 文を使用して宣言されます。この文は、カーソルに
名前を付けて使用法を指定し、そのカーソルを文と関連付けます。次に、
IBM Informix 4GL の簡単な例を示します。
DECLARE the_item CURSOR FOR
SELECT order_num, item_num, stock_num
INTO o_num, i_num, s_num
FROM items
宣言によって、カーソルは名前 ( ここでは the_item) が付けられ、SELECT
文と関連付けられます。( 本書の第 7 章には、カーソルを INSERT 文にも関
連付ける方法について説明されています。)
この例での SELECT 文には、INTO 節が含まれます。これは、データを受け
取る変数を指定できる 2 つの方法のうちの 1 つです。
DECLARE 文は、有効な文ではありません。これは、単にカーソルの機能を
確立して、それに記憶域を割り当てます。上述の例で宣言されたカーソル
を使用して、items 表を一度読み込むことができます。カーソルを宣言し
て、逆方向と正方向の両方に読み込むこともできます (6-23 ページの
『カーソル入力モード』を参照してください )。このカーソルは、FOR
UPDATE 節を持たないために、おそらくデータの読込みに使用されるだけ
で、データの修正には使用されません。( データ修正のためのカーソルの使
用方法は、本書の第 7 章に説明しています。)
カーソルのオープン
プログラムは、カーソルを使用する準備が整ったときに、カーソルをオー
プンします。OPEN 文が、カーソルを起動します。これにより、関連した
SELECT 文がデータベース・サーバーに渡され、一致する行の検索が開始さ
れます。データベース・サーバーは、出力の最初の行を位置決めしたり構
成したりするポイントまで問合せを処理します。データベース・サーバー
は、実際にその行のデータを戻すのではなく、復帰コードを SQLCODE に設
定します。次に、OPEN 文の IBM Informix 4GL における例を示します。
OPEN the_item
6-20 プログラム内の SQL
複数行の抽出
データベース・サーバーで問合せを実行するのは今回が初めてのため、多
くのエラーが検出されます。カーソルのオープン後、プログラムは SQLCODE をテストしなければなりません。負の数値が含まれる場合には、
カーソルは使用できません。SELECT 文にエラーがあったり、いくつかの他
のプログラムがデータベース・サーバーに文を実行させないようにしてい
たりする場合があります。
SQLCODE にゼロが含まれる場合、SELECT 文は構文上有効でカーソルを使
用できます。ただし、このポイントでは、プログラムはカーソルが行を作
成できるかどうかを判別しません。
行の取出し
プログラムは、FETCH 文を使用して、出力の各行を抽出します。この文は
カーソルを命名します。また、データを受け取るホスト変数を命名するこ
ともできます。次に完了した IBM Informix 4GL 例を示します。
DECLARE the_item CURSOR FOR
SELECT order_num, item_num, stock_num
INTO o_num, i_num, s_num
FROM items
OPEN the_item
WHILE sqlcode = 0
FETCH the_item
IF sqlcode = 0 THEN
DISPLAY o_num, i_num, s_num
END IF
END WHILE
プログラム内の SQL 6-21
複数行の抽出
データの終わりの検出
この例では、WHILE 条件は、OPEN 文がエラーを戻す場合にはループの実行
を回避します。同じ条件で、SQLCODE が 100 に設定されてデータの終わり
が示されるときはループが終了します。ただし、ループ内部には SQLCODE
のテスト (status の 4GL 名で ) もあります。このテストは必要です。という
のも、SELECT 文が有効でも一致する行が検索されない場合は、OPEN 文は
ゼロを戻しますが、最初の取出しによって 100 やデータの終わりが戻され
たり、全くデータが戻されないためです。次に、同じループを別の方法で
書き込んだ例を示します。
DECLARE the_item CURSOR FOR
SELECT order_num, item_num, stock_num
FROM items
OPEN the_item
IF sqlcode = 0 THEN
FETCH the_item -- fetch first row
END IF
WHILE sqlcode = 0
DISPLAY o_num, i_num, s_num
FETCH the_item
END WHILE
このバージョンでは、ゼロが戻された行の場合はすでに扱われているため、
ループ内部に sqlcode の 2 番目のテストはありません。これらのバージョン
には、sqlcode のテストの時間コストが取出しコストのほんの一部でしかな
いために、パフォーマンス上計測できる差はありません。
INTO 節の位置決め
INTO 節は、データベース・サーバーによって戻されるデータを受け取るホ
スト変数を命名します。これは、SELECT 文または FETCH 文のいずれかで
表示される必要がありますが、両方で表示される必要はありません。次に、
FETCH 文でホスト変数を指定するために再処理された例を示します。
DECLARE the_item CURSOR FOR
SELECT order_num, item_num, stock_num
FROM items
OPEN the_item
WHILE status = 0
FETCH the_item INTO o_num, i_num, s_num
IF status = 0 THEN
DISPLAY o_num, i_num, s_num
END IF
END WHILE
6-22 プログラム内の SQL
複数行の抽出
2 つ目のフォームには、異なる行は異なる変数に取り出されることができ
るという利点があります。例えば、このフォームを使用して、連続した行
を配列の連続した要素として取り出すことができます。
カーソル入力モード
入力目的のために、カーソルは 2 つのモード ( 順次 またはスクロール ) のう
ちのいずれかで作動します。順次カーソルは、シーケンス内の次の行しか
取り出すことができません。そのため、オープンするごとに一度しか表を
読み通すことができません。スクロール・カーソルは、次の行または以前
の行を取り出すことができるため、複数回行を読み込むことができます。
次に、IBM Informix ESQL/C で宣言された順カーソルを示します。
EXEC SQL DECLARE pcurs CURSOR FOR
SELECT customer_num, lname, city
FROM customer;
オープン後、このカーソルはデータの次の行を抽出する順次取出しを用い
てのみ使用できます。
EXEC SQL FETCH p_curs INTO $cnum, $clname, $ccity;
順次取出しごとに、新規の行が戻されます。
スクロール・カーソルは、さまざまな取り出しオプションと共に使用でき
ます。ABSOLUTE オプションは、取り出す行のランク数値を指定します。
+
EXEC SQL FETCH ABSOLUTE numrow s_curs
INTO :nordr, :nodat
この文は、ホスト変数 numrow で位置が指定されている行を取り出します。
また、現行行を再び取り出したり、最初の行を取り出してからリスト全体
を通して再び走査したりすることもできます。ただし、これらの機能を取
得するには、次のセクションで説明するとおりかなりの犠牲が必要となり
ます。
プログラム内の SQL 6-23
複数行の抽出
カーソルのアクティブ・セット
カーソルはオープンされると、行のいくつかの選択を表します。問合せに
よって作成されるすべての行のセットは、カーソルのアクティブ・セット
と呼ばれます。アクティブ・セットを明確に定義された行のコレクション
として考え、カーソルをそのコレクションの 1 つの行のポインティングと
して考えると簡単です。この状態は、その他のプログラムが同じデータを
並行して修正している場合を除いて真です。
アクティブ・セットの作成
カーソルがオープンすると、データベース・サーバーは選択済みデータの
最初の行を格納するために必要な処置をすべて行います。この処置は、問
合せのフレーズ方法によっては、とても簡単に実行できる場合や、非常に
多くの処理と時間が必要になる場合があります。
DECLARE easy CURSOR FOR
SELECT fname, lname FROM customer
WHERE state = "NJ"
このカーソルは単純な方法で単一表のみを問い合わせるため、データベー
ス・サーバーは、任意の行が問合せを満たすかどうかを非常に迅速に発見
して、最初の行を検索することができます。最初の行は、この時点でデー
タベース・サーバーが検索する唯一の行です。アクティブ・セット内の残
りの行は、特定できないまま残されます。
DECLARE hard CURSOR FOR
SELECT C.customer_num, O.order_num, sum (items.total_price)
FROM customer C, orders O, items I
WHERE C.customer_num = O.customer_num
AND O.order_num = I.order_num
AND O.paid_date is null
GROUP BY C.customer_num, O.order_num
このカーソルのアクティブ・セットは、3 つの表を結合して出力行をグ
ループ化することによって生成されます。オプティマイザーは、インデッ
クスを使用して正確な順序で行を作成することができるかもれませんが
( 詳細は、本書の第 4 章を参照してください )、一般的に、ORDERBY 節また
は GROUP BY 節を使用すると、データベース・サーバーはすべての行を生
成してそれらを一時表にコピーし、どの行が最初に表示されるかが分かる
ようにその表をソートする必要があります。
6-24 プログラム内の SQL
複数行の抽出
アクティブ・セットが完全に作成されて一時表に保存される場合、データ
ベース・サーバーは、カーソルをオープンするのに時間がかかることがあ
ります。その後、アクティブ・セットに含まれる行数を正確にプログラム
に伝えることができます。ただし、この情報は利用可能にはなりません。
1 つの理由として、ユーザーには、オプティマイザーがどのメソッドを使
用するかが分からないためです。ソートおよび一時表を回避できる場合は、
回避します。ただし、問合せ、表のサイズ、または利用できるインデック
スにおける非常に小さな変更によって、そのメソッドが変更される場合が
あります。
順カーソルのアクティブ・セット
データベース・サーバーは、カーソルのアクティブ・セットのメンテナン
スにおいて、できる限り少ないリソースを関連付けたい場合があります。
そうすることが可能な場合、データベース・サーバーは次に取り出される
1 行以上の行を保存しません。このことは、ほとんどの順カーソルに対し
て可能です。取出しごとに、現行行の内容を戻し、次の行を見つけます。
スクロール・カーソルのアクティブ・セット
スクロール・カーソルのアクティブ・セット内のすべての行は、カーソル
がクローズされるまで保存される必要があります。これは、データベー
ス・サーバーには、プログラムが次に要求する行が分からないためです。
かなり頻繁に、データベース・サーバーは、スクロール・カーソルのアク
ティブ・セットを一時表として実装します。ただし、データベース・サー
バーは、この表を即時には満たさないことがあります ( 問合せの処理のた
めに一時表を作成する場合を除く )。データベース・サーバーは、通常、
カーソルがオープンしたときに一時表を作成します。その後、行が最初に
取り出されるときに、データベース・サーバーはその行を一時表にコピー
してプログラムに戻します。2 回目に行が取り出されるときは、一時表か
ら取り出すことができます。このスキーマは、すべての行を取り出す前に
プログラムが問合せを中止するイベントにおいて、最少のリソースを使用
します。取り出されることがない行は、作成も保存もされません。
アクティブ・セットと同時実行性
1 つのプログラムだけがデータベースを使用しているとき、アクティブ・
セットのメンバーは変更できません。これは、ほとんどのデスクトップ・
ワークステーションにおける状態で、最も簡単に考えられる状態です。し
かし、プログラムのなかには、多数の異なるプログラムが同じ表で同時に
作業できる多重ランチャー・システムで使用できるように設計される必要
があるものもあります。
プログラム内の SQL 6-25
複数行の抽出
カーソルがオープンしている間に他のプログラムが表を更新できる場合、
アクティブ・セットのアイデアはあまり有効でなくなります。プログラム
は、一度に 1 行のデータしか表示できませんが、表の他のすべての行は変
更されている可能性があります。
簡単な問合せの場合、データベース・サーバーがアクティブ・セットの 1
行のみを保留すると、他の行が変更されることがあります。使用している
プログラムが行を取り出すと、すぐに他のプログラムは同じ行を削除また
は更新できるため、その行が再び検証される場合、その行はアクティブ・
セットの一部ではなくなります。
アクティブ・セットまたはその一部が一時表に保存される場合、失効した
データ の問題があります。つまり、アクティブ・セットの行の引き出し元
である実際の表の行が変更されることがあります。変更された場合、いく
つかのアクティブ・セットの行は現行の表の内容を反映しなくなります。
これらのアイデアは、最初は不安定に見えるかもしれませんが、プログラ
ムがデータを読み込むだけであれば、失効したデータのようなものはなく、
むしろ、すべてのデータが同等に失効状態にあります。アクティブ・セッ
トは、いつ取られようとも、ある一瞬のある地点のデータのスナップ
ショットです。行は次の日には異なっています。同様に、ミリ秒後に異
なっていても問題はありません。言い換えれば、プログラム実行中に生じ
る変更とプログラム終了時に保存されて適用される変更との間に実質的な
差はありません。
失効したデータが問題を引き起こす可能性がある唯一の場合は、プログラ
ムが入力データを使用して同じデータベースを修正しようとするときです。
例えば、銀行用アプリケーションが勘定残高を読み取り、変更し、書き込
んで戻す必要がある場合です。次の章では、データを修正するプログラム
について説明します。
カーソルの使用 : 部品展開
プログラム・ロジックによって補足されたカーソルを使用すると、プレー
ン SQL で解決できない問題を解決できます。これらの問題のうちの 1 つは
部品展開問題で、これは Bill of Materials 処理と呼ばれることもあります。
この問題の核心にあるのは、1 つのオブジェクトに他のオブジェクトが含
まれる ( このオブジェクトにもまた他のオブジェクトが含まれる ) ようなオ
ブジェクト間の再帰的な関係です。
問題は、通常、製造在庫に関して述べられます。企業は、さまざまなパー
ツを製造します。別個のパーツもあれば、他のパーツと組み合わされた
パーツもあります。
6-26 プログラム内の SQL
複数行の抽出
これらの関係は、contains という名が付いている可能性がある単一表に文
書化されています。その列 contains.parent に、組み立てられたパーツの
パーツ・ナンバーが保留されます。列 contains.child には、親のコンポーネ
ントであるパーツのパーツ・ナンバーが含まれます。パーツ #123400 が 9
つのパーツを組み立てたものである場合は、最初の列に 123400、2 番目の
列に他のパーツ・ナンバーを使用した 9 行が存在します。
CONTAINS
PARENT
FK NN
123400
432100
CHILD
FK NN
432100
765899
部品展開の問題は次のとおりです。パーツ・ナンバーが与えられると、そ
のパーツのコンポーネントであるすべてのパーツのリストを作成します。
IBM Informix 4GL で実装された 1 つのソリューションのスケッチを、図 6-6
に示します。
DEFINE part_list ARRAY[200] OF INTEGER
FUNCTION boom (top_part)
DEFINE this_part, child_part INTEGER
DEFINE next_to_do, next_free SMALLINT
DECLARE part_scan CURSOR FOR
SELECT child INTO child_part FROM contains
WHERE parent = this_part
LET next_to_do = 1
LET part_list[next_to_do] = top_part
LET next_free = 2
WHILE next_to_do < next_free
this_part = part_list[next_to_do]
FOREACH part_scan
LET part_list[next_free] = child_part
LET next_free = next_free + 1
END FOREACH
LET next_to_do = next_to_do + 1
END WHILE
RETURN next_free - 1
END FUNCTION
図 6-6
部品展開を生成するための横方向優先探索のアルゴリズム
プログラム内の SQL 6-27
複数行の抽出
専門的に言えば、contains 表の各行は、有向非周期サイクル、つまりツ
リーのヘッド・ノードです。図 6-6 の関数は、パラメーターとして渡され
たパーツ・ナンバーであるルートを持つツリーの横方向優先探索を実行し
ます。この関数は、カーソル part_scan を使用して、parent 列に特定の値
を持つすべての行を戻します。このことは、IBM Informix 4GL 文 FOREACH
を使用すると実装が非常に簡単です。FOREACH は、カーソルをオープン
し、選択セットの各行を 1 回繰り返してから、カーソルをクローズします。
また、このことは、部品展開問題の核心ですが、完全なソリューションで
はありません。例えば、図 6-6 のプログラムは、ツリーでコンポーネント
が 1 レベル以上に表示されることを許可しません。さらに、実際の contains 表には、列 count も含まれ、この列に、それぞれの parent で使用され
た child パーツのカウントが示されます。各コンポーネント・パーツの合計
カウント数を戻すプログラムは、大変複雑になります。
すでに説明した反復アプローチが、部品展開問題に取り組む唯一の方法と
は限りません。世代番号に固定された制限がある場合は、入れ子になった
外部の自己結合を使用して単一の SELECT 文での問題を解決することがで
きます。
1 つの最上位部内にパーツの 4 つの世代までを含めることが可能な場合、次
の SELECT 文はそれらのすべてを戻します。
SELECT a.parent, a.child, b.child, c.child, d.child
FROM contains a
OUTER (contains b,
OUTER (contains c, outer contains d))
WHERE a.parent = top_part_number
AND a.child = b.parent
AND b.child = c.parent
AND c.child = d.parent
この SELECT 文は、top_part_number として与えられたパーツをルートとす
る世代の行ごとに 1 行を戻します。存在しないレベルには、NULL 値が戻
されます。( これらを検出するには標識変数を使用してください。) このソ
リューションは、contains 表の入れ子になった外部結合を追加選択するこ
とによって、より多くのレベルに拡張できます。また、このソリューショ
ンを、レベルごとにパーツ・ナンバーのカウント数を戻すよう修正するこ
ともできます。
6-28 プログラム内の SQL
動的 SQL
動的 SQL
静的 SQL が極めて有効である間は、ユーザーは、プログラムの作成時にす
べての SQL 文の正確な内容を知っておく必要があります。例えば、任意の
WHERE 節でテストされる列および任意の選択リスト内で名前が付けられる
列を正確に述べる必要があります。
これは、特定の、明確に定義されたタスクを実行するプログラムを作成す
るときには問題にはなりません。しかし、いくつかのプログラムのデータ
ベース・タスクは、事前に完全には定義できません。特に、対話式ユー
ザーに応答する必要があるプログラムは、ユーザーが入力するデータに応
答して、SQL 文を構成する機能を必要とする場合があります。
動的 SQL を使用すると、プログラムは実行中に SQL 文を形成できます。そ
のため、その文の内容によりユーザー入力を判別できます。これは、次の
3 つのステップで実行されます。
1. プログラムは、SQL 文のテキストを、プログラム変数に格納された文字
列としてアセンブルする。
2. プログラムは、PREPARE 文を実行して、文のテキストを検証して実行
のための準備をするようにデータベース・サーバーに要求する。
3. プログラムは、EXECUTE 文を使用して、PREPARE 文で処理された文を
実行する。
この方法で、プログラムは、任意の種類のユーザー入力を基にした任意の
SQL 文を構成し、使用できます。例えば、SQL 文のファイルを読み込み、
それぞれを PREPARE 文で処理して実行できます。
SQL を対話式に探査するために使用するユーティリティー DB-Access は、
SQL 文を動的に構築して PREPARE 文で処理し、それから実行する
IBM Informix ESQL/C プログラムです。例えば、これによって、ユーザーは
簡単で対話的なメニューを使用して表の列を指定できます。ユーザーが終
了すると、DB-Access は必要な CREATE TABLE 文または ALTER TABLE 文を
動的に作成し、PREPARE 文で処理して実行します。
PREPARE 文での処理
フォームでは、動的 SQL 文はホスト変数名を含めることができないことを
除き、プログラムに書きこまれた他の SQL 文と同様です。
これによって、次の 2 つの制約事項が導かれます。1 つ目は、それが
SELECT 文である場合は、INTO 節を含めることができません。その節は、
列データの配置先のホスト変数を命名し、そのホスト変数は動的文で許可
されません。2 つ目は、通常ホスト変数名が表現式に表示される場合は常
に、疑問符 (?) マークが位置指定子として書き込まれます。
プログラム内の SQL 6-29
動的 SQL
PREPARE 文を使用して実行するために、このフォームで文を PREPARE 文
で処理できます。次に、IBM Informix ESQL/C での例を示します。
$
prepare query_2 from
"select * from orders
where customer_num = ? and
order_date > ?";
この例では、2 つの疑問符があります。これらは、文が実行されるときに
ホスト変数の値がこれらの 2 つのポイントで使用されるということを示し
ています。
ほとんどすべての SQL 文を PREPARE 文で動的に処理できます。PREPARE
文で処理できない唯一の文は、PREPARE 文と OPEN 文などの、動的 SQL と
カーソル管理に直接関係している文です。UPDATE 文または DELETE 文を
PREPARE 文で処理した後は、SQLAWARN の 5 番目のフィールドをテストし
て、WHERE 節 (6-12 ページの 『SQLAWARN 配列』を参照 ) を使用したかど
うかを確認してください。
文を PREPARE 文で処理した結果は、その文を表すデータ構造体です。こ
のデータ構造体は、それを作成した文字列と同じではありません。PREPARE 文で、そのデータ構造体に名前を付けます。上述の例では、query_2
です。この名前は、PREPARE 文で処理された SQL 文を実行するときに使
用されます。
6-30 プログラム内の SQL
動的 SQL
PREPARE 文は、文字列を 1 つの文に制限しません。この文には、複数の
SQL 文を、セミコロン (;) で区切って含めることができます。IBM Informix
ESQL/COBOL におけるかなり複雑な例を、図 6-7 に示します。
EXEC SQL
MOVE "
BEGIN WORK;
UPDATE account
SET balance = balance + ?
WHERE acct_number = ?;
UPDATE teller
SET balance = balance + ?
WHERE teller_number = ?;
UPDATE branch
SET balance = balance + ?
WHERE branch_number = ?;
INSERT INTO history VALUES(timestamp, values);
COMMIT WORK"
TO :BIG-QUERY.
END-EXEC.
EXEC SQL
PREPARE BIG-Q FROM :BIG-QUERY
END-EXEC.
図 6-7
5 つの SQL 文を含む文字列の PREPARE 文による処理
この文のリストが実行されると、ホスト変数は、6 つの位置指定疑問符 (?)
に値を提供する必要があります。複数文リストをセットアップするのがよ
り複雑になる一方、プログラムとデータベース・サーバーとの間で行われ
るエクスチェンジが少なくなるために、パフォーマンスがよくなる場合も
あります。
プログラム内の SQL 6-31
動的 SQL
PREPARE 文で処理された SQL の実行
文は 1 度 PREPARE 文で処理されると、何回でも実行できます。SELECT 文
以外の文、および単一行のみを戻す SELECT 文は、EXECUTE 文と共に実行
されます。
図 6-8 に、IBM Informix ESQL/C が銀行口座の複数文更新を PREPARE 文で
処理して実行する方法を示します。
$char bigquery[15] = "begin work";
stcat ("update account set balance = balance + ? where ", bigquery);
stcat ("acct_number = ?;", bigquery);
stcat ("update teller set balance = balance + ? where ", bigquery);
stcat ("teller_number = ?;", bigquery);
stcat ("update branch set balance = balance + ? where ", bigquery);
stcat ("branch_number = ?;", bigquery);
stcat ("insert into history values(timestamp, values);", bigquery);
stcat ("commit work;", bigquery);
$PREPARE bigq FROM $bigquery;
$EXECUTE bigq USING $delta, $acct_number,$delta,
$teller_number, $delta, $branch_number;
図 6-8
ESQL/C での複数文操作の PREPARE 文による処理と実行
EXECUTE 文の USING 節は、PREPARE 文で処理された文で疑問符 (?) に代わ
る値を持つホスト変数のリストを提供します。
PREPARE 文で処理された SELECT 文の使用
PREPARE 文で動的に処理された SELECT 文は簡単には実行できません。こ
れにより 1 行以上のデータが作成される場合があり、データベース・サー
バーは、戻す行が分からずに、エラー・コードを作成します。
6-32 プログラム内の SQL
動的 SQL
その代わり、動的 SELECT 文は、カーソルに付加されます。その後、カー
ソルはオープンされて普通に使用されます。PREPARE 文で処理された文と
共に使用されるカーソルは、その文の名前に応じて宣言されます。次に、
IBM Informix 4GL での例を示します。
LET select_2 = "select order_num, order_date from orders ",
"where customer_num = ? and order_date > ?"
PREPARE q_orders FROM select_2
DECLARE cu_orders CURSOR FOR q_orders
OPEN cu_orders USING q_c_number, q_o_date
FETCH cu_orders INTO f_o_num, f_o_date
次のリストは、この例における処理の段階を識別します。
1. SELECT 文を表している文字列は、プログラム変数に配置されます。こ
れは、2 つの位置指定疑問符 (?) を使用します。
2. PREPARE 文は、文字列を、実行できるデータ構造体に変換します。
データ構造体は、q_orders という名前と関連付けられています。
3. cu_orders という名前のカーソルが宣言され、PREPARE 文で処理された
文の名前と関連付けられます。
4. カーソルがオープンされると、PREPARE 文で処理された文が実行され
ます。OPEN 文の中の USING 節は、元の文の疑問符 (?) の代わりになる
内容を持つ 2 つのホスト変数の名前を提供します。
5. データの最初の行は、オープン・カーソルから取り出されます。FETCH
文の INTO 節は、取り出された列値を受け取るホスト変数を指定します。
この後、カーソルをクローズして再オープンできます。カーソルがクロー
ズされている間、異なる SELECT 文が q_orders という名前で PREPARE 文
で処理されます。この方法で、単一のカーソルを使用して異なる SELECT
文から取り出すことができます。
プログラム内の SQL 6-33
動的 SQL
動的ホスト変数
動的に割り当てられたデータ・オブジェクトがサポートされる埋込み言語
製品では、動的文を 1 ステップ先に進めることができます。また、列デー
タを受け取るホスト変数を動的に割り当てることができます。これにより、
プログラム入力から任意の SELECT 文を取り、作成する値の数とデータ型
を決定し、それらを保留する適切な型のホスト変数を割り当てることがで
きるようになります。
この機能のキーは、DESCRIBE 文です。この文は、PREPARE 文で処理され
た SQL 文の名前を受け取り、その文とその内容についての情報を戻します。
次に、SQLCODE を設定して、文の型、つまり、開始に使用する verb を指定
します。PREPARE 文で処理された文が SELECT または INSERT である場合、
DESCRIBE 文は、選択済み値または挿入済み値についての情報もデータ構造
体に戻します。そのデータ構造体は、この目的で割り当てられた事前定義
のデータ構造体で、システム記述子領域として知られています。
IBM Informix ESQL/C を使用している場合は、データ構造体は sqlda ポイン
ター構造体である可能性があります。
DESCRIBE 文が SELECT 文のために戻したり参照したりするデータ構造体に
は、構造体の配列が含まれます。それぞれの構造体は、選択リスト内の 1
つの項目用に戻されるデータについて説明します。プログラムは、配列を
検証して、データの行に 10 進数値、特定の長さの文字値、および整数が含
まれていることを発見できます。
この情報を使用すると、プログラムは抽出された値を保留するためのメモ
リーを割り当て、使用するデータベース・サーバーのデータ構造体に必要
なポインターを書き込むことができます。
PREPARE 文で処理された文の解放
PREPARE 文で処理された SQL 文は、メモリー内の領域を使用します。い
くつかのデータベース・サーバーを使用すると、プログラムに属する領域
だけでなく、データベース・サーバーによって所有された領域も消費でき
ます。この領域は、プログラムが終了するときに解放されますが、いくつ
かのプログラムではそれより前に解放することができます。
FREE 文を使用すると、この領域を解放できます。これは、文の名前または
文の名前用に宣言されたカーソルの名前のいずれかを受け取って、PREPARE 文で処理された文に割り当てられた領域を解放します。
6-34 プログラム内の SQL
埋込みデータ定義
高速実行
カーソルまたはホスト変数を必要としない単純ステートメントの場合、
PREPARE、EXECUTE、および FREE の文のアクションを単一の操作に結合す
ることができます。EXECUTE IMMEDIATE 文は、文字列を受け取り、1 つの
操作でその文字列を PREPARE 文で処理し、実行して、その記憶域を解放
します。
$
EXECUTE IMMEDIATE "drop index my_temp_index";
これにより、単純な SQL 操作を書き込むことが簡単になります。ただし、
USING 節が使用できないため、EXECUTE IMMEDIATE 文を SELECT 文に使用
することはできません。
埋込みデータ定義
データ定義文、つまり、データベースを作成して表の定義を修正する SQL
文は、通常はプログラムに書き込まれません。この理由は、これらの文は
ほとんど実行されないためです。データベースは一度だけ作成されますが、
何度も問合せが行われて更新されます。
データベースとその表の作成は、DB-Access または IBM Informix SQL を使用
して、一般的に対話式に実行されます。これらのツールは、文のファイル
からも駆動できるので、データベースの作成は 1 つのオペレーティング・
システム・コマンドを使用して実行できます。( これについては、本書の第
10 章で説明しています。)
GRANT 文と REVOKE 文のアクセス権の埋込み
データ定義に関連するタスク、つまりアクセス権の付与と取り消しは反復
して実行されます。この理由は、第 11 章で説明しています。アクセス権は
頻繁に付与されて取り消される必要があるため、また、SQL を熟知してい
ないユーザーによって実行される場合があるため、プログラムに GRANT 文
と REVOKE 文をパッケージして、これらにより簡単でより便利なユー
ザー・インターフェースを与えることが有益である場合があります。
GRANT 文と REVOKE 文は、動的 SQL には特に適した候補です。それぞれの
文には、次の 3 つのパラメーターが必要です。
• 1 つまたは複数のアクセス権のリスト
• 表名
• ユーザー名
プログラム内の SQL 6-35
おそらく、プログラム入力を基にしたこれらの値を ( ユーザー、コマンド
行パラメーター、またはファイルから ) 少なくともいくつか提供する必要
がありますが、どの値もホスト変数のフォームにおいては提供できません。
これらの文の構文は、どのポイントにおいてもホスト変数を許可しません。
唯一の代替策は、文の部分を文字列にアセンブルして、そのアセンブルし
た文を PREPARE 文で処理して実行する方法です。プログラム入力は、文
字として PREPARE 文で処理された文に組み込むことができます。
図 6-9 に、GRANT 文を関数パラメーターからアセンブルして、PREPARE
文で処理して実行する IBM Informix 4GL における関数を示します。
FUNCTION table_grant (priv_to_grant, table_name, user_id)
DEFINE priv_to_grant char(100),
table_name char(20),
user_id char(20),
grant_stmt char(200)
LET grant_stmt = " GRANT ", priv_to_grant,
" ON ", table_name,
" TO ", user_id
WHENEVER ERROR CONTINUE
PREPARE the_grant FROM grant_stmt
IF status = 0 THEN
EXECUTE the_grant
END IF
IF status <> 0 THEN
DISPLAY "Sorry, got error #", status, "attempting:"
DISPLAY " ",grant_stmt
END IF
FREE the_grant
WHENEVER ERROR STOP
END FUNCTION
図 6-9
GRANT 文を作成し、PREPARE 文で処理して実行する 4GL 関数
開始の文では、関数の名前とその 3 つのパラメーターの名前を定義します。
FUNCTION table_grant (priv_to_grant, table_name, user_id)
埋込みデータ定義
DEFINE 文は、それらのパラメーターと関数にローカルな 1 つの追加の値を
定義します。4 つとも、さまざまな長さを持つ文字列です。
DEFINE
priv_to_grant char(100),
table_name char(20),
user_id char(20),
grant_stmt char(200)
変数 grant_stmt は、パラメーターといくつかの定数とを連結させて作成さ
れたアセンブル済みの GRANT 文を保留します。
LET grant_stmt =
"GRANT ", priv_to_grant,
" ON ", table_name,
" TO ", user_id
IBM Informix 4GL では、ストリングを連結させるためにコンマが使用されま
す。この割り当て文は、次の 6 つの文字列を連結します。
•
•
•
•
•
•
“GRANT”
付与されるアクセス権を指定するパラメーター
“ON”
表名を指定するパラメーター
“TO”
ユーザーを指定するパラメーター
結果は、プログラム入力で部分的に構成された完全な GRANT 文です。同じ
ことを、異なる構文を使用して他のホスト言語で果たすことができます。
WHENEVER ERROR CONTINUE
PREPARE the_grant FROM grant_stmt
データベース・サーバーが SQLCODE にエラー・コードを戻すと、
IBM Informix 4GL プログラムのデフォルト・アクションは終了します。ただ
し、ユーザー提供のパーツで構成されている SQL 文を PREPARE 文で処理
する場合はエラーが大変発生しやすく、プログラムの終了はエラーを診断
するには不十分な方法です。上述のコードでは、WHENEVER 文によって終
了が回避されます。次に、PREPARE 文は、アセンブルされた文のテキスト
を構文解析のためにデータベース・サーバーに渡します。
プログラム内の SQL 6-37
サマリー
データベース・サーバーは、文のフォームを承認する場合、ゼロの復帰
コードを設定します。これは、文が正確に実行されることを保証するもの
ではありません。このことは、文が正確な構文を持つということを意味す
るだけです。存在しない表を参照したり、実行中にのみ検出できる他の多
くの種類のエラーが含まれることがあります。
IF status = 0 THEN
EXECUTE the_grant
END IF
準備が正常に終了したら、次のステップでは PREPARE 文で処理された文
を実行します。図 6-9 の残りの関数は、何かの不具合が生じる場合にエ
ラー・メッセージを表示します。書き込まれているとおり、PREPARE 操作
からのエラーと EXECUTE 操作からのエラーとの間に違いはなく、数値のエ
ラー・コードを解釈しようとせずに、ユーザーにその解釈を任せます。
サマリー
SQL 文は、プログラム言語の通常文であるかのようにプログラムに書き込
むことができます。プログラム変数は、WHERE 節で使用することができ、
データベースからのデータをそれらに取り出すことができます。プリプロ
セッサーは、SQL コードをプロシージャー呼出しとデータ構造体に変換し
ます。
データを戻さない文、または 1 行のデータのみを戻す問合せは、言語の通
常の命令ステートメントのように書き込まれます。2 行以上の行を戻すこ
とができる問合せは、データの現行行を表すカーソルと関連付けられてい
ます。カーソルを使用すると、プログラムは必要なときにデータの各行を
取り出すことができます。
静的 SQL 文は、プログラムのテキストに書き込まれます。ただし、プログ
ラムは新規の SQL 文を実行時に動的に形成し、それらの文も実行できます。
多くの拡張されたケースにおいて、プログラムは、問合せが戻す行の番号
と型についての情報を入手し、それらを保留するためのメモリー領域を動
的に割り当てることができます。
6-38 プログラム内の SQL
データを修正するプ
ログラム
概要 3
DELETE の使用方法 3
直接削除 4
直接削除中のエラー 4
トランザクション・ログ機能の使用 5
整合性がある削除 6
カーソルを使用した削除 7
INSERT の使用 8
INSERT カーソルの使用 9
INSERT カーソルの宣言 9
カーソルを使用した挿入 10
PUT および FLUSH の後の状態コード 11
定数行 12
挿入の例 12
UPDATE の使用 15
UPDATE カーソルの使用 16
キーワード UPDATE の目的 17
特定の列の更新 17
必須ではない UPDATE キーワード 17
表のクリーンアップ 18
同時実行性およびロック 18
同時実行性およびパフォーマンス 19
ロックおよび整合性 19
ロックおよびパフォーマンス 19
同時実行性の問題 20
第
7
章
ロックの動作 21
ロックの種類 22
ロック範囲 22
ロックの継続期間 25
修正中のロック 25
排他レベルの設定 26
「単純読込み」排他レベル 27
「確定読込み」排他レベル 27
「カーソル安定性」排他レベル 28
「繰返し可能読込み」排他レベル 29
ロック・モードの設定 30
ロックを待機する 30
ロックを待機しない 31
制限時間まで待機する 31
デッドロックの処理 32
外部デッドロックの処理 32
単純な同時実行性 32
他のデータベース・サーバーを使用したロック 33
読取り中の排他性 34
更新された行のロック 35
HOLD カーソル 35
サマリー 37
7-2 データを修正するプログラム
概要
前章では、SQL 文 ( 特に SELECT 文 ) を他の言語で作成されたプログラムに
挿入する方法について説明しました。これにより、プログラムを使用して
データベースからデータ行を取り出すことができるようになりました。
本章では、行の削除、挿入、または更新によってデータベースを修正する
場合に生じる問題について説明します。本書の第 6 章と同様、本章の目的
は、IBM Informix ESQL または 4GL 製品のマニュアルを理解するための知識
を習得することです。
INSERT、UPDATE、および DELETE 文の一般的な使用方法については、本書
の第 5 章で説明します。本章では、プログラムでのこれらの使用方法につ
いて説明します。これらの文をプログラムに挿入することは非常に簡単で
すが、エラー処理、および複数のプログラムからの同時修正の処理はかな
り困難な作業です。
DELETE の使用方法
プログラムで DELETE 文を実行すると、表から行が削除されます。DELETE
文では、通常の方法で WHERE 節を使用して行を指定することができます。
または、指定されたカーソルで最後に取り出された単一行を参照すること
ができます。
行を削除する場合は、その他の表の行が削除される行に依存しているかど
うかを確認する必要があります。この整合性がある削除については、本書
の第 5 章で説明します。このことは、プログラム内から削除した場合と同
じになります。
データを修正するプログラム 7-3
DELETE の使用方法
直接削除
DELETE 文は、プログラムに埋め込むことができます。次に、IBM Informix
ESQL/C を使用した例を示します。
$ delete from items
where order_num = $onum;
同じ形式の文を準備して、この文を動的に実行することもできます。いず
れの場合でも、文は直接データベースに作用し、1 つ以上の行に影響を与
えます。
上記の例の WHERE 節では、onum というホスト変数の値が使用されていま
す。この操作の実行後、通常どおりに結果が SQLCA でポストされます。
SQLERRD 配列の 3 番目のエレメントには、エラーが発生した場合に削除さ
れた行数が含まれています。SQLCODE 内のこの値は、操作全体が正常に行
われたことを示しています。この値が負でない場合は、エラーは発生しま
せん。SQLERRD の 3 番目のエレメントは、WHERE 節を満たして削除された
全行数です。
直接削除中のエラー
エラーが発生すると、文は実行途中で終了します。SQLCODE 内の負の数お
よび SQLERRD の 2 番目のエレメントはエラーの原因を示し、カウント数は
削除された行数を示します。通常は、これらのエラーによってデータベー
ス・サーバーが操作を開始できなかった場合、カウント数は 0 になります。
例えば、指定された表が存在していないか、または WHERE 節でテストされ
た列の名前が変更されていた場合、削除は行われません。
ただし、エラーの中には、操作を開始していくつかの行が処理された後に
発見されるものがあります。一般的なこれらのエラーとして、ロックの競
合を挙げることができます。データベース・サーバーが行を削除するには、
事前にこの行に対して排他ロックを取得する必要があります。他のプログ
ラムが表の行を使用しているため、データベース・サーバーで行をロック
することができない場合があります。ロックの問題はすべてのタイプの変
更に影響を与えるため、本章の後半の別のセクションで説明します。
頻繁ではありませんが、削除の開始後にエラーが発生する場合があります。
例として、データベースの更新中に発生するハードウェア・エラーを挙げ
ることができます。
7-4 データを修正するプログラム
DELETE の使用方法
トランザクション・ログ機能の使用
修正中に発生するあらゆる種類のエラーに対応するには、トランザクショ
ン・ログ機能を使用します。いかなる種類のエラーが発生した場合でも、
データベース・サーバーに対して、データベースを元に戻すように指示す
ることができます。次に、上記の例を拡張してトランザクションを使用し
ている例を示します。
$ begin work;
$ delete from items
where order_num = $onum;
del_result = sqlca.sqlcode;
del_isamno = sqlca.sqlerrd[1];
del_rowcnt = sqlca.sqlerrd[2];
if (del_result < 0)
$ rollback work;
else
$ commit work;
/* start the transaction*/
/* save two error */
/* ...code numbers */
/* ...and count of rows */
/* some problem, */
/* ...put everything back */
/* everything worked OK, */
/* ...finish transaction */
この例では、トランザクションを終了する前に、プログラムが重要な戻り
コードを SQLCA に保管することが重要なポイントになっています。これ
は、ROLLBACKWORK 文および COMMIT WORK 文のいずれも、SQL 文のよう
に戻りコードを SQLCA 内に設定するためです。エラー発生後に ROLLBACK
WORK 文を実行すると、エラー・コードが消去されます。このため、エ
ラー・コードを保管しない場合には、ユーザーにエラー・コードが報告さ
れないことになります。
トランザクションを使用する利点は、どのような不具合が生じても、デー
タベースを既知の予測可能な状態にしておくことができる点です。修正が
どの程度完了したか ( すべて完了、またはまったく完了していない ) が問題
になることはありません。
データを修正するプログラム 7-5
DELETE の使用方法
整合性がある削除
トランザクション・ログ機能は、複数の表を修正する必要がある場合に特
に役立ちます。例えば、デモンストレーション・データベースから注文を
削除する場合についてを考えます。この単純な形式の問題では、2 つの表
orders および items から、図 7-1 の IBM Informix 4GL の例に示されているよ
うに行を削除する必要があります。
WHENEVER ERROR CONTINUE{do not terminate on error}
BEGIN WORK {start transaction}
DELETE FROM items
WHERE order_num = o_num
IF (status >= 0) THEN{no error on first delete}
DELETE FROM orders
WHERE order_num = o_num
END IF
IF (status >= 0) THEN{no error on either delete}
COMMIT WORK
ELSE
{problem on some delete}
DISPLAY "Error ", status, " deleting."
ROLLBACK WORK
END IF
図 7-1
2 つの表から削除を行う 4GL のコード
このプログラムのロジックは、トランザクションが使用されている場合も
使用されていない場合もほとんど同じです。ただし、トランザクションが
使用されていない場合は、エラー・メッセージを確認して数多くの決定を
する必要が生じます。エラーがいつ発生したかに応じて、状況は次のよう
に異なります。
• 削除が行われなかった : この注文番号を持つすべての行はデータベース
に残っている。
• 一部の項目行は削除されたが、すべて削除されたわけではない:
一部の項目のみを持つ注文レコードは残っている。
• すべての項目行は削除されたが、注文行は残っている。
• すべての行が削除された。
2 番目と 3 番目の場合、データベースはある程度破損しています。データ
ベースに含まれている部分的な情報によって、一部の問合せで誤った解答
が作成される可能性があります。この情報を一貫性のある状態に復元する
場合は、注意が必要です。トランザクションが使用されている場合は、こ
のような不確定性はまったく発生しません。
7-6 データを修正するプログラム
DELETE の使用方法
カーソルを使用した削除
最後に取り出された行を削除するために、カーソルを使用した DELETE 文
を作成することができます。この方法を使用すると、WHERE 節ではテスト
することができない条件に基づいて、削除をプログラミングすることがで
きます。図 7-2 に、この例を示します。
int delDupOrder()
{
$
int ord_num;
int dup_cnt, ret_code;
$
declare scan_ord cursor for
select order_num, order_date
into $ord_num
from orders for update;
$
open scan_ord;
if (sqlca.sqlcode != 0) return (sqlca.sqlcode);
$
begin work;
for(;;)
{
$
fetch next scan_ord;
if (sqlca.sqlcode != 0) break;
dup_cnt = 0; /* default in case of error */
$
select count(*) into dup_cnt from orders
where order_num = $ord_num;
if (dup_cnt > 1)
{
$
delete where current of scan_ord;
if (sqlca.sqlcode != 0) break;
}
}
ret_code = sqlca.sqlcode;
if (ret_code == 100)
/* merely end of data */
$
commit work;
else
/* error on fetch or on delete */
$
rollback work;
return (ret_code);
}
図 7-2
カーソルを使用して削除を行う不確実な ESQL/C 関数 ( 注を参照 )
注 : 図 7-2 に示した ESQL/C 関数の設計は安全ではありません。この関数
は、現行の「排他レベル」( 本章の後半を参照 ) の正しい操作に依存してい
ます。この関数が正しく動作をしている場合でも、この関数による効果は、
表内の行の物理順序に依存することになります。このことは、一般的に得
策ではありません。
データを修正するプログラム 7-7
INSERT の使用
この関数の目的は、重複する注文番号を含む行を削除することです。デモ
ンストレーション・データベースの orders.order_num 列は一意性インデッ
クスを持っているため、行が重複することはありません。ただし、別の
データベース用に類似の関数を作成することは可能です。このデータベー
スでは、普通の列名が使用されています。
この関数では、orders 表のすべての行を走査するためのカーソル scan_ord
が宣言されます。このカーソルは、FOR UPDATE 節が付けられて宣言されま
す。この節は、このカーソルを使用してデータを修正することができるこ
とを示しています。カーソルが正しくオープンすると、この関数はトラン
ザクションを開始し、この表を全行に渡ってループします。この関数は、
各行ごとに埋込み SELECT 文を使用して、現行行の注文番号を格納してい
る行がこの表にいくつあるのかを決定します ( 後のセクションで説明する
ように、正しい排他レベルがない場合、この手順は失敗します )。
この表に一意性インデックスがあるため、デモンストレーション・データ
ベースでは、dup_cnt に戻されるカウント数は常に 1 になります。ただし、
カウント数が 1 よりも大きい場合は、この関数では表の現行行が削除され、
重複のカウント数が 1 だけ小さくなります。
このタイプのクリーンアップ関数が必要となる場合がありますが、これら
クリーンアップ関数では、一般にはさらに高度な設計が必要となります。
この設計では、データベース・サーバーから送信された最後の重複行を除
くすべての重複行が削除されます。この順序は、行の内容または行の意味
とは関係ありません。図 7-2 の関数のカーソル宣言に ORDER BY 節を追加
して、この関数を改良することができます。ただし、ORDER BY と FOR
UPDATE を共に使用することはできません。より優れたアプローチについ
ては、この章の後半で説明します。
INSERT の使用
プログラムには、INSERT 文を埋め込むこともできます。プログラム内での
形式および使用方法については、本書の第 5 章で説明します。VALUES およ
び WHERE の両方の節の式において、ホスト変数を使用することができる機
能が追加されています。また、プログラムには、カーソルを使用して行を
挿入する機能も追加されています。
7-8 データを修正するプログラム
INSERT の使用
INSERT カーソルの使用
DECLARE CURSOR 文には、数多くのバリエーションがあります。これらの
ほとんどは、データに対してさまざまな種類の走査を行うためのカーソル
を作成する場合に使用しますが、あるバリエーションでは、INSERT カーソ
ル と呼ばれる特殊なカーソルが作成されます。PUT 文および FLUSH 文で
INSERT カーソルを使用すると、表に行を効率的に一括挿入することがで
きます。
INSERT カーソルの宣言
INSERT カーソルを作成するには、カーソルに対して、SELECT 文ではなく
FOR INSERT 文であると宣言します。このようなカーソルは、データ行の取
出しには使用できません。行を挿入する場合にのみ使用することができま
す。図 7-3 に、INSERT カーソルの宣言の例を示します。
DEFINE the_company LIKE customer.company,
the_fname LIKE customer.fname,
the_lname LIKE customer.lname
DECLARE new_custs CURSOR FOR
INSERT INTO customer (company, fname, lname)
VALUES (the_company, the_fname, the_lname)
図 7-3
INSERT カーソルを宣言している 4GL のコード
INSERT カーソルを開くと、行ブロックを保持するためのバッファーがメ
モリー内に作成されます。このバッファーは、プログラムがデータ行を作
成すると、これらの行を受け取ります。バッファーがフルの場合、データ
行はブロック単位でデータベース・サーバーに渡されます。これにより、
プログラムとデータベース・サーバーの間の通信量が削減され、データ
ベース・サーバーは容易に行を挿入することができます。この結果、挿入
を高速に行うことができます。
INSERT バッファーの最小サイズは、埋め込まれている SQL のインプリメ
ンテーションに対して設定されています。この最小サイズを制御すること
はできません ( このサイズは一般的には 1 ~ 2 KB です )。バッファーは、
常に少なくとも 2 行分の挿入値を保持するのに十分な大きさになります。
行が最小バッファー・サイズよりも小さい場合、この値は複数行を保持す
るのに十分な大きさです。
データを修正するプログラム 7-9
INSERT の使用
カーソルを使用した挿入
図 7-3 のコードでは、INSERT カーソルを使用するための準備を行ってい
ます。図 7-4 はその続きで、カーソルの使用方法を示します。この例では、
next_cust という名前の関数は、新規のカスタマーに関する情報、または入
力の終わりを通知する NULL データのいずれかを戻すことを想定していま
す。
WHENEVER ERROR CONTINUE{do not terminate on error}
BEGIN WORK
OPEN new_custs
WHILE status = 0
CALL next_cust() RETURNING the_company, the_fname, the_lname
IF the_company IS NULL THEN
EXIT WHILE
END IF
PUT new_custs
END WHILE
IF status = 0 THEN
{no problem in a PUT}
FLUSH new_custs
{write any last rows}
END IF
IF status = 0 THEN
{no problem writing}
COMMIT WORK
{..make it permanent}
ELSE
ROLLBACK WORK
{retract any changes}
END IF
図 7-4
INSERT カーソルを使用するコード ( 図 7-3 の続き )
図 7-4 のコードでは、next_cust が繰り返し呼び出されています。このコー
ドが NULL 以外のデータを戻すと、PUT 文が行バッファーに戻り、データ
を送信します。バッファーがいっぱいになると、このバッファーに含まれ
ている行は自動的にデータベース・サーバーに送信されます。next_cust が
戻すデータがなくなると、ループは正常に終了します。その後、FLUSH 文
を使用して、バッファー内に残っている行がすべて書き込まれ、トランザ
クションが終了します。
図 7-3 の INSERT 文をもう一度調べます。この文は、それ自体はカーソル定
義の一部ではなく、単一行を customer 表に挿入します。実際は、INSERT
カーソルの仕組み全体をこの例のコードから削除し、図 7-4 の現在 PUT 文
がある箇所に、INSERT 文を書き込むことができます。INSERT カーソルを
使用すると、プログラムの実行速度は少し高速になります。
7-10 データを修正するプログラム
INSERT の使用
PUT および FLUSH の後の状態コード
プログラムでは、PUT 文を実行するときに、行がバッファー内に正常に配
置されているかどうかをテストする必要があります。新規の行がバッ
ファー内に正しく配置されている場合は、PUT アクションでのみ行をバッ
ファーにコピーすることができます。この場合、エラーは発生しません。
ただし、行が正しく配置されていない場合は、バッファーの負荷全体が
データベース・サーバーに送信されて挿入されます。この場合は、エラー
が発生する可能性があります。
SQL 通信域に戻された値によって、これらをソートする場合にプログラム
が必要とする情報がプログラムに与えられます。エラーが発生しない場合、
SQLCODE はすべての PUT 文の後に 0 に設定されます。エラーがある場合
は、負のエラー・コードに設定されます。
SQLERRD の 3 番目のエレメントは、実際に表に挿入された行の数に設定さ
れます。新規の行が単にバッファーに移動されただけの場合は、このエレ
メントは 0 に設定されます。バッファーの負荷が挿入されてエラーが発生
しなかった場合は、バッファー内の行のカウント数に設定されます。エ
ラーが発生した場合は、エラーが発生する前に挿入された行のカウント数
に設定されます。
もう一度コード ( 図 7-4) を確認して、SQLCODE がどのように使用されてい
るかを確認します。まず最初に、OPEN 文でエラーが発生した場合、ループ
は実行されず (WHILE 条件が失敗するため )、FLUSH 操作も実行されないた
め、トランザクションはロールバックされます。
次に PUT 文がエラーを戻した場合、ループは終了し (WHILE 条件のため )、
FLUSH 操作は実行されず、トランザクションはロールバックされます。こ
れは、少なくとも一度はループによってバッファーを満たすのに十分な行
が生成された場合にのみ発生します。このような場合以外は、PUT 文では
エラーが発生することはありません。
プログラムがバッファー内に行を残したまま、いずれの行もまったく挿入
せずにループを終えることがあります。この場合は、SQL の状態は 0 にな
り、FLUSH 操作が実行されます。FLUSH 操作によってエラー・コードが生
成された場合、トランザクションはロールバックされます。すべての挿入
が正常に行われた場合にのみ、トランザクションはコミットされます。
データを修正するプログラム 7-11
INSERT の使用
定数行
INSERT カーソル機構では、パフォーマンスを容易に改善できる特殊な
ケースがサポートされています。この場合、INSERT 文でリストされるすべ
ての値は、式やホスト変数ではなく定数 ( 単なるリテラル番号および文字
列 ) になります。この INSERT 操作を何度実行しても、作成される行は同じ
になります。この場合、各同一行をコピー、バッファリング、および転送
する必要はありません。
代わりに、この種の INSERT 操作では、PUT 文はカウンターを増分する以外
は何も行いません。最後に FLUSH 操作が実行されると、行の単一コピー、
および挿入のカウント数がデータベース・サーバーに渡されます。データ
ベース・サーバーは、一度の操作で同じ数の行を作成して挿入します。
数多くの同じ行を挿入することは、一般的な操作ではありません。最初に
データベースを確立したときに大きな表に NULL のデータを取り込む場合、
この操作を行うことができます。
挿入の例
DELETE 文に関する前のセクションでは、表の重複行を探し出し、これを削
除することを目的とした例について説明しました (7-7 ページの『カーソル
を使用した削除』を参照 )。同様の操作をより優れた方法で行うには、不要
な行を削除するのではなく、必要な行を選択します。図 7-5 の
IBM Informix 4GL のコードに、これを行うための 1 つの方法を示します。こ
の例は、SQL プログラミングを容易にするいくつかの機能を使用するため
に、IBM Informix 4GL で作成されています。
7-12 データを修正するプログラム
INSERT の使用
BEGIN WORK
INSERT INTO new_orders
SELECT * FROM ORDERS main
WHERE 1 = (SELECT COUNT(*) FROM ORDERS minor
WHERE main.order_num = minor.order_num)
COMMIT WORK
DEFINE ord_row RECORD LIKE orders,
last_ord LIKE orders.order_num
DECLARE dup_row CURSOR FOR
SELECT * FROM ORDERS main INTO ord_row.*
WHERE 1 < (SELECT COUNT(*) FROM ORDERS minor
WHERE main.order_num = minor.order_num)
ORDER BY order_date
DECLARE ins_row CURSOR FOR
INSERT INTO new_orders VALUES (ord_row.*)
BEGIN WORK
OPEN ins_row
LET last_ord = -1
FOREACH dup_row
IF ord_row.order_num <> last_ord THEN
PUT ins_row
LET last_ord = ord_row.order_num
END IF
END FOREACH
CLOSE ins_row
COMMIT WORK
図 7-5
重複のない表を再作成する 4GL プログラム
この例では、通常の INSERT 文で始まっており、表の重複していない行をす
べて見つけ出し、これらを ( このプログラムの開始前に作成された ) 別の表
に挿入します。これにより、重複行のみが残ります。( デモンストレーショ
ン・データベースの orders 表には一意性インデックスがあり、重複行は含
まれていません。この例では、別のデータベースが使用されています。)
IBM Informix 4GL では、表のような データ構造体を定義することができま
す。この構造体には、表内の列ごとに 1 つのエレメントが自動的に与えら
れます。ord_row 構造体は、表の一行を保持するバッファーです。
図 7-5 のコードでは、2 つのカーソルが宣言されています。最初のカーソ
ルは dup_row と呼ばれ、表内の重複行を戻します。このカーソルは入力専
用で、ORDER BY 節を使用して、重複行の順序を 7-7 ページの図 7-2 で使用
された物理レコードの順序とは異なる順序にすることができます。この例
では、重複行は日付によって ( 最も古い順に ) 並べられていますが、データ
に基き、その他の任意の順序を使用することができます。
データを修正するプログラム 7-13
INSERT の使用
2 番目のカーソルは、INSERT カーソルです。このカーソルは、
IBM Informix 4GL のアスタリスク 表記を使用するように作成されています。
すべてのフィールド を示すアスタリスクを使用すると、レコードを指定す
るだけですべての列に値を提供することができます。
コードの残りの部分では、dup_row で戻される行が検証されます。この部
分では、重複する行の各グループの最初の行が新規の表に挿入され、残り
は無視されています。
この例では、最も単純なエラー処理が使用されています。特に指示がない
限り、IBM Informix 4GL プログラムは、エラー・コードが SQLCODE で設定
されると自動的に終了します。この場合は、アクティブ・トランザクショ
ンもロールバックされます。このプログラムは、この動作に依存していま
す。つまり、このプログラムが最後になると、エラーが発生していないた
めトランザクションをコミットすることができる、と想定されることにな
ります。エラーの発生確率が低く、プログラムが終了したことを知る必要
のない人がこのプログラムを使用している場合は、このエラー処理を容認
することができます。
7-14 データを修正するプログラム
UPDATE の使用
UPDATE の使用
UPDATE 文は、第 5 章で説明した任意の形式でプログラムに埋め込むこと
ができます。また、SET および WHERE のいずれの節においても、式の中に
ホスト変数を指定することができます。また、カーソルで扱われた行をプ
ログラムで更新することもできます。
影響を受ける行数 SQLCODE および SQLERRD
プログラムでカーソルを使用して行を選択する場合は、データの終了
戻りコードの 100 に対して SQLCODE をテストすることができます。こ
れは、照会条件を満たす行が存在しなかったか、またはそれ以上存在
していないことを示すために設定されます。データの終わりコードは、
SELECT 文の後の SQLCODE にのみ設定されます。DELETE、INSERT、ま
たは UPDATE 文の後には使用されません。
データを検出しなかった照会は、成功とは見なされません。ただし、
偶然行を更新または削除しなかっただけの UPDATE 文または DELETE 文
は成功と見なされます。この文は、WHERE 文で指示されている行セッ
トを更新または削除したためです。ただし、セットは空になっていま
す。
同様に、INSERT 文では、挿入された行のソースが SELECT 文であり、
この文で行が選択されなかった場合も、データの終わりコードが設定
されません。INSERT 文では要求された行数 ( つまり 0) が挿入されたた
め、この文は成功と見なされます。
挿入、更新、または削除された行数を見つけるために、プログラムで
は、SQLERRD の 3 番目のエレメントをテストすることができます。
SQLCODE 内の値 (0 または負 ) に関係なく、行のカウント数は行のエレ
メントにあります。
データを修正するプログラム 7-15
UPDATE の使用
UPDATE カーソルの使用
UPDATE カーソル を使用すると、現行行、つまり最新の取出し行を削除ま
たは更新することができます。次に、UPDATE カーソルの宣言の例を示し
ます (IBM Informix ESQL/COBOL)。
EXEC SQL
DECLARE names CURSOR FOR
SELECT fname, lname, company
FROM customer
FOR UPDATE
END-EXEC
このカーソルを使用するプログラムでは、通常の方法で行を取り出すこと
ができます。
EXEC SQL
FETCH names INTO :FNAME, :LNAME, :COMPANY
END-EXEC.
行を変更する必要があると判断した場合、プログラムで変更できます。
IF COMPANY IS EQUAL TO "SONY"
EXEC SQL
UPDATE customer
SET fname = "Midori", lname = "Tokugawa"
WHERE CURRENT OF names
END-EXEC.
WHERE 節では、通常のテスト式の代わりに CURRENT OF names という語
句が使用されています。その他の点では、この UPDATE 文は通常と変わら
ず、表の名前も指定されています。表の名前は、カーソル名では暗黙指定
ですが必須です。
7-16 データを修正するプログラム
UPDATE の使用
キーワード UPDATE の目的
カーソル内のキーワード UPDATE の目的は、プログラムが取り出した行は
プログラムが更新 ( または削除 ) することができることをデータベース・
サーバーに知らせることです。データベース・サーバーは、UPDATE カー
ソルで取り出された行にはより厳しいロックを配置し、UPDATE キーワー
ドで宣言されていないカーソルで行を取り出している場合にはあまり厳し
くないロックを配置します。これにより、通常のカーソル、および多重プ
ロセッシング・システムにおける高度な並行使用の場合はパフォーマンス
が向上します ( ロックおよび並行使用のレベルについては、本章の後半を
参照 )。
特定の列の更新
特定の列を更新するためのカーソルを宣言することができます。次に、こ
の機能を使用できるよう変更した例を示します。
EXEC SQL
DECLARE names CURSOR FOR
SELECT fname, lname, company, phone
INTO :FNAME, :LNAME, :COMPANY, :PHONE FROM customer
FOR UPDATE OF fname, lname
END-EXEC.
このカーソルでは、fname 列および lname 列のみが更新されます。次のよ
うな文は、エラーとして拒否されます。
EXEC SQL
UPDATE customer
SET company = "Siemens"
WHERE CURRENT OF names
END-EXEC.
このプログラムでこのような更新を実行しようとすると、エラー・コード
が戻され、更新は行われません。WHERE CURRENT OF を使用して削除しよ
うとしても、削除によってすべての列が影響を受けるために拒否されます。
必須ではない UPDATE キーワード
ANSI 標準の SQL では、カーソル定義における FOR UPDATE 節が提供されて
いません。プログラムで ANSI 標準準拠のデータベースを使用する場合は、
任意のカーソルを使用して更新または削除を行うことができます。
データを修正するプログラム 7-17
同時実行性およびロック
表のクリーンアップ
最後に、UPDATE カーソルを使用する仮想的な例を示します。この例で
は、確立したデータベースでは発生しないが、アプリケーション設計の初
期フェーズでは発生する可能性のある問題が提示されています。
target という名前の大きな表が作成され、データが取り込まれています。
文字カラム datcol には、いくつかの NULL 値が誤って取り込まれています。
これらの行は削除する必要があります。また、新しい列 serials が (ALTER
TABLE コマンドを使用して ) 表に追加されています。この列には、一意の
整数値を取り込みます。図 7-6 に、これらを行うための IBM Informix ESQL/
C のコードを概略的に示します。
$ char[80] dcol;
$ short int dcolint;
$ int sequence;
$ declare target_row cursor for
select datcol
into $dcol:dcolint
from target
for update of serials;
$ begin work;
$ open target_row;
if (sqlca.sqlcode == 0) $ fetch next target_row;
for(sequence = 1; sqlca.sqlcode == 0; ++sequence)
{
if (dcolint < 0) /* null datcol */
$ delete where current of target_row;
else
$ update target set serials = $sequence
where current of target_row;
}
if (sqlca.sqlcode >= 0) $ commit work;
else $ rollback work;
図 7-6
UPDATE カーソルを使用して手作業で作成された表のクリーンアップ
同時実行性およびロック
データベースが他のマシンとネットワーク接続されていないシングル・
ユーザーのワークステーションに含まれている場合は、プログラムを使用
して自由にデータを修正することができます。ただし、それ以外の場合は、
このプログラムがデータを修正している間に、他のプログラムが同じデー
タを読み取りまたは修正する可能性があることを考慮する必要があります。
このことを同時実行性 と呼び、同じデータを同時に複数のプログラムが別
個に使用することを意味します。
7-18 データを修正するプログラム
同時実行性およびロック
同時実行性およびパフォーマンス
同時実行性は、多重ランチャー・システムにおいて高いパフォーマンスを
実現する場合にきわめて重要です。データへのアクセスがシリアル化 され
ており、一度に 1 つのプログラムでのみデータを使用する場合、処理が非
常に遅くなります。
ロックおよび整合性
同様に、データの使用を制御しない限り、同時実行性によりさまざまなマ
イナス効果が発生する可能性があります。無効なデータをプログラムが読
み取ったり、修正が完了した後にこの修正データが失われる場合がありま
す。
データ・サーバーでは、この種のエラーを回避するために、ロック という
システムが使用されています。ロックとは、プログラムがデータの一部に
置くことができる要求、つまり予約を意味します。データベース・サー
バーでは、データがロックされている限り、他のプログラムによってこの
データが修正されないことが保証されます。別のプログラムがこのデータ
を要求すると、データベース・サーバーは、このプログラムを待機させる
か、またはエラーを発生させてそのプログラムを退けます。
ロックおよびパフォーマンス
ロックでは、データの一部分へのアクセスがシリアル化されるため、同時
実行性が低下します。つまり、データの一部にアクセスしようする他のプ
ログラムは、待機する必要があります。データベース・サーバーがロック
を配置することができるのは、単一行、ディスク・ページ ( 複数の行を保
持 )、表全体、またはデータベース全体に対してです。データベース・サー
バーが配置するロックが多く、ロックするオブジェクトが大きいほど同時
実行性が低下します。ロックが少なくオブジェクトが小さいほど、同時実
行性 ( およびパフォーマンス ) が向上します。
このセクションでは、プログラムが次の 2 つの目標をどう達成するかにつ
いて説明します。
• データの整合性を保証するために必要なロックをすべて配置する
• 上記の目標を実現するために、可能な限り少なくかつ小さなデータ部分
をロックする
データを修正するプログラム 7-19
同時実行性およびロック
同時実行性の問題
同時実行性の危険性を理解するには、個別の速度で動作している複数のプ
ログラムについて考慮する必要があります。次に、その一例を示します。
このプログラムは、次のカーソルを使用して行を取り出しています。
DECLARE sto_curse CURSOR FOR
SELECT * FROM stock
WHERE manu_code = "ANZ"
各行をデータベース・サーバーからプログラムに転送するには時間がかか
ります。転送中、および転送と転送の間に、他のプログラムは別のデータ
ベース操作を実行することができます。問合せで作成された行をこのプロ
グラムが取り出そうとするのとほぼ同時に、別のユーザーのプログラムが
次の更新を実行する場合について考えます。
UPDATE stock
SET unit_price = 1.15 * unit_price
WHERE manu_code = "ANZ"
つまり、いずれのプログラムも同じ表を読み取っており、一方のプログラ
ムはいくつかの行を取り出し、もう一方のプログラムは同じ行を変更して
います。次に何が起こるかについては、次の 4 つの場合を挙げることがで
きます。
1. このプログラムが最初の行を取り出す前に、他方のプログラムがその行
の更新を完了する。
このプログラムは、更新された行のみを表示します。
2. もう一方のプログラムが行を更新する前に、このプログラムがすべての
行を取り出した。
このプログラムは、オリジナルの行のみを表示します。
3. このプログラムがいくつかのオリジナルの行を取り出した後に、もう一
方のプログラムが追いつき、このプログラムがまだ読み取っていないい
くつかの行を更新する。次に、もう一方のプログラムが COMMIT WORK
を実行する。
このプログラムは、オリジナルの行と更新された行を混在させて戻す可
能性があります。
4. 表の更新後、もう一方のプログラムが ROLLBACK WORK を発行する点
を除き、番号 3 と同じ動作をする。
このプログラムは、データベースにはもう存在していないオリジナルの
行と更新された行を混在させて表示する可能性があります。
7-20 データを修正するプログラム
同時実行性およびロック
最初の 2 つの事例は無害です。事例 1 では、このプログラムによる問合せ
が開始される前に更新が完了しています。更新が 1 マイクロ秒前に終了し
ていても、一週間前に終了していても違いはありません。
事例 2 では、このプログラムによる問合せは、実際には更新が開始する前
に完了しています。もう一方のプログラムの作業は、このプログラムより
1 行だけ遅れていたかもしれません。または、明日の夜にならないと開始
されなかったかもしれません。しかし、このことは問題ではありません。
ただし、一部のアプリケーションの設計においては、残りの 2 つの可能性
は非常に重要になるかもしれません。事例 3 では、問合せは更新された
データとオリジナルのデータを混在させて戻します。アプリケーションに
よっては、このことが不利になる場合があります。その他のアプリケー
ション、例えばすべての価格の平均を取るアプリケーションの場合は、
まったく問題にならないかもしれません。
事例 4 では、トランザクションが取り消されたために表内で検出できなく
なったいくつかのデータ行をプログラムが戻した場合、きわめて深刻な結
果となります。
このプログラムがカーソルを使用して最後に取り出した行を更新または削
除する場合は、別の問題が生じます。次の理由のため、結果に誤りが生じ
ることになります。
• このプログラムが行を取り出す。
• もう一方のプログラムがこの行を更新または削除する。
• このプログラムが WHERE CURRENT OF names を更新または削除する。
このような並行イベントは、データベース・サーバーのロックおよび排他
レベル 機能を使用して制御します。
ロックの動作
IBM Informix OnLine データベース・サーバーでは、このセクションで説明
する複雑で柔軟なロック機能のセットがサポートされています。その他の
IBM Informix データベース・サーバーのロック・システムは、これよりも
単純です。
データを修正するプログラム 7-21
同時実行性およびロック
ロックの種類
IBM Informix OnLine では、さまざまな状況で使用する 3 種類のロックがサ
ポートされています。
共有
共有ロックは、オブジェクトを読取り専用として予約しま
す。共有ロックを使用すると、ロックが残っている間はオ
ブジェクトを変更することができなくなります。複数のプ
ログラムは、同一オブジェクトに共有ロックを配置するこ
とができます。
排他的
排他ロックは、単一プログラムを使用するためにオブジェ
クトを予約します。排他ロックは、プログラムがオブジェ
クトを変更することを目的としている場合に使用されま
す。
排他ロックは、その他の種類のロックが存在している場所
には配置することができません。排他ロックが配置されて
いると、その他のロックを同じオブジェクトに配置するこ
とはできません。
増進可能
増進可能なロックは、更新の意図を指定します。このロッ
クは、その他のロックが存在していない場所にのみ配置す
ることができます。ただし、一度配置すると、その他の共
有ロックは、このロックを結合することができます。増進
可能なロックは、後で排他ロックに変更することができま
す。
ロック範囲
ロックは、データベース全体、表全体、ディスク・ページ、単一行、また
は索引キーの値に適用することができます。ロックされるオブジェクトの
サイズは、ロックの範囲 と呼ばれます ( ロック範囲 と呼ばれることもあり
ます )。一般的には、ロックの範囲が大きくなると、同時実行性が低下して
プログラミングが簡単になります。
データベース・ロック
データベース全体をロックすることができます。データベースをオープン
しようとすると、このデータベースの名前に共有ロックが配置されます。
データベースは DATABASE 文または CREATE DATABASE 文でオープンされ
ます。プログラムがデータベースをオープンしている限り、このデータ
ベースの名前に対する共有ロックによって、他のプログラムはデータベー
スを削除したり、データベースに排他ロックをかけることができなくなり
ます。
7-22 データを修正するプログラム
同時実行性およびロック
データベース全体を排他的にロックするには、次の文を使用します。
DATABASE < データベース名 > EXCLUSIVE
このデータベースをオープンしたプログラムが他にない場合には、この文
は成功します。ロックが配置されると、読取りが目的の場合でも、他のい
ずれのプログラムもこのデータベースをオープンすることができません
( データベース名に共有ロックを配置しようとすると失敗するため )。
データベース・ロックは、データベースがクローズされるときに解放され
ます。このことは、CLOSE DATABASE 文を使用して明示的に行うか、また
は別の DATABASE 文を実行して暗黙的に行うことができます。
データベースをロックすると、このデータベースにおける同時実行性がゼ
ロになるため、プログラミングが非常に簡単になります。同時実行性の影
響を受けることはありません。ただし、他のプログラムがアクセスを必要
としていない場合にのみ、データベースをロックするようにします。デー
タベース・ロックは、オフピーク時にデータに大量の変更を加える前に、
頻繁に使用されます。
表ロック
表全体をロックすることができます。これは、自動的に行われる場合があ
ります。IBM Informix OnLine は、次の文のいずれかを実行している間は、
常に表全体をロックします。
•
•
•
•
•
•
ALTER INDEX
ALTER TABLE
CREATE INDEX
DROP INDEX
RENAME COLUMN
RENAME TABLE
文が完了すると ( またはトランザクションが終了すると )、ロックが解放さ
れます。このセクションの後半で説明するように、いくつかの問合せ中に
表全体を自動的にロックすることもできます。
LOCK TABLE 文を使用すると、表全体を明示的にロックすることができま
す。この文を使用すると、表全体に共有ロックまたは排他ロックのいずれ
かを配置することができます。
共有の表ロックを使用すると、プログラムがその表を読み取っている間は、
その表を同時に更新することができなくなります。IBM Informix OnLine は、
次のセクションで説明するように、排他レベルを設定することによって、
データを修正するプログラム 7-23
同時実行性およびロック
同程度の保護を実現します。これにより、同時実行性をより大きくするこ
とができます。ただし、すべての IBM Informix データベースでは、LOCK
TABLE 文がサポートされています。
排他的な表ロックを使用すると、表を同時に使用することができなくなり
ます。他のプログラムがその表を使用するために競合している場合は、パ
フォーマンスに重大な影響を与えます。排他的な表ロックは、排他的な
データベース・ロックのように、オフピーク時に大量の更新が適用される
場合によく使用されます。例えば、アプリケーションによっては、ピーク
時間帯の間は表を更新しないものがあります。その代わり、更新日誌 に更
新を書き込みます。オフピークの時間帯に、その更新日誌が読み取られ、
すべての更新がバッチで適用されます。
ページ・ロック、行ロック、およびキーロック
ロックすることができる最小のオブジェクトは、表の 1 行です。あるプロ
グラムが 1 行または選択した複数行をロックしている場合でも、他のプロ
グラムは同じ表の他の行を操作することができます。
IBM Informix OnLine は、ディスク・ページ ( このディスク・ストレージ方式
については、本書の第 10 章を参照 ) と呼ばれる単位でデータを保管しま
す。1 ディスク・ページに 1 行以上の行が含まれています。場合によって
は、ディスク・ページ上の個々の行をロックするよりは、ディスク・ペー
ジをロックした方がよいことがあります。
行によるロックまたはページによるロックのいずれを選択するかは、表の
作成時にその表に対して設定されます。IBM Informix OnLine では、ページ・
ロックまたは行ロックのいずれかを指定するための LOCK MODE 節がサ
ポートされています。ロック・モードは CREATE TABLE 文で指定し、
ALTER TABLE を使用して後に変更することができます。( 他の IBM Informix
データベース・サーバーでは、いずれか一方を選択することはできません。
ページまたは行のいずれかのインプリメンテーションが優れた方でロック
します。)
ページ・ロックおよび行ロックは同じように使用されます。IBM Informix
OnLine は、行をロックする必要が生じると、行自体をロックするか、また
はその行があるページをロックします。いずれをロックするかは、表に対
して指定されているロック・モードによって異なります。
データベース・サーバーは、存在していない行をロックする必要がある場
合があります。実際には、その行が存在している場合にその行が配置され
る場所をロックします。データベース・サーバーは、索引キーの値にロッ
クを配置することによってこれを行います。キーロックは、行ロックと同
じように使用されます。表が行ロックを使用している場合、キーロックは
仮想的な行に対するロックとして実装されます。表がページ・ロックを使
7-24 データを修正するプログラム
同時実行性およびロック
用している場合、キーロックはそのキーを含むインデックス・ページか、
またはそのキーが存在しているときにそのキーを含むインデックス・ペー
ジにキーロックが配置されます。
ロックの継続期間
プログラムは、データベース・ロックの継続期間を制御します。データ
ベース・ロックは、データベースがクローズされてロックが解放されるま
で残ります。
表ロックの継続期間は、データベースがトランザクションを使用している
かどうかによって異なります。データベースがトランザクションを使用し
ていない場合 ( トランザクション・ログが存在しておらず、COMMIT WORK
文が使用されていない場合 )、テーブル・ロックは、UNLOCK TABLE 文が実
行されてロックが削除されるまで残ります。
表、行、およびインデックスに対するロックの継続期間は、どのような
SQL 文が使用されているか、またはトランザクションが使用中であるかど
うかによって異なります。
トランザクションが使用されている場合は、トランザクションが終了する
と、すべての表、行、ページ、およびインデックスに対するロックが解放
されます。このことは重要です。トランザクションが終了すると、すべて
のロックは解放されます。
修正中のロック
データベース・サーバーは、UPDATE カーソルで行を取り出すと、取り出
した行に対して増進ロックを配置します。このことが正常に行われると、
データベース・サーバーは、他のプログラムはその行に対して変更を加え
ることができないことを認識します。増進可能なロックは排他的ではない
ため、他のプログラムは、その行の読み取りを続行することができます。
このことは、パフォーマンスの向上に役立ちます。この理由は、行を取り
出したプログラムが、UPDATE 文または DELETE 文を発行するのに少し時間
がかかったり、または単に次の行を取り出すだけであったりする可能性が
あるためです。
行を修正する必要が生じると、データベース・サーバーは、その行に対し
て排他ロックを取得します。その行がすでに増進可能なロックを持ってい
る場合、データベースはその行を排他的な状況に変更します。
データを修正するプログラム 7-25
同時実行性およびロック
排他的行ロックの継続時間は、トランザクションが使用中かどうかによっ
て異なります。トランザクションが使用されていない場合は、修正された
行がディスクに書き込まれると、ロックはすぐに解放されます。トランザ
クションが使用中の場合は、トランザクションが終了するまで、このよう
なロックはすべて保持されます。これにより、他のプログラムでは、オリ
ジナルの状態にロールバックされる可能性のある行が使用できなくなりま
す。
トランザクションが使用中の場合は、行が削除されると必ずキーロックが
使用されます。これにより、次のエラーが回避されます。
• プログラム A が行を削除する。
• プログラム B が同じキーを持つ行を挿入する。
• プログラム A がそのトランザクションをロールバックし、強制的にデー
タベース・サーバーに削除された行をリストアさせる。この場合、B に
よって挿入された行はどうなるでしょうか。
インデックスをロックすると、データベース・サーバーは、最初のプログ
ラムがトランザクションをコミットするまで 2 番目のプログラムが行を挿
入しないようにします。
読取り中に配置されたロックは、現行の排他レベル ( 次のトピックを参照 )
によって制御されます。
排他レベルの設定
排他レベル とは、プログラムが他のプログラムの並行動作から分離されて
いる度合いを示すものです。IBM Informix OnLine では、4 つの排他レベルか
ら 1 つを選択することができます。これらの排他レベルは、プログラムが
読取り中にどのようなロックを使用するかについて異なる規則を設定する
ことによって実装されています。
排他レベルを設定するには、SET ISOLATION LEVEL コマンドを使用します。
すべてのデータベース・サーバーがこのコマンドをサポートしているわけ
ではないため、プログラムでこのコマンドを実行する前に、データベー
ス・サーバーがこのコマンドをサポートしているかどうかをテストしてく
ださい。
簡単にテストするには、この文を実行して、戻りコードを無視するか、ま
たは戻りコードをテストしてどのデータベース・サーバーが使用中である
かを確認します ( エラー・コード 513 の場合は、「文はこのデータベース・
サーバーでは使用できません」というメッセージが表示されます )。
7-26 データを修正するプログラム
同時実行性およびロック
「単純読込み」排他レベル
最も単純な排他レベルは「単純読込み」ですが、これには実質的にはまっ
たく排他性がありません。プログラムでは、行が取り出されてもロックが
配置されず、何も考慮されません。プログラムは、他のプログラムの動作
にかかわらず、単にデータベースから行をコピーします。
プログラムは常に完全なデータ行を受け取ります。「単純読込み」排他レベ
ルの下でも、更新された列および更新されていない列がある行は受け取り
ません。ただし、「単純読込み」排他レベルを使用しているプログラムは、
更新プログラムがトランザクションを終了する前に、更新された行を読み
取る場合があります。後に更新プログラムがトランザクションをロール
バックすると、読み取りプログラムは、実際には存在しないデータを処理
します (7-20 ページの同時実行性の問題のリストの事例 4)。
単純読込みは、最も効率的なレベルです。読取りプログラムは待機せず、
他のプログラムを待機させることもありません。次のいずれかの場合は、
単純読込みが推奨レベルです。
• すべての表が静的である。つまり、並行プログラムは単にデータを読み
取るだけで変更を行わない。
• データベースが排他ロック状態に保持されている。
• データベースを使用しているのは 1 つのプログラムのみであることが明
白である。
「確定読込み」排他レベル
プログラムが「確定読込み」排他レベルを要求した場合は、IBM Informix
OnLine では、プログラムがデータベースにコミットされていない行を戻さ
ないことが保証されます。これにより、7-20 ページの同時実行性の問題の
リストの事例 4 の状況 ( コミットされずにロールバックされたデータの読
取り ) は回避されます。
確定読込みのインプリメンテーションは非常に単純です。行を取り出す前
に、データベース・サーバーは、更新プロセスが行にロックを配置したか
どうかを判断するためのテストを実行します。ロックを配置していなかっ
た場合は、その行を戻します。更新されているがコミットされていない行
にはロックが配置されているため、このテストによって、コミットされて
いないデータをプログラムが読み取ることがないことが保証されます。
確定読込みは、取り出された行にはロックを配置しません。このため、効
率は単純読込みとほとんど同じになります。確定読込みは、データの各行
が独立した単位として処理され、同じ表または別の表の他の行を参照して
いない場合に使用するのに適しています。
データを修正するプログラム 7-27
同時実行性およびロック
「カーソル安定性」排他レベル
次のレベルは、カーソル安定性と呼ばれます。この排他レベルが有効な場
合、データベース・サーバーは、最後に取り出された行にロックを配置し
ます。データベース・サーバーが配置するのは、通常カーソルの場合は共
有ロック、UPDATE カーソルの場合は増進可能なロックになります。一度
にロックされるのは 1 つの行のみです。つまり、1 つの行が取り出されるご
とに、直前の行に対するロックは解放されます ( ただし、これは行が更新
済みでない場合に限られます。更新済みの場合は、ロックはトランザク
ションが終了するまで保持されます )。
カーソル安定性によって、プログラムが行を調べている間は、その行は変
更されないことが保証されます。これは、この行から読み取ったデータに
基づいてプログラムが他の表を更新する場合に重要となります。カーソル
安定性によって、プログラムに対して更新が現行情報に基づいていること
が保証されます。プログラムによって失効したデータ が使用されることを
防ぐことができます。
次に、この点に関連する例を示します。デモンストレーション・データ
ベースの観点から見ると、プログラム A は、製造者 Hero に対して新規在庫
品目を挿入しようとしています。同時に、プログラム B は、製造者 Hero と
これに関連付けられているすべての在庫を削除しようとしています。次の
ようなイベントのシーケンスが発生する可能性があります。
1. プログラム A はカーソル安定性の下で動作しており、製造者コードを認
識するために、manufact 表の Hero 行を取り出す。これにより、その行
に共有ロックが配置されます。
2. プログラム B は、DELETE 文を行に対して発行する。この行には共有
ロックがあるため、データベース・サーバーは、このプログラムを待機
させます。
3. プログラム A は、manufact 表から取得した製造者コードを使用して、
stock 表に新規の行を挿入する。
4. プログラム A は、manufact 表のカーソルをクローズし ( またはその表の
別の行を読み取り )、そのロックを解放する。
5. プログラム B は、待機から解放されるとその行の削除を完了し、プログ
ラム A が挿入したばかりの行など、製造者コード HRO を使用している
stock の行の削除を続行する。
プログラム A がより低い排他レベルを使用していた場合は、次のシーケン
スが発生していた可能性があります。
1. プログラム A は、製造者コードを認識するために、manufact 表の Hero
行を読み取る。ロックは配置されません。
2. プログラム B は、DELETE 文をその行に対して発行する。正常に完了し
ます。
7-28 データを修正するプログラム
同時実行性およびロック
3. プログラム B は、製造者コード HRO を使用している stock のすべての行
を削除する。
4. プログラム B が終了する。
5. プログラム A は、Hero 行のコピーが現時点で無効になっていることを
認識していないため、製造者コード HRO を使用して、stock に新規の行
を挿入する。
6. プログラム A が終了する。
最後に、manufact 内の製造者コードと一致しない行が stock に残ります。
また、プログラム B には明らかにバグがあります。このプログラムは、削
除することになっていた行を削除していません。「カーソル安定性」排他レ
ベルを使用すると、これらの影響を回避することができます。
( 前のシナリオを変更して、カーソル安定性を使用している場合でも前のシ
ナリオが失敗するように変更することができます。プログラム A と逆の
シーケンスでプログラム B が表を操作するようにする必要があります。プ
ログラム B が、manufact の行を削除する前に stock から削除すると、いず
れの排他レベルでもエラーを回避することはできません。この種類のエ
ラーが発生する場合は、関係するすべてのプログラムが同じアクセス・
シーケンスを使用することが重要となります。)
カーソル安定性では一度に 1 つの行のみがロックされるため、同時実行性
は、表ロックやデータベース・ロックの場合よりも小さくなります。
「繰返し可能読込み」排他レベル
「繰返し可能読込み」排他レベルは、データベース・サーバーに対して、プ
ログラムが取り出すすべての行がロックを配置するように要求します。配
置されるロックは、通常カーソルの場合は共有ロック、UPDATE カーソル
の場合は増進可能ロックになります。これらのロックは、行が取り出され
ると一度に 1 つずつ配置されます。ロックは、カーソルがクローズされる
か、またはトランザクションが終了するまで解放されません。
繰返し可能読込みでは、スクロール・カーソルを使用するプログラムは選
択された行を複数回読み取ることができ、読取りと読取りの間でこれらの
行が修正または削除されないことが保証されます ( スクロール・カーソル
については、本書の第 6 章を参照 )。これよりも低い排他レベルでは、行が
2 回目に読み取られた場合、これらの行がまだ存在し、変更されないこと
は保証されていません。
データを修正するプログラム 7-29
同時実行性およびロック
「繰返し可能読込み」排他レベルは、最も多くのロックを配置し、これらを
最も長く保持します。このため、「繰返し可能読込み」排他レベルは、同時
実行性が最も低下するレベルとなります。プログラムでこの排他レベルを
使用する場合は、このレベルが配置するロックの数、これらのロックが保
持されている時間、および他のプログラムに与える可能性のある影響につ
いて注意深く検討する必要があります。
同時実行性に対する影響以外に、ロックの数が多いことが問題になる可能
性があります。データベース・サーバーでは、サービスしているすべての
プログラムに対しては、決まった数のロックのみが記録されます。表が
いっぱいになると、データベース・サーバーはロックを配置できなくなり、
エラー・コードを戻します。IBM Informix OnLine システムの管理者はロッ
ク表をモニターすることができるため、使用頻度が高い時期を通知するこ
とができます。
ANSI 標準準拠データベースでは、繰返し可能読込みが自動的に排他レベル
になります。ANSI 標準の SQL に従った操作の振る舞いを保証するには、繰
返し可能読込みが必要となります。
ロック・モードの設定
ロック・モードによって、プログラムがロックされたデータを検出したと
きの動作が決定されます。プログラムがロックされた行を取り出そうとす
ると、次に示す 3 つの内の 1 つが発生します。
• プログラムには、データベース・サーバーから即時に SQLCODE でエ
ラー・コードが戻される。
• ロックを配置したプログラムによってそのロックが削除されるまで、プ
ログラムは一時停止する。
• プログラムはしばらくの間一時停止し、ロックが削除されない場合は、
データベース・サーバーからエラーの戻りコードを受け取る。
これらの結果から選択するには、SET LOCK MODE コマンドを使用します。
ロックを待機する
待機する場合は ( 多くのアプリケーションではこれが最善の選択です )、以
下のコマンドを実行してください。
SET LOCK MODE TO WAIT
7-30 データを修正するプログラム
同時実行性およびロック
このロック・モードが設定されると、プログラムは、通常、他の並行プロ
グラムの存在を無視します。プログラムが別のプログラムによってロック
された行にアクセスする必要がある場合、ロックが削除されるまでプログ
ラムは待機し、その後続行します。この遅延は、通常、きわめて小さなも
のです。
ロックを待機しない
ロックを待機する場合の欠点は、待機時間が非常に長くなる可能性がある
という点です ( ただし、適切に設計されているアプリケーションでは、
ロックの保持時間は非常に短くなります )。遅延時間が長くなる可能性を許
容することができない場合は、プログラムで次のコマンドを実行します。
SET LOCK MODE TO NOT WAIT
ロックされた行を要求すると、このプログラムは即時にエラー・コード
( 例えば、エラー 107 「行はロックされています」) を受け取り、現行の
SQL 文が終了します。プログラムは、現行トランザクションをロールバッ
クして再試行するかどうかを決定します。
プログラムの始動時の初期設定は、非待機です。SQL を対話式に使用して
おり、ロックに関連するエラーが表示された場合は、ロック・モードを待
機に設定してください。プログラムを作成する場合は、このロック・モー
ドをプログラムが最初に実行する組込み SQL コマンドの 1 つにしてくださ
い。
制限時間まで待機する
IBM Informix OnLine を使用している場合は、追加の選択肢があります。
データベース・サーバーに対して待機時間の制限を設定するよう要求する
ことができます。次のコマンドを実行します。
SET LOCK MODE TO WAIT 17
これにより、いずれの待機時間に対しても、17 秒という制限が設定されま
す。ロックがこの時間内に削除されない場合は、エラー・コードが戻され
ます。
データを修正するプログラム 7-31
同時実行性およびロック
デッドロックの処理
デッドロック とは、2 つのプログラムが互いにもう一方の進行をブロック
している状況のことです。プログラムは、もう一方のプログラムがアクセ
スしようとしているオブジェクトに対するロックを保持しています。デッ
ドロックは、関連するすべてのプログラムでそれぞれのロック・モードが
待機に設定されている場合に発生します。
IBM Informix OnLine は、プログラムが単一のネットワーク・サーバー上の
データのみを要求すると、即時にデッドロックを検出します。IBM Informix Online は、ロックを要求している 2 番目のプログラムにエラー・コード
( エラー 143「ISAM エラー : デッドロックが発見されました」) を戻すこと
によって、エラーを回避します。このエラー・コードは、プログラムが
ロック・モードを非待機に設定している場合に受け取るコードです。この
ため、プログラムがロック・モードを待機に設定している場合にロックに
関連したエラー・コードを受け取ったときは、デッドロックが発生する可
能性があることになります。
外部デッドロックの処理
デッドロックは、異なるデータベース・サーバーにあるプログラムの間で
も発生する場合があります。この場合、IBM Informix OnLine は、デッド
ロックを直ちに検出することができません ( 完全なデッドロック検出を行
うには、ネットワークのすべてのデータベース・サーバーの間に大量の通
信トラフィックがある必要があります )。その代わりに、各データベース・
サーバーは、プログラムが別のデータベース・サーバー上のデータに対す
るロックを取得するまでの待機時間に制限を設定します。この時間が期限
切れになると、データベース・サーバーは、その原因がデッドロックであ
ると判断して、ロック関連のエラー・コードを戻します。
つまり、外部データベースが関係している場合は、すべてのプログラムは
ロック待機時間を最大にして実行されます。この最大値はデータベース・
サーバーに対して設定されます。そのデータベース・サーバーをインス
トールした人が、この最大値を変更することができます。
単純な同時実行性
ロックおよび同時実行性に関していずれを選択すればよいか分からないが、
アプリケーションの構造が単純な場合は、プログラムの開始時に、次のコマ
ンドをプログラムに実行させてください ( 最初の DATABASE 文の直後 )。
SET LOCK MODE TO WAIT
SET ISOLATION TO REPEATABLE READ
7-32 データを修正するプログラム
同時実行性およびロック
両方の文からの戻りコードは無視します。他のプログラムは存在していな
いものとして続行します。パフォーマンスに問題が発生しない場合は、こ
のセクションを読み直す必要はありません。
他のデータベース・サーバーを使用したロック
IBM Informix OnLine では、それ自体のロックが管理され、前述のトピック
で説明したさまざまな種類のロックおよび排他レベルが提供されています。
他の IBM Informix データベース・サーバーでは、ホストのオペレーティン
グ・システムの機能を使用してロックが実装されているため、同様の機能
は提供されていません。
ホストのオペレーティング・システムには、オペレーティング・システム
のサービスとしてロック機能を提供しているものもあります。これらのシ
ステムにおいて、データベース・サーバーでは、SET LOCK MODE 文がサ
ポートされています。
ホストのオペレーティング・システムの中には、カーネル・ロック 機能を
備えていないものがあります。これらのシステムにおいて、データベー
ス・サーバーでは、データベース・ディレクトリーに作成される小さな
ファイルに基づき、それ自体のロックが実行されます ( これらのファイル
には、.lok という接尾辞が付いています )。
SET LOCK MODE 文を実行してエラー・コードをテストすると、データベー
ス・サーバーが稼働しているシステムの種類を知ることができます。以下
の IBM Informix ESQL/C のコードに、例を示します。
#define LOCK_ONLINE 1
#define LOCK_KERNEL 2
#define LOCK_FILES 3
int which_locks()
{
int locktype;
locktype = LOCK_FILES;
$
set lock mode to wait 30;
if (sqlca.sqlcode == 0) locktype = LOCK_ONLINE;
else
{
$
set lock mode to wait;
if (sqlca.sqlcode == 0) locktype = LOCK_KERNEL;
}
$
set lock mode to not wait; /* restore default condition */
return(locktype);
}
データを修正するプログラム 7-33
データベース・サーバーで SET LOCK MODE 文がサポートされていない場
合、プログラムは常に NOT WAIT ( 非待機 ) モードになっています。つま
り、別のプログラムでロックされた行をロックしようとすると、プログラ
ムは即時にエラー・コードを受け取ります。
読取り中の排他性
IBM Informix OnLine 以外の IBM Informix データベース・サーバーは、通常、
行を取り出しているときにはロックを配置しません。
「カーソル安定性」排
他レベルを実装する場合に IBM Informix OnLine で使用されている共有ロッ
クと比較できるものはありません。
単一行 SELECT 文を使用するか、または FOR UPDATE が宣言されていない
カーソルで行を取り出すと、終了していないトランザクションでロックさ
れていたか、または修正されていたかにかかわらず、その行は即時に取り
出されます。
この設計では最も優れたパフォーマンスを引き出すことができますが ( 特
にディスク・ファイルに書き込むことによってロックが実装されている場
合 )、コミットされていないトランザクションによって修正された行をプロ
グラムが読み取ることができる点に注意する必要があります。
カーソルを FOR UPDATE と宣言し、入力用にこのカーソルを使用すると、
「カーソル安定性」排他レベルの効果を得ることができます。データベー
ス・サーバーは、UPDATE カーソルで行を取り出すと、取り出した行に対
してロックを配置します ( 行がすでにロックされている場合は、ロック・
モードに応じて、プログラムは待機するかエラーを受け取ります )。プログ
ラムが現行行を更新せずに別の行を取り出すと、現行行のロックが解放さ
れ、新規の行がロックされます。
このため、UPDATE カーソルを使用している限り、UPDATE カーソルによ
る取出しによって、取り出された行がロックされていることが保証されま
す ( この行は失効 しません )。また、コミットされたデータのみが取り出さ
れることが保証されます。更新された行に対するロックは、トランザク
ションの終了まで保持されます。ホストのオペレーティング・システムお
よびデータベース・サーバーに応じて、UPDATE カーソルをこのように使
用した場合、パフォーマンス上の影響が出る場合があります。
HOLD カーソル
更新された行のロック
カーソルが FOR UPDATE と宣言されている場合、ロックは次のように処理
されます。行は、取り出される前にロックされます。また、ロックできな
い場合には、プログラムは待機させられるか、またはエラーが戻されます。
次の取出しが要求されたときに、データベース・サーバーでは、(UPDATE
または DELETE を WHERE CURRENT OF と共に使用して ) 現行行が修正され
たかどうか、またはトランザクションが進行中であるかどうかが監視され
ます。これらのうちいずれも当てはまる場合は、行に対するロックは保持
されます。このような場合以外、ロックは解放されます。
このため、トランザクション内で更新を実行すると、更新されたすべての
行は、トランザクションが終了するまでロックされ続けます。更新されな
かった行は、行が現行である間のみロックされます。トランザクションの
外部で更新された行、またはトランザクション・ログ機能を使用していな
いデータベースで更新された行は、別の行が取り出されるとすぐにアン
ロックされます。
HOLD カーソル
トランザクション・ログ機能が使用された場合、データベース・サーバー
では、トランザクションで実行されたものは終了時にすべてロールバック
できることが保証されます。これを確実に保証するために、データベー
ス・サーバーでは、通常、次のルールが適用されています。
• すべてのカーソルは、トランザクションの終了時にクローズされる。
• すべてのロックは、トランザクションの終了時に解放される。
データを修正するプログラム 7-35
HOLD カーソル
これらのルールは、トランザクションがサポートされているすべてのデー
タベースでは標準で備わっており、ほとんどのアプリケーションではこれ
らのルールで問題が発生することはありません。ただし、トランザクショ
ンが使用されていないときにトランザクションが追加されると、このトラ
ンザクションが実際的ではなくなるプログラム設計があります。図 7-7 の
疑似コードに、この設計の概要を示します。
DECLARE master CURSOR FOR ...
DECLARE detail CURSOR FOR ... FOR UPDATE
OPEN master
LOOP:
FETCH master INTO ...
IF (the fetched data is appropriate) THEN
BEGIN WORK
OPEN detail USING data read from master
FETCH detail ...
UPDATE ... WHERE CURRENT OF detail
COMMIT WORK
END IF
END LOOP
CLOSE MASTER
図 7-7
データベース・アプリケーションの 1 つの共通形式である概略疑似コード
この設計では、1 つのカーソルを使用して表を走査しています。選択され
たレコードは、異なる表を更新するための基本として使用されます。問題
は、( 図 7-7 の概略擬似コードのように ) 各更新が個別のトランザクション
として処理された場合、UPDATE の後の COMMIT WORK 文によって、主
カーソルを含むすべてのカーソルがクローズされる点です。
これに代わる最も簡単な方法は、COMMIT WORK 文および BEGIN WORK 文
をそれぞれ最後と最初の文になるよう移動させることです。これにより、
主表に対する全体走査が 1 つの大きなトランザクションとなります。この
方法が可能な場合もありますが、更新する必要のある行が非常に多い場合、
これは現実的な方法ではありません。ロック数が多くなりすぎ、プログラ
ムを実行している間にロックが保持されることになる場合があります。
IBM Informix データベース・サーバーでは、主カーソルの宣言にキーワー
ド WITH HOLD を追加するという解決策がサポートされています。このよう
なカーソルを HOLD カーソル と呼びます。このカーソルでは、トランザク
ションが終了してもクローズされません。データベースは他のすべての
カーソルをクローズしてすべてのロックを解放し、HOLD カーソルは明示
的にクローズされるまでオープンのままになります。
7-36 データを修正するプログラム
サマリー
HOLD カーソルを使用する前に、ここで説明したロック機構について理解
しているかどうか、および並行して実行されているプログラムについて理
解しているかどうかを確認する必要があります。これは、COMMIT WORK
が実行されると、HOLD カーソルで取り出された行に配置されているロッ
クを含むすべてのロックが解放されるためです。
表の前方走査を行うためにカーソルを使用している場合は、Hold カーソル
が重要になることはほとんどありません。ただし、UPDATE カーソルおよ
びスクロール・カーソルなどの任意のカーソルに対して WITH HOLD を指定
することは可能です。この指定を行う前に、( 表全体に対するロックなど
の ) すべてのロックがトランザクションの終了時に解放されることについ
て理解する必要があります。
サマリー
第 5 章で説明したように、プログラムは INSERT 文、DELETE 文、および
UPDATE 文を実行することができます。また、プログラムは、カーソルを
使用して表を走査し、選択した行を更新または削除することもできます。
さらに、カーソルを使用して行を挿入することもできます。この場合、行
がバッファーに挿入され、ブロックでデータベース・サーバーに送信され
るという利点があります。
これらのすべての動作において、プログラムは、エラーを検出して、エ
ラーが発生した場合にはデータベースを既知の状態に戻します。このこと
を実現するための最も重要なツールが、トランザクションです。トランザ
クション・ログ機能がない場合は、プログラムがエラーから回復すること
が難しくなります。
複数のプログラムが並行して 1 つのデータベースにアクセスする場合 ( こ
れらのプログラムの中の少なくとも 1 つがデータを変更することができる
場合 )、すべてのプログラムでは、データを読み取っている間に別のプログ
ラムがそのデータを変更してしまう可能性について考慮する必要がありま
す。データベース・サーバーは、ロックおよび排他レベルの機構を備えて
います。これらの機構を使用すると、プログラムは、通常、それぞれが単
独でデータを操作しているように実行することができます。
データを修正するプログラム 7-37
サマリー
7-38 データを修正するプログラム
データ・モデルの作
成
概要 3
データ・モデルを作成する理由 3
拡張された関係分析 3
基本的な考え方 6
表、行、列 6
主キー 7
候補キー 7
外部キー ( 結合列 ) 8
手順 1: エンティティーの命名 8
エンティティー・キー 9
ユーザー割当てキー 10
複合キー 10
システム割当てキー 10
時間依存キー 10
エンティティー表 11
住所録の例 11
手順 2: 関係の定義 14
関係の発見 14
表への関係の追加 19
手順 3: 属性のリスト化 22
属性の選択 22
属性表の選択 22
サマリー 24
第
8
章
8-2 データ・モデルの作成
概要
データベースを作成する最初の手順は、データ・モデル ( 格納するデータ
の正確で完全な定義 ) を作成することです。この章では、データ・モデル
を作成するメソッドの 1 つについて簡単に説明します。この後の章では、
設計したデータ・モデルを実装する方法について説明します。
データ・モデルを作成する理由
データ・モデル は、格納するデータを正確かつ完全に定義したものです。
すでに直感的なデータ・モデルを構想している場合でも、正式な表記タイ
プを使用してこのモデルを完成させる必要があります。データ・モデルを
作成すると、設計時に次の 2 つの利点があります。
• データ・モデルを通して、完全に検討できる。
通常、観念的なモデルには未調査の前提が含まれていますが、設計を形
式化することにより、これらの前提を明らかにすることができます。
• 設計を他のユーザーに伝えることが簡単になる。
正式な文によってモデルが明示されるため、他のユーザーは同じ形式で
コメントおよび提案を戻すことができます。
拡張された関係分析
データのモデリングのメソッドは、マニュアルごとに異なります。ほとん
どのモデルは、完全かつ正確に作成する必要があります。すでにいくつか
のメソッドを学習している場合は、そのメソッドを使用してください。
この章では、Relational Systems Corporation が開発したモデリングのメソッ
ドである拡張された関係分析 のサマリーを示します。このモデリングのメ
ソッドは、次の 3 つの手順で実行されます。
1. データベースが記述するエンティティー ( 基本オブジェクト ) を識別し
ます。
2. エンティティー間の関係を識別します。
データ・モデルの作成 8-3
データ・モデルを作成する理由
3. エンティティーおよび関係に関連付けられた属性 ( 固有の特徴 ) を識別
します。
第 9 章では、各属性のドメイン ( データ型 ) を指定する 4 番目の手順につい
て説明します。
モデリングによって最終的に得られるのは、図 8-8 に示すような、個人住
所録に関する最終的な一連の表です。この章では、個人住所録を例として
作成します。個人住所録はサイズが小さく 1 つの章内で完成でき、しかも
そのメソッド全体を示すことができるため、ここでは stores5 データベース
でなく個人住所録を使用します。
8-4 データ・モデルの作成
データ・モデルを作成する理由
Name
NameString
AddressCode
PK UA
FK
BirthDate
Gaius C. Caesar
SPQR, S.A.
1001
1020
17-03-1990
(null)
Street
City
StaProv
Postcode
2430 Tasso St. #8
411 Bohannon Drive
St. Louis
Lenaxa
CA
Abta.
83267-1048
TW2 5AQ
VceNumber
OperFrom
OperTill
0800
1730
0400
1900
Address
AddressCode
PK SA
1001
1020
Voice
VceNumber
VceType
PK UA
1-800-274-8184
011-49-89-922-030
home
car
Fax
FaxNumber
AddressCode
PK UA
FK
FK
926-6741
61-62-435-143
1001
1020
926-6300
(null)
NameFax
NameVce
NameString
FaxNumber
NameString
VceNumber
PK FK
PK FK
PK FK
PK FK
Gaius C. Caesar
SPQR, S.A.
926-6741
61-62-435-143
Gaius C. Caesar
SPQR, S.A.
1-800-274-8184
011-49-89-922-030
B300
Modem
MdmNumber
NameString
VceNumber
AddressCode
PK UA
FK NN
FK
FK
416-566-7024
33 1 42 70 67 74
Nite Owl BBS
CompuServe
926-6300
(null)
1001
1020
図 8-1
Y
Y
B1200
Y
Y
B2400
N
Y
個人住所録のデータ・モデル
データ・モデルの作成 8-5
基本的な考え方
基本的な考え方
拡張された関係分析を含むほとんどの関係型データ・モデルのメソッドで
は、次の考え方が基本となります。
表、行、列
ユーザーはすでに行 および列 で構成される表 について理解している必要が
あります。ただし、正式なデータ・モデルの表を定義する場合は、4 つの
ルールを考慮する必要があります。
• 行はスタンドアロンである必要がある。
表の各行は独立しており、同じ表の別の行に依存しません。したがっ
て、表内の行の順序は、データ・モデルでは重要でありません。表のす
べての行をランダムな順序に並べ替えても、データ・モデルは正常に機
能します。
データベースを実装した後に行を特定の順序で格納して効率性を高める
ようにデータベース・サーバーに指示できますが、これにより、デー
タ・モデルが影響を受けることはありません。
• 行は一意である必要がある。
すべての行に、一意の値を格納しなければならない列があります。この
プロパティーが設定されている列がない場合は、特定の列グループの値
が、全体として、行ごとに異なっている必要があります。
• 列はスタンドアロンである必要がある。
データ・モデルでは、表内の列の順序に意味はありません。表のすべて
の列を並べ替えても、データ・モデルは正常に機能する必要があります。
実装されたデータベースでは、列の最終的な順序は、すべての列 とい
う意味のアスタリスクを使用するプログラムおよび保管問合せに影響し
ますが、データ・モデルには影響しません。
• 列値は分割不可能である必要がある。
列には単一値のみを格納でき、リストまたはグループの繰り返しを格納
することはできません。複合値は個別の列に分割する必要があります。
例えば、個人の姓および名を個別の値として処理する必要がある場合
は、これらの値を単一の名前 列でなく、個別の列に格納する必要があ
ります。
これまで配列または順次ファイルとして編成されたデータしか扱った経験
がない場合は、これらのルールは不自然に思われるかもしれません。ただ
し、リレーショナル・データベース理論では、次のルールに従う表、行、
および列のみを使用して、すべてのタイプのデータを表すことができます。
ほんの少し練習するだけで、ルールを自動的に適用できるようになります。
8-6 データ・モデルの作成
基本的な考え方
主キー
表の主キー は、行ごとに値が異なる列です。行ごとに値が異なるため、各
行は一意になります。このような列がない場合は、複数の列 ( 行ごとに値
の組が異なる列 ) が主キーとなります。
データ・モデルの各表には主キーが必要です。このルールは、すべての行
が一意でなければならないというルールから自動的に導き出されます。必
要な場合は、すべての列をまとめたものが主キーになります。
主キーの列では、NULL 値が許可されません。NULL 値は比較できません。
つまり、同一であるか、または異なっているかを判別できません。した
がって、NULL 値を持つ行が他の行に対して一意になることはありません。
NULL 値が許可されている列は、主キーに含めることができません。
図 8-8 表のように、表の主キー列には注釈 PK というフラグが立てられます。
Modem
MdmNumber
PK UA
416-566-7024
33 1 42 70 67 74
PK という注釈は、主キー (Primary Key) の意味です。注釈 UA は、ユーザー
割当て (User Assigned) の意味です。つまり、この主キーの値は実際の値で
あり、システムによって割り当てられたコードではありません ( システム
割り当てキーには、SA というフラグが立てられます )。
候補キー
複数の列または列のグループが主キーとなる場合があります。このような
列または列グループを候補キーといいます。候補キーを選択する場合は、
表の主キーとなる列数が最小になるようにしてください。
一意であるという候補キーの特性により、SELECT 処理の結果が予測可能に
なるため、すべての候補キーに注意する必要があります。候補キーの列を
選択した場合は、結果に重複行が含まれなくなります。このため、場合に
よっては、戻される行数を予測することができます。これは、選択された
候補キーを主キーとする表が作成されるということです。
表の図の CK のように、候補キー列にフラグを立てることもできます。
データ・モデルの作成 8-7
手順 1:エンティティーの命名
外部キー ( 結合列 )
外部キー は、他の表の主キーと一致する値を含む、1 つの表内の特定の列
または列のグループにすぎません。外部キーは表を結合するために使用さ
れます。実際、このマニュアルですでに参照している結合列 のほとんど
は、外部キー列です。図 8-8 に示されているように、モデル表内の外部
キー列には FK というフラグが設定されます。
Fax
FaxNumber
AddressCode
VceNumber
PK UA
FK
FK
926-6741
61-62-435-143
1001
1020
926-6300
(null)
モデル内に外部キーが存在する場合は、表から行を削除する機能が制限さ
れるため、外部キーには注意する必要があります。行を安全に削除するに
は、外部キーを通して、その行を参照しているすべての行を削除する必要
があります。このようにしないと、データベースは矛盾した状態になりま
す。行内の外部キー値が、存在しないデータを参照することもあります。
このような矛盾が発生した場合、つまり、特定の表の外部キー値がどの主
キーとも一致しない場合は、参照整合性 に違反しています。常に参照整合
性を保持するには、すべての外部キー行を削除してから、これらの行を参
照している主キーを削除します。データベースに参照制約が設定されてい
る場合、外部キーと一致する主キーを削除する操作は、データベース自体
によって禁止されます。また、既存の主キー値を参照しない外部キー値を
追加することもできません。モデルを実装するときに参照制約を使用する
方法については、第 9 章を参照してください。
手順 1:エンティティーの命名
エンティティー は、人物、場所など、データベースに記録される情報のタ
イプです。データ・モデルを言語に例えると、エンティティーは名詞に当
たります。
モデリングの最初の手順は、記録するエンティティーを選択することです。
各エンティティーは、モデル内の表になります。
8-8 データ・モデルの作成
手順 1:エンティティーの命名
複数のエンティティーをすぐにリストできるかもしれません。ただし、他
のユーザーがデータベースを使用する場合は、データベースに格納する必
要がある基本的な情報 の種類をユーザーが理解できるように、調査する必
要があります。
エンティティーのリストが複雑に見える場合は、各エンティティーが次の
特質を保持するようにして、エンティティー・リストを整理します。
• 有効である。
データベース・ユーザーにとって重要な、手間と経費をかけてコン
ピューターで作表するだけの価値があるエンティティーのみをリストし
ます。
• 一般的である。
個々のインスタンスでなく、情報のタイプのみをリストします。例え
ば、シンフォニー はエンティティーですが、ベートーベンの第 5 番 は
インスタンスです。
• 基本的である。
説明するために他の情報を必要としない、独立して存在するエンティ
ティーのみをリストします。特質、特徴、説明と呼ばれるものは、エン
ティティーでなく、単なる属性です。例えば、部品番号 は、基本的な
部品 エンティティーがなければ、意味を持ちません。同様に、他のエ
ンティティーから導出できる情報 ( 例えば、SELECT 式で計算できる合
計、平均、その他の値 ) は、リストしないでください。
• 分割できない。
名前を付けた各エンティティーが、それぞれ独自の特徴を持つサブカテ
ゴリーに分割できない、単一のクラスを表すようにしてください。住所
録モデルの計画では (8-11 ページの 『住所録の例』を参照 )、電話番号
という一見単純なエンティティーは、それぞれ異なる特徴を持つ 3 つの
カテゴリーで構成されます。
これらの選択作業は、単純でなく、自動実行できません。最適なエンティ
ティーを発見するには、格納するデータの本質について深く考察する必要
があります。この作業は、正式なデータ・モデルを作成するために重要で
す。
エンティティー・キー
選択した各エンティティーは、データ・モデル内の表として表されます。
表はエンティティーを抽象的な概念として表しますが、各行はエンティ
ティーに関する特定の個々のインスタンス を表します。例えば、カスタ
マー がエンティティーである場合、カスタマー表はカスタマーの概念を表
し、各行は特定のカスタマーを表します。
データ・モデルの作成 8-9
手順 1:エンティティーの命名
エンティティーは表であり、各表には主キーが必要です。したがって、次
に行う作業は、各エンティティーに主キーを指定することです。つまり、
各インスタンスを区別するエンティティーの限定的な特性を指定する必要
があります。
ユーザー割当てキー
一部のエンティティーには、カタログ・コードや ID 番号など、モデル外部
で定義された既製の主キーが設定されています。これらはユーザー割り当
てキーであり、モデル内では UA というフラグが立てられています。
複合キー
他のエンティティーには、必ず一意であるという特徴がありません。異な
る人物の名前が同一である場合、および異なる書籍のタイトルが同一であ
る場合があります。通常は、複数の特徴を組み合わせて一意性を実現でき
ます ( 名前が同じ人物が同じ住所に住んでいる場合や異なる書籍のタイト
ル、作者、出版日が同じであることは、ほとんどありません )。
システム割当てキー
システムにより割り当てられた主キーは、通常、複合キーよりも適してい
ます。システム割当てキーは、最初にデータベースに入力したときに、エ
ンティティーの各インスタンスに付加される番号またはコードです。実装
されるシステム割当てキーの中で最も簡単なものは、データベース・サー
バーが自動生成できるシリアル番号です。ただし、データベースを使用す
るユーザーによっては、平易な数値コードを好まない場合があります。そ
の場合には、実データに基づく他のコードを使用できます。例えば、従業
員の ID コードは、従業員のイニシャルと雇用日を表す数字を、組み合わせ
て作成できます。
時間依存キー
エンティティー・キーによっては、本質的に複雑であったり、外部キーを
含んでいる場合があります。両方のタイプのキーは、通常、データに時間
が関係する場合に必要となります。例えば、クライアントに請求できる時
間を表す請求可能時間 が重要なエンティティーになることがあります。法
律事務所や結婚コンサルタントは、アドバイザーやクライアント などのエ
ンティティーを使用する場合もあります。アドバイザーがクライアントと
面談すると、請求可能時間のインスタンスが発生します。
8-10 データ・モデルの作成
手順 1:エンティティーの命名
請求可能時間エンティティーには、エンティティーを一意にするために、
少なくとも次の 3 つの情報が必要です。
• アドバイザーの ID
( アドバイザー ・エンティティーを参照する外部キー )
• 日付
• サービスの開始時刻
エンティティー表
主キーを決定したら、決定事項を図に記録します。エンティティーごとに、
図 8-2 のように表のコーナーを描き、エンティティー名および選択した主
キー列を記入します。
エンティティー ( および表 ) 名
Name
NameString
PK UA
Gaius C. Caesar
SPQR, S.A.
列名
フラグ :
PK ( 主キー )
FK ( 外部キー )
SA ( システム割り当て )
UA ( ユーザー割り当て )
NN (NULL を許可しない )
具体的な値
図 8-2
エンティティー表の図
住所録の例
個人住所録を管理するデータベースを作成するとします。データベース・
モデルには、ユーザーが業務で処理する個人および企業の名前、住所、電
話番号を記録する必要があります。
最初の手順はエンティティーを定義することですが、まず住所録のページ
をよく調べて、そこに存在するエンティティーを把握する必要がある場合
があります ( 図 8-3 を参照 )。
データ・モデルの作成 8-11
手順 1:エンティティーの命名
図 8-3
住所録のページ
既存データの物理的なフォームによって、誤解が生じる可能性があります。
住所録のページおよびエントリーのレイアウトに引きずられて、住所録の
特定のエントリーを表すエンティティー ( 名前、番号、住所のフィールド
を含む特定の種類のアルファベット順のレコード ) を指定しないでくださ
い。このエンティティーはモデル化のメソッドでなく、データです。
一見したところ、住所録に記録される基本的なデータ・エンティティーは、
次のとおりです。
• 名前 ( 個人および企業 )
• 住所
• 電話番号
これらのデータ・エンティティーは上述の基準を満たすでしょうか。明ら
かに、これらはモデルにとって重要であり、一般的です。
これらは基本的でしょうか。確認するためのよい方法は、エンティティー
の値を他のエンティティーと無関係に変更できるかどうかを調べることで
す。このことについて検討した後で、住所録に電話番号や現住所が記載さ
8-12 データ・モデルの作成
手順 1:エンティティーの命名
れていない ( 引っ越したか、または 転職した ) 人物が記されていることに
注意します。住所録に記載されている住所および電話番号には、複数の個
人で共有されているものもあります。これら 3 つのエンティティーはすべ
て、独立して値が変化するため、他に依存しない基本データとして強く推
奨されます。
これらは分割できるでしょうか。名前は個人名と企業名に分割できます。
このことについて検討した後で、このモデルのすべての名前に同じ特徴を
持たせることにします。つまり、企業と個人に関して、異なる情報を記録
しないことにします。同様に、1 種類の住所のみが存在するようにします。
勤務先住所と自宅住所を別個に扱う必要はありません。
ただし、電話番号は 1 種類でなく 3 種類あることにも注意してください。
人間が応答する電話番号、FAX 装置につながる FAX 番号、およびコン
ピューターに接続されるモデム 番号があります。番号の種類ごとに異なる
情報を記録する必要があるため、これらの 3 つは異なるエンティティーに
なります。
主キーを選択した後で、モデルの表を表す図は図 8-4 のようになります。
図 8-4
Name
Address
NameString
AddressCode
PK UA
PK SA
Gaius C. Caesar
SPQR, S.A.
1001
1020
Voice
Fax
Modem
VceNumber
FaxNumber
MdmNumber
PK UA
PK UA
PK UA
1-800-274-8184
011-49-89-922-030
926-6741
61-62-435-143
416-566-7024
33 1 42 70 67 74
主キーを選択した後の住所録モデルの表
この図には重要な決定事項がいくつか反映されています。最初に、個人ま
たは組織の名前が主キー ( ユーザー割当て ) として使用されています。2 つ
の企業または個人が同じ名前を持つ可能性がある場合には、これらを主
キーに設定できません。この例では、名前の重複は問題でない、またはミ
ドル・ネームや役職を追加して一意にできると想定しています。
データ・モデルの作成 8-13
手順 2:関係の定義
電話番号もユーザー割当て主キーとして示されています。ただし、住所を
一意にするためには、主キーに市町村、番地などのすべての情報を含める
必要があるため、住所にはシステム割当ての主キーを指定します。これに
より、キーは非常に複雑になります。設計の後半では、住所の要素は個別
の属性 ( 列 ) として処理する必要があるため、住所は複合キーでもありま
す。
手順 2:関係の定義
これで、モデルにはエンティティーが記録されますが、エンティティー間
の関係は記録されません。関係は常に明らかなわけではありませんが、記
録する価値のある関係は、すべて見つけ出す必要があります。すべての関
係を確実に見つけ出す唯一の方法は、すべての可能な関係を完全にリスト
することです。エンティティー A および B のすべてのペアについて検討し、
“A と B の関係は何であるか ” を調べる必要があります。
関係の発見
関係を発見する最も簡単な方法は、行と列にすべてのエンティティーの名
前を記入したマトリックスを作成することです。図 8-5 は、個人住所録の
エンティティーを反映したマトリックスです。
name
address
number
(voice)
name
address
number
(voice)
number
(fax)
number
(modem)
図 8-5
個人住所録のエンティティーを反映したマトリックス
8-14 データ・モデルの作成
number
(fax)
number
(modem)
手順 2:関係の定義
行の下側の三角形 ( 網掛け領域 ) は無視できます。対角線上のセルを検討す
る必要があります。つまり、“A と他の A の間の関係が何であるか ” を調べ
る必要があります。このモデルでは、常に関係ありません。名前と名前の
間、または住所と住所の間には、少なくともこのモデルに記録する価値の
ある関係はありません。
明らかに関係がないすべてのセルについて、このマトリックス内に none と
記入します。これで、マトリックスは図 8-6 のようになります。
name
name
address
number
(voice)
address
number
(voice)
number
(modem)
none
none
none
number
(fax)
number
(modem)
図 8-6
number
(fax)
none
none
none
エンティティー間に関係のないマトリックス
このモデルではエンティティー間に関係がありませんが、他のモデルでは
関係がある場合があります。一般的な例として、他の従業員のマネー
ジャーである従業員などを挙げることができます。また、製造現場では、
部品エンティティーが別の部品で構成されている例があります。
このマトリックスに反映されるもう 1 つの決定事項は、FAX 番号とモデム
番号の間に関係がないことです。
残りのセルには、行のエンティティーと列のエンティティーの間に存在す
る関係を記入します。次の 3 つの関係が考えられます。
• 1 対 1 (1:1 と記述 )。1 つのエンティティー B に対してエンティティー A
が複数存在したり、1 つのエンティティー A に対してのエンティティー
B が複数存在することはありません。
• 1 対多 (1:n と記述 )。複数のエンティティー A は存在しませんが、関連先
のエンティティー B が複数存在することがあります ( またはその逆 )。
データ・モデルの作成 8-15
手順 2:関係の定義
• 多対多 (m:n と記述 )。1 つの B に関連するエンティティー A が複数存在
したり、1 つの A に関連するエンティティー B が複数存在することがあ
ります。
1 対多の関係が最も一般的ですが、住所録モデルには、3 つの関係がすべて
使用されます。
図 8-6 にあるように、未記入の最初のセルは、名前と住所の間の関係を表
します。この関係のタイプは何でしょうか。名前 ( ユーザーが決定 ) には住
所を 0 個または 1 個指定できますが、複数指定することはできません。次
の図のように、name の横、address の下に、0-1 と記入します。
name
name
none
address
0-1
ただし、住所には、複数の名前を関連付けることができます。例えば、1
つの企業に勤務する複数の個人や、同じ住所に居住する複数の個人を知っ
ている場合があるとします。
住所に名前を 関連付けない ことはできるでしょうか。つまり、名前で使用
されない住所が存在することは可能でしょうか。ここでは、可能であると
します。次の図のように、address の下、name の横に、0-n と記入します。
name
name
none
address
0-1
0-n
少なくとも 1 つの名前に関連付けられていない住所は存在できないと決め
た場合は、0-n の代わりに 1-n を記入します。
いずれかの側の関係が 1 に制限されている場合は、1:n の関係になります。
名前と住所の間の関係は 1:n です。0 が可能であるため、関係を表の列とし
て符号化する場合には、NULL を許可する必要があります。
8-16 データ・モデルの作成
手順 2:関係の定義
ここで、次のセル ( 名前と電話番号の関係 ) について検討します。名前に関
連付けることができる電話番号の個数は、1 でしょうか、または複数で
しょうか。住所録を少し調べると、多忙な営業マンについては、自宅、事
務所、携帯電話、自動車電話など、個人の電話番号が複数記入されている
ことがあります。ただし、電話番号が関連付けられていない名前が存在す
る場合もあります。次の図のように、name の横、number (voice) の下に、
0-n と記入します。
name
name
none
address
0-1
0-n
number
(voice)
0-n
この関係の反対側はどうでしょうか。1 つの電話番号に、いくつの名前を
関連付けることができるでしょうか。もちろん、複数の名前を関連付ける
ことができます。住所録では、1 つの企業に複数の個人が対応している場合
があり、この場合、着信コールの番号は 1 つです。電話番号に名前を関連
付けないことはできるでしょうか。ここではできないとします。知人が使
用する電話番号でない限り、記録しても無駄です。number (voice) の下、
name の横に、1-m と記入します ( このセルに記入されている n と異なる 1
より大きな値を表すには、m を使用します )。
name
name
none
address
0-1
0-n
number
(voice)
0-n
1-m
これは、多対多 (m:n) の関係です。1 方の側では 0 が許可されないため、列
定義に変換して考えた場合、NULL が許可されません。
同様にして、マトリックスの残りのセルに記入します ( 図 8-7 を参照 )。
データ・モデルの作成 8-17
手順 2:関係の定義
name
name
address
none
address
0-1
0-n
none
number
(voice)
number
(voice)
0-n
1-m
none
none
number
(fax)
number
(modem)
図 8-7
number
(fax)
0-n
0-n
0-1
none
1-m
0-1
0-1
number
(modem)
1
0-n
0-n
0-1
none
none
none
完成した住所録用マトリックス
図 8-7 には、次の決定事項反映されています。
• 1 つの名前に複数の FAX 番号を関連付けることができます。例えば、1
つの企業に複数の FAX 装置を設定することができます。別の言い方を
すると、1 つの FAX 番号に複数の名前を関連付けることができます。
例えば、複数の個人が同じ FAX 番号を使用することもできます。
• 1 つのモデム番号には、ただ 1 つの名前のみを関連付ける必要がありま
す ( この任意の指示により、この例は複雑になります。このことは、設
計上の要件であると見なします )。ただし、1 つの名前に複数のモデム
番号を関連付けることができます。例えば、企業のコンピューターに複
数のダイヤルアップ回線を接続することができます。
• 実際の電話番号と住所の間には何らかの関係がありますが、このモデル
では記録する必要がありません。name を介して、間接的な関係がすで
に存在しています。
• 特定の住所に、複数のモデムまたは FAX が存在する場合があります。
一方、特定のモデムまたは FAX に 1 つの住所が対応し、住所が不明の
モデムまたは FAX が存在する場合があります。
• 1 つの電話機に 1 つの FAX 電話を関連付けたり、その逆を行うことがで
きます。この関係には、FAX 装置のオペレーター用に、音声回線が引
いてある場合が多いという事実が反映されています。
8-18 データ・モデルの作成
手順 2:関係の定義
これらの決定事項の一部に異論がある場合もあります ( 例えば、電話番号
とモデム番号の関係がなぜサポートされていないかなど )。異論がある場合
には、それに従ってマトリックスおよび表を改訂します。
表への関係の追加
すべての関係を発見したら、それらを新しい列および表の形式で記録しま
す。
1:n の関係を記録するには、エンティティーを表す表の 1 つに、新しい列を
挿入します。関連先のエンティティーがただ 1 つ であるエンティティー側
の表に、列を追加します。新しい列には、他のエンティティーの外部キー
が格納されます。例えば、次の図において、名前とモデム番号の間の 1:n
の関係を考えます。
number
(modem)
name
0-n
1
1 つの名前には n 個のモデムを関連付けることができますが、1 つのモデム
番号には名前が 1 つしか関連付けられません。したがって、新しい列を
modem 表に追加し、name 表への外部キーを格納します ( 次の図を参照 )。
Name
Modem
NameString
MdmNumber
Namestring
PK UA
PK UA
FK NN
Gaius C. Caesar
SPQR, S.A.
416-566-7024
33 1 42 70 67 74
Nite Owl BBS
CompuServe
フラグ NN (NULL を許可しない ) は、モデムを名前に関連付ける必要があ
ることを示します。モデムを名前に関連付けないことができる場合は、NN
フラグが省略され、表のこの列に NULL 値が許可されます。
データ・モデルの作成 8-19
手順 2:関係の定義
電話番号と FAX 番号の関係のような 1:1 の関係は、一方のエンティティー
の表に外部キー列を追加し、その列をもう一方のエンティティーにリンク
することにより、1:n の関係と同様に処理されます。1:1 の関係がある場合
は、いずれかの表に外部キーを設定できます。表で使用される領域を最小
化するには、行数が少ないと予測される表に外部キーを設定します。
エンティティー表に列を追加して、m:n の関係を記録することはできませ
ん。この関係には独自の表が必要です。例えば、1 つの名前に複数の FAX
番号を設定したり、1 つの FAX 番号に複数の名前を設定することができる
とします。この場合、この関係を 2 列の表として、モデルに追加する必要
があります。各列は、関連するエンティティーのいずれかに対応する外部
キーです。
Name
Fax
NameString
FaxNumber
PK UA
PK UA
Gaius C. Caesar
SPQR, S.A.
926-6741
61-62-435-143
NameFax
NameString
FaxNumber
PK FK NN
PK FK NN
Gaius C. Caesar
SPQR, S.A.
926-6741
61-62-435-143
主キーは両方の列で構成されます。各列は主キーの一部であるため、
NULL 値が許可されません。この点を強調するために、NN フラグが指定さ
れています。
ここまでのモデル全体を図 8-8 に示します。このマトリックスから、すべ
ての関係を読み取ってください。
8-20 データ・モデルの作成
手順 2:関係の定義
Name
NameString
AddressCode
PK
FK
Gaius C. Caesar
SPQR, S.A.
1001
1020
Address
AddressCode
PK SA
1001
1020
Voice
VceNumber
PK UA
1-800-274-8184
011-49-89-922-030
Fax
FaxNumber
AddressCode
VceNumber
PK UA
FK
FK
926-6741
61-62-435-143
1001
1020
926-6300
(null)
NameFax
NameVce
NameString
FaxNumber
NameString
VceNumber
PK FK
PK FK
PK FK
PK FK
Gaius C. Caesar
SPQR, S.A.
926-6741
61-62-435-143
Gaius C. Caesar
SPQR, S.A.
1-800-274-8184
011-49-89-922-030
Modem
MdmNumber
NameString
VceNumber
AddressCode
PK UA
FK NN
FK
FK
416-566-7024
33 1 42 70 67 74
Nite Owl BBS
CompuServe
926-6300
(null)
1001
1020
図 8-8
エンティティー間の関係が定義されたデータ・モデル
データ・モデルの作成 8-21
手順 3:属性のリスト化
手順 3:属性のリスト化
すべてのエンティティーおよび関係が見つかっている場合、モデルには設
定可能なすべての表が格納されています。ただし、エンティティーには、
属性 ( 特性、特質、量、または特徴 ) があります。これらの属性は、新しい
列としてモデルに追加されます。
属性の選択
属性を選択する場合は、次の特質を持つ属性を選択します。
• 有効である。
データベースのユーザーにとって重要である属性のみを追加します。
• 導出的でなく、直接的である。
既存の属性から ( 例えば、SELECT 文の式から ) 導出できる属性は、モデ
ルに追加しないでください。導出データが存在すると、データベースの
管理が大幅に複雑になります。
設計の後の段階で ( 第 10 章を参照 )、導出属性を追加してパフォーマン
スを改善する方法について検討しますが、ここではこれらの属性は除外
してください。
属性表の選択
正しい表に各属性を設定する必要もあります。属性を表に設定できるのは、
属性の値が表の主キー列および候補キー列の値にのみ依存する場合に限定
されます。
属性の値が列に依存する ということは、列の値が変化した場合に、属性の
値も変化する必要があるということです。属性は列の関数になります。次
に、この点についてより詳細に説明します。
• 表に 1 列の主キーがある場合、属性はこのキーに依存する必要がありま
す。
• 表に複合主キーがある場合、属性はこの中の 1 つまた一部の列ではな
く、すべての列に ( 全体として ) 依存する必要があります。
• 属性が他の列にも依存する場合は、これらの列は候補キー列、つまり各
行で一意である列です。
上記のルールに従っている場合、モデルの表はリレーショナル・データ
ベースを考案した E.F. Codd が名付けた第 3 正規形 になります。表が第 3 正
規形でない場合、モデル内に冗長データが存在するか、または表を更新し
ようとすると問題が発生します。
8-22 データ・モデルの作成
手順 3:属性のリスト化
上記のルールに従う属性を設定できない場合、通常は、次に示すエラーの
いずれかが該当しています。
•
•
•
•
属性が適切に定義されていない。
属性が直接的でなく、導出的である。
属性が実際はエンティティーまたは関係である。
一部のエンティティーまたは関係がモデルに含まれていない。
この章の冒頭にある 図 8-1 の表を作成するために、次の属性が住所録モデ
ルに追加されました。
•
address エンティティーに番地、市町村、都道府県、郵便番号が追加さ
れました。
• name エンティティーに誕生日が追加されました。
• 自動車電話、家庭電話、事務所電話を区別するために、voice エンティ
ティーにタイプが追加されました。
• fax エンティティーに FAX 装置の在席操作時間が追加されました。
• modem エンティティーに、300、1200、2400 ボー・レートのサポートの
有無が追加されました。
データ・モデルの作成 8-23
サマリー
サマリー
この章では、拡張された関係分析ですでに説明した、データ・モデリング
に関する次の 3 つの手順の概要について説明しました。
1. 記録するエンティティーをリストして、次の点を確認します。
•
•
•
•
有効である
一般的である
基本的である
分割できない
次に、主キーを識別して、各エンティティーを表に図示します。
2. エンティティーの各ペアの関係を完全にリストして、次のように分類し
ます。
•
•
•
•
関係なし
1対1
1 対多
多対多
次に、エンティティー表に列を追加して各関係を記録します ( 多対多の
関係の場合は、2 列の表を新規に追加します )。
3. 表に新規列を追加して、エンティティーまたは関係に関する重要な属性
を記録します。
プロセスが正常に終了したら、データのあらゆる面を一度だけでなく何度
も調べる必要があります。
8-24 データ・モデルの作成
モデルの実装
概要 3
ドメインの定義 3
データ型 4
データ型の選択 4
10 進数 (NUMERIC) 型 7
日時順のデータ型 12
文字 (CHARACTER) 型 16
データ型の変更 20
デフォルト値 21
チェック制約 21
ドメインの指定 22
データベースの作成 24
CREATE DATABASE の使用方法 24
IBM Informix OnLine での
CREATE DATABASE の使用方法 24
他の IBM Informix データベース・サーバーでの
CREATE DATABASE の使用方法 26
CREATE TABLE の使用方法 28
コマンド・スクリプトの使用方法 30
スキーマのキャプチャー 30
ファイルの実行 30
サンプル 30
表の構築 31
サマリー 32
第
9
章
9-2 モデルの実装
概要
データ・モデルを作成した場合、データベースおよび表として実装する必
要があります。本章では、モデルを実装するために行う必要がある決定に
ついて説明します。
実装の最初の手順では、各列にドメイン またはデータ値のセットを定義す
ることによりデータ・モデルを作成 します。次の手順では、SQL 文を使用
してモデルを実装します。
本章の最初のセクションでは、ドメインの定義について詳しく説明します。
次のセクションでは、データベースを作成して (CREATEDATABASE および
CREATE TABLE コマンドを使用 ) データを入力する方法について説明しま
す。
ドメインの定義
本書の第 8 章で説明するデータ・モデルを作成するために、各列に対して
ドメインを定義する必要があります。列のドメイン とは、その列に正しく
表示できるすべてのデータ値のセットのことです。
ドメインの目的は、データ・モデルのデータの意味整合性 を保証し、実際
のデータを適切に反映することです。電話番号を入力するように設計され
ている場所に名前を入力できたり、整数を入力する場所に分数を入力でき
る場合、データ・モデルの整合性が失われる場合があります。
ドメインを定義する場合は、まず最初に、ドメインに含めるためにデータ
値が満たす必要がある制約 を定義します。列ドメインは、次の制約を使用
して指定されます。
• データ型
• デフォルト値
• チェック制約
また、各表で主キーと外部キーを識別することにより、列に対して参照制
約を指定できます。これらのキーの識別方法については、本書の第 8 章を
参照してください。
モデルの実装 9-3
ドメインの定義
データ型
列の最初の制約は、その列のデータ型に暗黙的に含まれています。データ
型を選択すると、そのデータ型によって表される値のみを列に格納できる
ように列が制約されます。
各データ型は特定の種類の情報のみを表します。列に対する正しいデータ
型とは、列に対して不適切なごくわずかな値を除く、その列に対して正し
いすべてのデータ値を表すデータ型のことです。
データ型の選択
表のすべての列には、データベース・サーバーでサポートされているデー
タ型の中から選択されたデータ型が含まれる必要があります。次の理由に
より、データ型の選択は重要です。
• データ型は、列の基本的なドメイン、つまり列に格納できる有効なデー
タ項目のセットを設定する。
• データ型は、データに対して実行できる操作を決定する。例えば、SUM
などの集計関数を文字データ型の列に適用することはできません。
• データ型は、各データ型によりディスクで占有される領域のサイズを決
定する。このことは小さい表では重要ではありませんが、表に何万また
は何十万の行がある場合は、4 バイトと 8 バイトの違いは極めて重要で
す。
図 3-8 に示す決定木は、データ型の選択の要約を示しています。これらに
ついては、次のセクションで説明します。
9-4 モデルの実装
ドメインの定義
データ項目は数値のみ
ですか ?
はい
いいえ
数値はすべて整数ですか ?
はい
いいえ
すべての数値は -215 ~ 215-1
の範囲内ですか ?
いいえ
すべての数値は -231 ~ 231-1
の範囲内ですか ?
いいえ
はい
SMALLINT
はい
INTEGER
DECIMAL(p,0)
小数点以下の桁数は
固定されていますか ?
いいえ
最大有効桁数は
8 桁ですか ?
いいえ
最大有効桁数は
16 桁ですか ?
いいえ
はい
DECIMAL(p,s)
はい
SMALLFLOAT
はい
FLOAT
DECIMAL(p)
図 3-8
データ型を選択するための決定に関する図 (1/2)
モデルの実装 9-5
ドメインの定義
データは日時順ですか ?
はい
いいえ
期間ですか、または特定の
時刻ですか ?
point
精度は最も近い日付に設定
されますか ?
いいえ
span
INTERVAL
はい
DATE
DATETIME
データは ASCII 文字
ですか ?
はい
いいえ
項目の長さには相違がまった
くないか、またはほとんどあ
りませんか ?
はい
いいえ
長さは 32,511 バイト以下
ですか ?
いいえ
長さは 255 バイトを超えて
いますか ?
はい
いいえ
VARCHAR(m,r)
BYTE
図 3-8
9-6 モデルの実装
データ型を選択するための決定に関する図 (2/2)
TEXT
はい
CHAR(n)
ドメインの定義
10 進数 (NUMERIC) 型
Informix データベース・サーバーは、8 つの 10 進数 (NUMERIC) 型をサポー
トしています。これらには、カウンターやコードに最適なもの、技術的な
数量に最適なもの、および金額に最適なものがあります。
カウンターとコード : 整数 (INTEGER) 型と
小数桁数 (SMALLINT) 型
整数 (INTEGER) 型および小数桁数 (SMALLINT) 型は、小さい整数を格納しま
す。これらのデータ型は、格納する最大値および最小値があらかじめ分
かっている場合に、カウント数、シーケンス番号、数値識別コード、また
は整数の範囲を含む列に適しています。
両方のデータ型は符号付き 2 進整数として格納されます。INTEGER 値は 32
ビットであり、- 231 ~ 231–1、つまり –2,147,483,647 ~ 2,147,483,647 の整数を
表すことができます。( 負の最大値の –2,147,483,248 は予約済みで、使用す
ることはできません。)
SMALLINT 値は 16 ビットのみです。–32,767 ~ 32,767 の整数を表すことが
できます。( 負の最大値の -32,768 は予約済みで、使用することはできませ
ん。)
これらのデータ型には、次の 2 つの利点があります。
• 大きな領域を占有しない (SMALLINT の場合は、値ごとに 2 バイト、
INTEGER の場合は値ごとに 4 バイト )。
•
SUM や MAX などの算術式およびソート比較を、非常に効率的に実行で
きる。
INTEGER および SMALLINT を使用する場合の短所は、格納できる値の範囲
が限定されていることです。データベース・サーバーは、整数の許容範囲
を超える値を格納することはできません。ただし、格納する最大値および
最小値が分かっている場合、このことは問題になりません。
自動シーケンス : シリアル (SERIAL) 型
シリアル (SERIAL) 型 は、特殊な機能を備えた整数 (INTEGER) 型 です。新しい
行が表に挿入されるたびに、データベース・サーバーは SERIAL 列に対して
新しい値を自動的に生成します。1 つの表には 1 つの SERIAL 列のみを指定
できます。シリアル値はデータベース・サーバーによって生成されるため、
モデルの実装 9-7
ドメインの定義
複数のユーザーが同時に行を追加する場合でも、新しい行のシリアル値は
常に異なります。通常のプログラムがこのような条件下で一意な数字コー
ドを生成するのは非常に困難であるため、この機能は非常に便利です。
シリアル化された行の最大数
231 行を表に挿入した場合、データベース・サーバーではすべての正の
シリアル番号が使用されることになります。ただし、この状態が発生す
るには、68 年間にわたり毎秒 1 行ずつ挿入する必要があり、このことが
問題になることはないと考えられます。また、このような状態が発生し
た場合、データベース・サーバーは新しい番号を生成し続けます。この
場合、次のシリアル番号は符号付き整数となります。データベース・
サーバーは正の値のみを使用するため、元に戻って 1 から整数値を生成
します。
生成される番号は、常に昇順になります。行を表から削除した場合、その
シリアル番号は再利用されません。このため、SERIAL 列でソートされた行
は、作成された順に戻されます。他のデータ型にはこの機能はありません。
CREATE TABLE 文の SERIAL 列には初期値を指定できます。このため、異な
る表に異なるシーケンスのシステム割当てキーを生成することができます。
stores5 データベースでは、この方法が使用されます。stores5 では、顧客番
号は 101 から始まり、オーダー番号は 1001 から始まります。899 名を超え
る顧客が登録されない小規模なビジネスでは、すべての顧客番号は 3 桁、
オーダー番号は 4 桁となります。
SERIAL 列は、自動的に一意な列にはなりません。重複するシリアル番号が
まったくないようにするには、一意な制約を適用する必要があります (9-28
ページ『CREATE TABLE の使用方法』を参照 )。ただし、DB-Access または
IBM Informix SQL の対話型スキーマ・エディターを使用して表を定義する場
合、SERIAL 列には一意な制約が自動的に適用されます。
シリアル (SERIAL) 型 には、次の利点があります。
• システム割当てキーを生成する場合に便利である。
• 複数のユーザーが表を更新している場合でも、一意な数字コードを生成
できる。
• 表ごとに異なる範囲の数値を使用できる。
9-8 モデルの実装
ドメインの定義
このデータ型には、次の利点があります。
• 1 つの表には 1 つの SERIAL 列のみを指定できる。
• 任意の数値のみを生成できます ( 任意の数字コードはデータベース・
ユーザーに許容されない場合があります )。
次のシリアル番号の変更
SERIAL 列の開始値は、列を作成するときに設定されます (9-28 ページ
『CREATE TABLE の使用方法』を参照 )。ALTER TABLE コマンドを後で
使用して、次の 値、つまり次に挿入される行に使用される値をリセット
できます。
データベース・サーバーが重複した値を生成する可能性があるため、現
在の最大値よりも小さい値を次の 値として設定することはできません。
一方、次の 値を現在の最大値よりも大きい値に設定することはできます
が、この場合は順序にギャップが生じます。
近似値 : 実数 (FLOAT) 型と小桁実数 (SMALLFLOAT) 型
科学、エンジニアリング、および統計アプリケーションでは、数桁の精度
までしか分からない場合が多く、数値の大きさは正確な桁数と同様に重要
です。
浮動小数点データ型は、このようなアプリケーショのために設計されてい
ます。このデータ型は、非常に大きなものから極めて小さいものまで広範
囲の分数および整数の数量を表すことができます。例えば、地球から太陽
までの平均距離 (1.5 × 109 m) およびプランク定数 (6.625 × 10-27) の両方を
簡単に表すことができます。唯一の制約事項は、精度が限定されているこ
とです。浮動小数点数は、値の最大重み数字 (MSD) のみを格納します。値
が浮動小数点数で格納できる桁数以下の場合、値はそのまま格納されます。
値が浮動小数点数で格納できる桁数を超える場合は、近似値として格納さ
れ、最小重み数字は 0 として扱われます。
多くの場合、このように正確さが欠如していても問題はありません。ただ
し、金額、および最小重み数字を 0 に変更するとエラーになるようなその
他の数量を記録する場合は、浮動小数点データ型を使用しないようにして
ください。
浮動小数点データ型には、次の 2 つのサイズがあります。実数 (FLOAT) 型
は、使用しているコンピューター上で C 言語で実装される実数の 2 進浮動
小数点数です。このデータ型は、通常は 8 バイトです。一方、小桁実数
(SMALLFLOAT) 型 ( 小桁実数 (REAL) 型とも呼ばれる ) は、通常は 4 バイトの単
精度の 2 進浮動小数点数です。この 2 つのデータ型の主な相違点は精度で
す。FLOAT 列は約 16 桁の値を格納し、SMALLFLOAT 列は約 8 桁の値のみを
格納します。
モデルの実装 9-9
ドメインの定義
浮動小数点数には、次の利点があります。
• 非常に大きな値および非常に小さい値 ( 分数を含む ) を格納できる。
• 数値を 4 バイトまたは 8 バイトでコンパクトに表すことができる。
• これらのデータ型では、AVG や MIN などの算術関数およびソート比較が
効率的である。
浮動小数点数の主な短所は、精度の範囲外の桁が 0 として扱われることで
す。
精度を調整可能な浮動小数点 : DECIMAL(p)
DECIMAL(p) データ型は、FLOAT および SMALLFLOAT と類似する浮動小数
点データ型です。重要な相違点は、格納する有効数字を指定できることで
す。p として指定する精度は 1 ~ 32 で、SMALLFLOAT よりも小さい値から
FLOAT の精度の 2 倍の値までを指定することができます。
DECIMAL(p) 数値の大きさは、10-128 ~ 126 の範囲になります。
10 進数 (DECIMAL) 型は混同されやすく、DECIMAL(p)、つまり精度が指定
された DECIMAL については注意が必要です。DECIMAL(p) 数値のサイズは
精度によって異なり、1+p/2 バイトを占有します ( 必要に応じて整数に丸め
られる )。
DECIMAL(p) には、FLOAT と比較した場合に次のような利点があります。
•
•
•
•
アプリケーションに合わせて近似値から高精度まで精度を設定できる。
32 桁までの数値を正確に表すことができる。
数値の精度に応じて記憶域が使用される。
すべての Informix データベース・サーバーは、ホスト・オペレーティン
グ・システムに関係なく、同じ精度および大きさの範囲をサポートして
います。
DECIMAL(p) データ型には、次の短所があります。
• 算術計算およびソートが FLOAT 数値よりも多少遅い。
• 数多くのプログラミング言語は、実数 (FLOAT) 型 および 整数 (INTEGER)
型 のようには DECIMAL(p) データ形式をサポートしていない。プログラ
ムがデータベースから DECIMAL(p) 値を抽出する場合は、他の形式に変
換してから処理する必要があります ( ただし、IBM Informix 4GL プログ
ラムは、DECIMAL(p) 値を直接使用することができます。)
9-10 モデルの実装
ドメインの定義
固定小数点数 : 10 進数 (DECIMAL) 型と金額 (MONEY) 型
ほとんどの商用アプリケーションでは、小数点以上および小数点以下の桁
数が固定されている数値を格納する必要があります。この最も典型的な例
は金額です。米国通貨またはその他の通貨の金額は、小数点以下 2 桁で書
き込まれます。通常、小数点以上の必要な桁数は記録するトランザクショ
ンによって決定され、例えば、個人的な予算の場合は 5 桁、小規模ビジネ
スの場合は 7 桁、国家予算の場合は 12 桁または 13 桁となります。
これらの数値は、数値に関係なく小数点が固定されているため、固定小数
点 数です。DECIMAL(p,s) データ型は、固定小数点数を格納するように設計
されています。このような列を指定する場合は、精度 (p) を 1 ~ 32 の範囲の
格納可能な合計桁数として指定します。スケール (s) は、小数点以下の桁数
として指定します ( 図 3-9 に、精度とスケールの関係を示す )。スケールを
0 にすると、整数のみが格納されます。この場合、DECIMAL(p,s) は 32 桁ま
での整数を格納できます。
精度:8 桁
DECIMAL(8,3)
31964.535
スケール:3 桁
図 3-9
固定小数点数の精度とスケールの関係
DECIMAL(p) データ型と同様に DECIMAL(p,s) は、その精度に比例して領域
を占有します。1 つの値は 1+p/2 バイトを占有し、整数のバイト数に丸め
られます。
金額 (MONEY) 型は、DECIMAL(p,s) とほぼ同じですが、さらに特別な機能が
あります。データベース・サーバーは、表示する文字へと MONEY 値を変
換するたびに通貨記号を自動的に付加します。
整数 (INTEGER) 型および実数 (FLOAT) 型と比較した場合の DECIMAL(p,s) の利
点は、非常に高い精度が使用可能なことで ( 整数 (INTEGER) 型の 10 桁およ
び実数 (FLOAT) 型の 16 桁に対して 32 桁 )、精度および必要な記憶域はアプ
リケーションに合わせて調整できます。
モデルの実装 9-11
ドメインの定義
短所は、算術計算の効率が低く、数多くのプログラミング言語がこの形式
の数値をサポートしていないことです。このため、プログラムが数値を抽
出する場合、通常は処理を行うために他の数値形式に変換する必要があり
ます ( ただし、IBM Informix 4GL プログラムは、DECIMAL(p,s) および
MONEY 値を直接使用できます )。
どこの国の通貨であるか : 通貨フォーマットの選択
国によって金額を区切るする独自の方法があります。Informix データ
ベース・サーバーは、MONEY 値を表示するとき、オペレーティング・
システムで定義された通貨フォーマット、通常、DBMONEY 変数に定義
された通貨フォーマットを参照します。通貨記号は金額の前または後に
付けられ、10 進数値の区切り記号は、ピリオド、コンマなどの文字に設
定できます。詳細については、「IBM Informix SQL リファレンス・ガイド」
の第 4 章を参照してください。
日時順のデータ型
Informix データベース・サーバーは、時間を記録するために 3 つのデータ
型をサポートしています。DATE データ型は、カレンダー日付を格納しま
す。DATETIME は、時点を年から小数部までの任意の精度で記録できます。
INTERVAL データ型は、時間の範囲、つまり期間を格納します。
カレンダー日付 : 日付 (DATE) 型
DATE データ型は、カレンダー日付を格納します。DATE 値は符号付き整数
で、その内容は 1899 年 12 月 31 日午前 0 時からの正の日数を表します。多
くの場合、今世紀の方向にカウントする場合が正の日数になります。
DATE 形式には、遠い将来 (58,000 世紀 ) の日付に対応できるほどの十分な
精度があります。負の DATE 値は、基準日の前の日数として解釈され、
DATE -1 は 1899 年 12 月 30 日を表します。
DATE 値は整数であるため、Informix データベース・サーバーではこれらの
値を算術式に使用することができます。例えば、DATE 列の平均を計算した
り、DATE 列に 7 または 365 を追加することができます。また、DATE 値を
取り扱うためのさまざまなセットの関数が用意されています
(「IBM Informix SQL リファレンス・ガイド」の第 7 章を参照 )。
9-12 モデルの実装
ドメインの定義
DATE データ型は、項目当たり 4 バイトで、コンパクトです。算術関数お
よび比較は、DATE 列で迅速に実行されます。
M/D/Y と D-M-Y: 日付書式の選択
日付のコンポーネントを区切って順序付けるには、さまざまな方法があ
ります。Informix データベース・サーバーは、DATE 値を表示する場合、
オペレーティング・システムに定義されているフォーマット ( 通常は、
DBDATE という変数内で定義されている ) を参照します。日付、月、年
の数値は、選択した区切り記号で区切り、任意の順序で表示できます。
詳細については、「IBM Informix SQL リファレンス・ガイド」の第 4 章を参
照してください。
正確な時刻 : 日時 (DATETIME) 型
DATETIME データ型は、1 A.D から始まる期間内の時刻を格納します。実際
には、DATETIME は 28 のデータ型のファミリーで、それぞれの精度は異な
ります。DATETIME 列を定義するときに、その精度を指定します。この列
には、 年、月、日、時間、分、秒、小数部 のリストから任意のシーケンス
を含むことができます。このように、年のみ、月と日のみ、または時間や
ミリ秒まで正確な日付と時刻を格納する DATETIME 列を定義できます。
DATETIME 値のサイズは、図 3-10 に示すように精度に応じて 2 ~ 11 バイト
となります。
DATETIME の利点は、最も近い日付よりも精度が高い日付を格納でき、時
間値を格納できることです。唯一の短所は、表示フォーマットに柔軟性が
ないことですが、このことは回避することが可能です (9-16 ページ『日時
(DATETIME) 型値または時間隔 (INTERVAL) 型値のフォーマットの強制』を
参照 )。
モデルの実装 9-13
ドメインの定義
精度
year to year
year to month
year to day
year to hour
year to minute
year to second
year to fraction (f)
month to month
month to day
month to hour
month to minute
month to second
month to fraction(f)
day to day
サイズ *
3
4
5
6
7
8
8+f/2
2
3
4
5
6
6+f/2
2
精度
day to hour
day to minute
day to second
day to fraction(f)
hour to hour
hour to minute
hour to second
hour to fraction(f)
minute to minute
minute to second
minute to fraction(f)
second to second
second to fraction(f)
fraction to fraction(f)
サイズ *
3
4
5
5+f/2
2
3
4
4+f/2
2
3
3+f/2
2
2+f/2
1+f/2
* f が奇数の場合、サイズは次の完全なバイトに丸められます。
図 3-10
日時 (DATETIME) 型のすべての精度およびサイズ ( バイト )
期間 : 時間隔 (INTERVAL) 型
INTERVAL データ型は、期間、つまり時間の範囲を格納します。2 つの
DATETIME 値の相違点は、これらの値を分離する期間を表す INTERVAL で
す。次に、相違点を明確にするための例を示します。
• 従業員が 1991 年 5 月 21 日に仕事を開始した (DATE または DATETIME)。
• この従業員は 254 日間働いている (INTERVAL、TODAY 関数と開始 DATE
または DATETIME の差 )。
• 従業員は 0900 時から仕事を始める (DATETIME)。
• 従業員は 8 時間働き (INTERVAL)、昼食時間は 45 分である ( もう 1 つの
INTERVAL)。
• 退社時間は 1745 時である ( 仕事の開始時の DATETIME と 2 つの INTERVAL の合計 )。
9-14 モデルの実装
ドメインの定義
DATETIME と同様に、INTERVAL は、それぞれ精度が異なるデータ型のファ
ミリーです。INTERVAL は、年と月のカウントを表したり、日、時間、分、
秒、または小数部のカウントを表すことができ、合わせて 18 の精度を指定
できます。INTERVAL 値のサイズは、図 3-11 に示すように 2 ~ 8 バイトで
す。
精度
year(p) to year
year(p) to month
month(p) to month
day(p) to day
day(p) to hour
day(p) to minute
day(p) to second
day(p) to fraction(f)
hour(p) to hour
サイズ *
1+p/2
2+p/2
1+p/2
1+p/2
2+p/2
3+p/2
4+p/2
4+(p+f)/2
1+p/2
精度
hour(p) to minute
hour(p) to second
hour(p) to fraction(f)
minute(p) to minute
minute(p) to second
minute(p) to fraction(f)
second(p) to second
second(p) to fraction(f)
fraction to fraction(f)
サイズ *
2+p/2
3+p/2
3+(p+f)/2
1+p/2
2+p/2
2+(p+f)/2
1+p/2
1+(p+f)/2
1+f/2
* 小数部のサイズは、次の完全なバイトに丸められます。
図 3-11
時間隔 (INTERVAL) 型のすべての精度およびサイズ ( バイト )
INTERVAL 値は、正だけでなく負にすることもできます。値を加算または減
算したり、ある値で乗算または除算することによって比率を変えることが
できます。このことは、DATE または DATETIME には該当しません。“4 月
23 日までの日数の半分は何日か ” と尋ねることは適切ですが、“4 月 23 日の
半分は何か ” と尋ねることは適切ではありません。
モデルの実装 9-15
ドメインの定義
文字 (CHARACTER) 型
すべての Informix データベース・サーバーは、CHAR(n) データ型をサポー
トしています。IBM Informix OnLine は、特別な用途を持つ 3 つの他のデータ
型をサポートしています。
文字データ : CHAR(n)
CHAR(n) データ型は、n ASCII 文字のシーケンスを含みます。長さ n は 1 ~
32,511 です。
日時 (DATETIME) 型値または時間隔 (INTERVAL) 型値のフォーマット
の強制
データベース・サーバーは、常に INTERVAL 値または DATETIME 値のコ
ンポーネントを年 - 月 - 日 時間 : 分 : 秒 . 小数部 の順に表示します。デー
タベース・サーバーは、DATE をフォーマットする場合とは異なり、オ
ペレーティング・システムで定義されている日付書式を参照しません。
DATETIME 値の日付部分をシステム定義フォーマットで表示する
SELECT 文を作成することができます。このためには、EXTEND 関数を
使用してコンポーネント・フィールドを分離し、MDY() 関数にこれらの
フィールドを渡して、DATE に変換します。次に、例の一部を示します。
SELECT ... MDY (
EXTEND (DATE_RECEIVED, MONTH TO
MONTH),
EXTEND (DATE_RECEIVED, DAY TO DAY),
EXTEND (DATE_RECEIVED, YEAR TO YEAR))
FROM RECEIPTS ...
IBM Informix 4GL または IBM Informix SQL を使用してレポートを設計す
る場合は、PRINT 文の柔軟性を生かすことができます。EXTEND を使用
して、DATETIME または INTERVAL 値の各コンポーネントを式の一部と
して選択します。便宜的に各式に別名を指定します。PRINT 式のコン
ポーネントと適切な句読点とを組み合わせます。
SELECT ...
EXTEND (START_TIME, HOUR TO HOUR) H,
EXTEND (START_TIME, MINUTE TO MINUTE) M, ...
次に、レポートに次のように指定します。
PRINT "Start work at ", H USING "&&", M USING "&&", "hours."
9-16 モデルの実装
ドメインの定義
CHAR(n) 値を抽出するか、または格納するたびに、n バイトが転送されま
す。挿入された値が短い場合は、空白が埋め込まれて n バイトになります。
n よりも長い値は切り捨てられます。このフォーマットは、可変長データ
に対応していません。
CHAR(n) はタブや空白を含むことはできますが、通常、その他の非印字文
字は含みません。INSERT または UPDATE を使用して行を挿入するか、また
はユーティリティー・プログラムを使用して行をロードする場合、非印字
文字を入力することはできません。ただし、埋込み SQL を使用して行を作
成する場合は、プログラムは NULL 文字 (2 進数の 0) 以外のすべての文字を
挿入できます。文字列に非印字文字を格納することは、標準的なプログラ
ムやユーティリティーでは想定されていないため、適切ではありません。
CHAR(n) データ型の利点は、すべてのデータベース・サーバーで使用可能
なことです。このデータ型の唯一の短所は、固定長であることです。デー
タ値の長さが行ごとに大きく異なる場合、領域が無駄になります。
可変長文字列 : VARCHAR(m,r)
多くの場合、文字カラムの項目は長さが異なり、多くの項目は平均長さで、
最大長さの項目は少数のみであることがあります。VARCHAR(m,r) データ型
は、そのようなデータを格納するときにディスク領域を節約するように設
計されています。VARCHAR(m,r) として定義された列は、CHAR(n) として定
義された列と同じように使用します。VARCHAR(m,r) 列を定義する場合は、
m をデータ項目の最大 長さとして指定します。1 バイトの長さのフィール
ドを使用して、各項目の実際の内容のみがディスクに格納されます。m の
最大値は 255 です。つまり、VARCHAR(m,r) 値は最大 255 文字まで格納でき
ます。列がインデックス付けされている場合、m の最大値は 254 です。
2 番目のパラメーター r は、オプションの予約 長で、ディスクに格納され
る項目の長さの最小値を設定します。項目が r よりも短い場合でも、
その項目を格納するために r バイトが割り当てられます。これは、行を更
新するときに時間を節約するためです (9-18 ページ『可変長の実行時間』を
参照 )。
CHAR(n) と比較した場合の VARCHAR(m,r) データ型の利点は、次のとおり
です。
• データ項目の長さが非常に異なるか、またいくつかの項目のみが平均長
さよりも長い場合は、ディスク領域が節約される。
• 表が小さいほど、問合せは迅速に実行される。
モデルの実装 9-17
ドメインの定義
このデータ型の短所は、次のとおりです。
• 255 文字を超える長さは許容されない。
• 表の更新が遅くなる場合がある。
• すべての Informix データベース・サーバーで使用可能なわけではない。
可変長の実行時間
VARCHAR(m,r) を使用する場合、表の列は固定長ではなく可変長となり
ます。このことは、データベース操作の実行速度にさまざまな影響を与
えます。
1 つのディスク・ページに収まる行が多くなるため、データベース・
サーバーは、行が固定長である場合よりも少ないディスク操作で表を検
索できます。このため、問合せをさらに迅速に実行できます。同様に、
挿入および削除操作も多少迅速に実行できます。
行を更新するときにデータベース・サーバーが実行する必要がある作業
量は、古い行ではなく新しい行の長さに依存します。新しい行のサイズ
が同じか、または短い場合は、実行時間は固定長の行の場合とあまり変
わりません。ただし、新しい行が古い行よりも長い場合は、データベー
ス・サーバーは数倍のディスク操作を実行することが必要となる場合が
あります。このため、VARCHAR(m,r) データを使用する表を更新する場合
は、固定長のフィールドを更新する場合よりも遅くなることがあります。
大部分のデータ項目をカバーするサイズとして r を指定すると、このよう
な影響を緩和することができます。この場合、ほとんどの行は予約長を
使用するため、埋め込み時に無駄になる領域はわずかとなり、通常の値
が非常に長い値と置き換えられる場合にのみ更新が遅くなります。
ラージ・キャラクター・オブジェクト : 文字 (CHARACTER) 型
テキスト (TEXT) 型 は、テキストのブロックを格納します。このデータ型は、
ビジネス・フォーム、プログラム・ソース、データ・ファイル、メモなど
の内蔵タイプのドキュメントを格納するように設計されています。TEXT 項
目にはどのようなデータでも格納できますが、IBM Informix ツールは TEXT
項目が印字可能であると想定しているため、このデータ型は印字可能な
ASCII テキストに制限されます。
9-18 モデルの実装
ドメインの定義
TEXT 値は、その一部である行には格納されません。このような値は、通
常、行とは別の領域にあるディスク・ページ全体に割り当てられます
(10-20 ページ『BLOB データの格納』を参照 )。
BLOB の使用方法
テキスト (TEXT) 型とバイト (BYTE) 型の列は、総称してバイナリー・ラー
ジ・オブジェクト または BLOB と呼ばれます。データベース・サーバー
は、BLOB の格納と抽出のみを行います。通常、BLOB は、IBM Informix
4GL または IBM Informix ESQL/C などの埋込み SQL をサポートする言語を
使用して作成されたプログラムによって取り出され、格納されます。こ
のようなプログラムでは、順次ファイルの読取りまたは書込みと同様に
BLOB 値の取出し、挿入、更新を行うことができます。
対話型であれ、プログラムされたものであれ、すべての SQL 文で、
BLOB 列を次のように使用することはできません。
• 算術式またはブール式
• GROUP BY または ORDER BY 節
• UNIQUE テスト
• それ自体または複合インデックスの一部としてのインデックス機能
のため
対話式、あるいはフォームまたはレポートに入力された SELECT 文では、
BLOB を次のように操作できます。
• 名前で選択する。部分文字列を使用して名前の一部を抽出すること
もできる。
•
•
LENGTH( 列 ) を選択することによって長さを戻す。
IS [NOT] NULL 述部を使用してテストする。
対話型 INSERT 文では、VALUES 節を使用して BLOB を挿入できますが、
その列に指定できる値は NULL のみです。ただし、INSERT 文の SELECT
フォームを使用して、他の表から BLOB 値をコピーできます。
対話型 UPDATE 文では、BLOB 列を NULL または BLOB 列を戻す副問合
せに更新できます。
CHAR(n) および VARCHAR(m,r) と比較した場合のテキスト (TEXT) 型の利点
は、データを格納するディスク領域の容量制限を除き、TEXT データ項目の
サイズに制限がないことです。TEXT データ・タイプの短所は、次のとおり
です。
モデルの実装 9-19
ドメインの定義
• TEXT データはディスク・ページ全体に割り当てられるため、短い項目
の場合は領域が無駄になる。
•
SQL 文の TEXT 列の使用方法には制限がある (9-19 ページ『BLOB の使用
方法』を参照 )。
• すべての Informix データベース・サーバーで使用可能なわけではない。
TEXT 値は、IBM Informix 4GL プログラムまたは ACE レポート・ライターを
使用して作成されたレポートに表示できます。IBM Informix 4GL プログラム
または PERFORM スクリーン・フォーム・プロセッサーで作成したスク
リーン・フォームを使用して、TEXT 値を画面に表示し、編集することがで
きます。
2 進数オブジェクト : 2 進数 (BINARY) 型
バイト (BYTE) 型は、グラフィック・イメージ、プログラム・オブジェク
ト・ファイル、ワード・プロセッサーやスプレッドシートによって保存さ
れたドキュメントなど、プログラムによって生成されるすべてのデータを
格納するように設計されています。データベース・サーバーは、BYTE 列に
どのような長さと種類のデータも格納できます。
テキスト (TEXT) 型 と同様に、バイト (BYTE) 型 は、通常の行データとは異な
るディスク領域のディスク・ページ全体に格納されます。
バイト (BYTE) 型の利点は、テキスト (TEXT) 型および CHAR(n) とは異なり、
どのようなデータでも許容できることです。このデータ型の短所は、テキ
スト (TEXT) 型の場合と同じです。
データ型の変更
ALTER TABLE コマンドを使用すると、表の作成後に、列に割り当てられた
データ型を変更することができます。この操作が必要となる場合もありま
すが、次の理由により、データ型を変更しないようにしてください。
• データ型を変更するには、データベース・サーバーが表をコピーして再
作成する必要がある。大きな表では、多くの時間とディスク領域が必要
になる場合があります。
• データ型を変更すると、情報が失われることがある。例えば、列を長い
文字データ型から短い文字データ型に変更した場合は長い値が切り捨て
られ、精度の低い数値データ型に変更した場合は下位の桁が切り捨てら
れます。
• 既存のプログラム、フォーム、レポート、および格納された問合せも、
変更することが必要になる場合がある。
9-20 モデルの実装
ドメインの定義
デフォルト値
デフォルト値は、明示的な値が指定されない場合に列に挿入される値です。
デフォルト値は、ユーザーが定義するリテラル文字、または次の SQL
NULL 定数式のいずれかにすることができます。
•
•
•
•
USER
CURRENT
TODAY
SITENAME
すべての列にデフォルト値が必要なわけではありませんが、データ・モデ
ルを処理するときにデフォルト値を使用すると、データ入力時間を節約し
たり、データ入力エラーを防止できる場合があります。例えば、アドレ
ス・ブック・モデルには State 列があります。この列のデータを表示する
と、アドレス・リストの 50% 以上の州が California になっています。時間
を節約するために、“California” という文字列を State 列のデフォルト値とし
て指定します。
デフォルト値は、列にフラグが含まれる場合にも役立ちます。アドレス・
ブック・モデルはフラグ (Y/N) を使用して、モデムが 300、1200、または
2400 ボーのいずれで動作するかを示します。この列にデフォルト値 (“N”)
を指定することができます。これにより、特定のボー・レートで動作しな
いモデムに値を入力する必要がなくなります。
チェック制約
チェック制約は、データ値をドメインに含める前に、データ値に関する条
件または要件を指定します。制約は、前の例のように自然言語で記述でき
ます。また、精度を高めるために、WHERE 節の構文に制約を記述すること
もできます。例えば、次の要件は、整数ドメインの値を特定の範囲に制限
します。
Customer_Number >= 50000 AND Customer_Number <= 99999
このように、MATCHES 述部およびサポートされる正規表現構文を使用して
文字ベースのドメインに制約を記述できます。例えば、次の制約は、Telephone ドメインを米国のローカル電話番号の形式に限定します。
VceNumber MATCHES "[2-9][2-9][0-9]-[0-9][0-9][0-9][0-9]"
モデルの実装 9-21
ドメインの定義
ただし、この形式の制約は、記述が単調で困難な場合があります。自然言
語でルールを記述する方が簡単です。
ドメインの指定
1 つのドメインを数多くの列に適用できます。アドレス・ブック・モデル
には、ドメインが電話番号である列が含まれます。電話番号ドメインは一
度のみ指定します。
データ・モデル作成の最後の手順は、モデルに必要なドメインを指定する
ことです。これにより、次の列を含むドメインのリストが生成されます。
• 参照を容易にするための名前
• INTEGER、CHAR(n) などのデータ型
• WHERE 節形式または英語で記述される、この種類のデータを制限する
追加ルール
図 3-12 に、アドレス・ブック・データ・モデルのドメインのリストの例を
示します。
図 3-12
ドメイン
アドレス・コード
在席操作時間
誕生日
市
名前
郵便番号
州/県
住所
電話
真/偽
データ型
SERIAL
DATETIME HOUR TO MINUTE
DATE
VARCHAR(40,10)
VARCHAR(50,20)
CHAR(10)
CHAR(5)
VARCHAR(50,20)
CHAR(13)
CHAR(1)
電話タイプ
CHAR(10)
その他の制約
1000<code および code <10000
birthday <= TODAY
有効な郵便番号のみ
有効な電話番号のみ
Y = 真、N = 偽、
DEFAULT = N
アドレス・ブック・データ・モデルを完了するために必要なドメイン
列の下にドメイン名を書き込んで、リストを完成させてください。これら
の名前は、モデルの表を表示するときに使用されます。例えば、アドレ
ス・ブック・モデルの 5 つの表の 6 つの列にドメイン Telephone を書き込み
ます。図 3-13 は、完全なモデルを示します。
9-22 モデルの実装
ドメインの定義
名前
NameString
AddressCode
PK UA
FK
Gaius C. Caesar
SPQR, S.A.
1001
1020
BirthDate
17-03-1990
(null)
名前
アドレス・コード
誕生日
アドレス
AddressCode
Street
City
StaProv
Postcode
2430 Tasso St. #8
411 Bohannon Drive
St. Louis
Lenaxa
CA
Abta.
83267-1048
TW2 5AQ
PK SA
1001
1020
アドレス・コード
住所
市
州/県
音声
VceNumber
郵便番号
VceType
PK UA
1-800-274-8184
011-49-89-922-030
home
car
電話
音声電話タイプ
FAX
FaxNumber
AddressCode
VceNumber
PK UA
FK
FK
926-6741
61-62-435-143
1001
1020
926-6300
(null)
電話
アドレス・コード
OperFrom
OperTill
0800
1730
0400
1900
電話
NameFax
在席操作時間
NameVce
NameString
FaxNumber
NameString
VceNumber
PK FK
PK FK
PK FK
PK FK
Gaius C. Caesar
SPQR, S.A.
926-6741
61-62-435-143
Gaius C. Caesar
SPQR, S.A.
1-800-274-8184
011-49-89-922-030
名前
電話
名前
電話
モデム
MdmNumber
NameString
VceNumber
AddressCode
PK UA
FK NN
FK
FK
416-566-7024
33 1 42 70 67 74
Nite Owl BBS
CompuServe
926-6300
(null)
1001
1020
電話
図 3-13
名前
電話
B300
Y
Y
アドレス・コード
B1200
Y
Y
B2400
N
Y
真/偽
第 8 章に記載されている、ドメインが追加された
アドレス・ブック・データ・モデル
モデルの実装 9-23
データベースの作成
データベースの作成
これで、データ・モデルをデータベースの表として作成できます。デー
タ・モデルを作成するには、CREATE DATABASE、CREATE TABLE、および
CREATE INDEX コマンドを使用します。これらのコマンドの構文について
は、「IBM Informix SQL リファレンス・ガイド」に詳しく示されています。こ
のセクションでは、データ・モデルの実装における CREATE DATABASE お
よび CREATE TABLE の使用方法について説明します。CREATE INDEX の使
用方法については、次の章で説明します。
同じモデルを複数回作成することが必要となる場合があります。ただし、
モデルを作成するコマンドは自動的に格納および実行できます。
表が存在する場合は、データ行を入力する必要があります。この入力は、
手動で行うか、またはユーティリティー・プログラムかカスタム・プログ
ラミングを使用して行うことができます。
CREATE DATABASE の使用方法
データベースは、データ・モデルに入力されるすべての要素を格納するコン
テナーです。これらの要素は、表だけでなく、ビュー、インデックス、およ
びシノニムも含まれます。他の何らかの要素を作成するには、まずデータ
ベースを作成する必要があります。CREATE DATABASE コマンドは、データ
ベースを作成するだけでなく、使用するトランザクション・ログ機能を設定
します。トランザクション・ログ機能については、7 章で説明します。
IBM Informix OnLine データベース・サーバーは、他のデータベース・サー
バーとはデータベースおよび表の作成方法が異なります。まず最初に、
IBM Informix OnLine について説明します。
IBM Informix OnLine での CREATE DATABASE の使用方法
IBM Informix OnLine データベース・サーバーは、データベースを作成すると
きに、データベースの存在およびロギング・モードを示すレコードを設定
します。データベース・サーバーはディスク領域を直接管理するため、こ
れらのレコードはオペレーティング・システムのコマンドには見えません。
名前の競合の回避
通常、IBM Informix OnLine の 1 つのコピーのみがマシン上で実行され、これ
により、そのマシンのすべてのユーザーに属するデータベースが管理され
ます。データベース名のリストは 1 つのみ保持されます。データベース名
は、そのデータベース・サーバーによって管理される他のすべてのデータ
ベースの名前と異なる必要があります ( データベース・サーバーの複数の
コピーを実行することができます。このような実行は、例えば、操作デー
9-24 モデルの実装
データベースの作成
タとは別のテストのために安全な環境を作成する場合に行われます。この
場合、データベースを作成するとき、および後でデータベースにアクセス
するときに正しいデータベース・サーバーを使用していることを確認する
必要があります。)
DB 領域の選択
IBM Informix OnLine では、特定の DB 領域 においてデータベースを作成で
きます。DB 領域は、ディスク装置の名前付きの領域です。特定の DB 領域
を使用する場合は、IBM Informix OnLine 管理者に必ず問い合わせてくださ
い。管理者は、データベースを DB 領域に配置することによって、他の
データベースから分離したり、データベースを特定のディスク・デバイス
に格納することができます (DB 領域とディスク・デバイスの関係について
は、第 10 章で説明します。)
DB 領域はミラーリング されることがあります ( 信頼性を高めるために、2
つの異なるディスク・デバイス上に複製される )。その内容が非常に重要な
場合は、データベースをミラーリングされた DB 領域に格納できます。
ログ機能のタイプの選択
IBM Informix OnLine では、トランザクション・ログ機能に関して次の 4 つ
の選択肢が用意されています。
• ログ機能を使用しない。この方法は推奨しません。ハードウェア障害の
ためにデータベースが失われた場合、最後のアーカイブ以降のすべての
データ変更内容が失われます。
CREATE DATABASE db_with_no_log
ログ機能を選択しない場合、BEGIN WORK およびトランザクション処理
に関連するその他の SQL 文をデータベースに使用することはできませ
ん。このことは、データベースを使用するプログラムのロジックに影響
を与えます。
• 定期的な ( バッファーなし ) ログ機能。ほとんどのデータベースにとっ
て最適な方法です。障害が発生した場合は、コミットされていないトラ
ンザクションのみが失われます。
CREATE DATABASE a_logged_db WITH LOG
モデルの実装 9-25
データベースの作成
• バッファー付きログ機能。データベースが失われた場合、最新の変更内
容の一部が失われるか、またはまったく失われません。このようにリス
クが少なくなっていますが、変更時のパフォーマンスの向上はわずかで
す。
CREATE DATABASE buf_log_db WITH BUFFERED LOG
バッファー付きログ機能は、頻繁に更新されるデータベースに最適です
が ( 更新の速度が重要となるため )、クラッシュした場合は更新内容を
他のデータから再作成することができます。SET LOG 文を使用して、
バッファー付きログ機能と定期的なログ機能を切り替えることができま
す。
•
ANSI 標準準拠のログ機能。この機能は定期的なログ機能と同じですが、
トランザクション処理のための ANSI ルールが強制的に適用されます
( 第 1 章の『ANSI SQL』を参照 )。
CREATE DATABASE std_rules_db WITH LOG MODE ANSI
ANSI SQL の設計では、バッファー付きログ機能を使用することはでき
ません。
IBM Informix OnLine 管理者は、後でトランザクション・ログ機能をオンま
たはオフにすることができます。例えば、数多くの新しい行を挿入する前
にオフにすることができます。
他の IBM Informix データベース・サーバーでの CREATE DATABASE の
使用方法
他の Informix データベース・サーバーは、オペレーティング・システムに
よって管理される 1 つまたは複数のファイルのセットとしてデータベース
を作成します。例えば、UNIX オペレーティング・システムでは、データ
ベースはデータベース名と同じ名前のディレクトリーに格納されたファイ
ルの小さなグループです ( ファイルの使用方法の詳細については、データ
ベース・サーバーのマニュアルを参照 )。つまり、データベース名のルール
は、オペレーティング・システムのファイル名のルールと同じです。
9-26 モデルの実装
データベースの作成
ログ機能のタイプの選択
他のデータベース・サーバーでは、次の 3 つのログ機能を選択できます。
• ログ機能を使用しない。この方法は推奨しません。ハードウェア障害の
ためにデータベースが失われた場合、最後のアーカイブ以降のすべての
データ変更内容が失われます。
CREATE DATABASE not_logged_db
ログ機能を選択しない場合、BEGIN WORK やトランザクション処理に関
連するその他の SQL 文をデータベースに使用することはできません。
このことは、データベースを使用するプログラムのロジックに影響を与
えます。
• 定期的なログ機能。ほとんどのデータベースにとって最適な方法です。
データベースが失われた場合、障害時に進行中の変更内容のみが失われ
ます。
CREATE DATABASE a_logged_db WITH LOG IN "a-log-file"
トランザクション・ログを含めるファイルを指定する必要があります
( ファイル名の形式は、オペレーティング・システムのルールに応じて
異なる )。データベースが変更されるたびに、このファイルは大きくな
ります。データベース・ファイルがアーカイブされるたびに、最新の最
新のアーカイブ以降のトランザクションのみを反映するためにログ・
ファイルを空の状態に戻す必要があります。
•
ANSI 標準準拠のログ機能。これは定期的なログ機能と同じですが、ト
ランザクション処理のための ANSI ルールもオンになります ( 第 1 章の
ANSI 標準準拠のデータベースに関する説明を参照 )。
CREATE DATABASE std_rules_db WITH LOG IN "a-log-file" MODE ANSI
START DATABASE 文を使用して、トランザクション・ログをログなしデー
タベースに追加することができます。ログ機能を適用すると、削除するこ
とはできません ( ログ機能は、IBM Informix OnLine でのみオンまたはオフに
することができる )。
モデルの実装 9-27
データベースの作成
CREATE TABLE の使用方法
CREATE TABLE 文を使用して、データ・モデルで設計した各表を作成する
ことができます。この文の形式は複雑ですが、基本的には表の列のリスト
となっています。各列に次の情報を入力します。
•
•
•
•
•
•
•
•
9-28 モデルの実装
列名
データ型 ( 作成したドメイン・リストから )
列が主キーである場合、制約 PRIMARY KEY
列が外部キーである場合、制約 FOREIGN KEY
列が主キーでなく NULL が許容されない場合、制約 NOT NULL
列が主キーでなく重複が許容されない場合、制約 UNIQUE
列にデフォルト値がある場合、制約 DEFAULT
列にチェック制約がある場合、制約 CHECK
データベースの作成
要約すると、CREATE TABLE 文は、データ・モデル・ダイアグラムに作成
した表で構成されるイメージです。図 3-14 は、図 3-139-23 ページ に示さ
れるアドレス・ブック・モデルの文を示します。
CREATE TABLE NAME
(
NameString
VARCHAR(50,20) PRIMARY KEY,
AddressCode
INTEGER,
BirthDate
DATE
FOREIGN KEY (AddressCode) REFERENCES ADDRESS (AddressCode)
);
CREATE TABLE ADDRESS
(
AddressCode
SERIAL(1000) PRIMARY KEY,
Street
VARCHAR(50,20),
City
VARCHAR(40,10),
StaProv
CHAR(5),
PostCode
CHAR(10)
);
CREATE TABLE VOICE
(
VceNumber
CHAR(13) PRIMARY KEY,
VceType
CHAR(10)
);
CREATE TABLE FAX
(
FaxNumber
CHAR(13) PRIMARY KEY,
AddressCode
INTEGER,
VceNumber
CHAR(13),
OperFrom
DATETIME HOUR TO MINUTE,
OperTill
DATETIME HOUR TO MINUTE
FOREIGN KEY (AddressCode) REFERENCES ADDRESS (AddressCode),
FOREIGN KEY (VceNumber) REFERENCES VOICE (VceNumber)
);
CREATE TABLE NAMEVCE
(
NameString
VARCHAR(50,20),
VceNumber
CHAR(13),
PRIMARY KEY (NameString, VceNumber),
FOREIGN KEY (NameString) REFERENCES NAME (NameString),
FOREIGN KEY (VceNumber) REFERENCES VOICE (VceNumber)
);
CREATE TABLE NAMEFAX
(
NameString
VARCHAR(50,20),
FaxNumber
CHAR(13),
PRIMARY KEY (NameString, FaxNumber),
FOREIGN KEY (NameString) REFERENCES NAME (NameString),
FOREIGN KEY (FaxNumber) REFERENCES FAX (FaxNumber)
);
CREATE TABLE MODEM
(
MdmNumber
CHAR(13) PRIMARY KEY,
NameString
VARCHAR(50,20) NOT NULL,
VceNumber
CHAR(13),
AddressCode
INTEGER,
B300
CHAR(1) DEFAULT "N",
B1200
CHAR(1) DEFAULT "N",
B2400
CHAR(1) DEFAULT "N",
FOREIGN KEY (NameString) REFERENCES NAME (NameString),
FOREIGN KEY (VceNumber) REFERENCES VOICE (VceNumber),
FOREIGN KEY (AddressCode) REFERENCES ADDRESS (AddressCode)
);
図 3-14
アドレス・ブック・データ・モデルの CREATE TABLE 文
モデルの実装 9-29
データベースの作成
コマンド・スクリプトの使用方法
対話式に文を入力することによって、データベースおよび表を作成するこ
とができます。ただし、文をもう一度または何度も入力する場合は、どの
ようにすればよいでしょうか。
テスト・バージョンが完成した後、プロダクション・バージョンを作成す
るために再度コマンドを入力する場合があります。また、複数のマシンに
同じデータ・モデルを実装することが必要となる場合もあります。この場
合、時間を節約してエラーを回避するために、データベースを作成するす
べてのコマンドをファイルに含めて、自動的に実行することができます。
スキーマのキャプチャー
モデルを実装する文をファイルにユーザー自身が書き込むことができます。
ただし、このためのプログラムを使用することも可能です。使用している
データベース・サーバーのマニュアルを参照してください。本書には、
データベースの内容を検査し、データベースを再作成するために必要なす
べての SQL 文を生成する dbschema ユーティリティー・プログラムについ
て記載されています。データベースの最初のバージョンを対話式に作成し、
目的に応じて変更を行うことができます。次に、dbschema を使用して、複
製を行うために必要な SQL 文を生成できます。
ファイルの実行
DB-Access または IBM Informix SQL は、SQL 文を対話式に入力するためのプ
ログラムで、コマンドのファイルから実行できます。オペレーティング・
システムのコマンド行からこれらの製品を使用する方法については、
DB-Access または IBM Informix SQL のマニュアルに記載されています。
DB-Access または IBM Informix SQL を起動して、ユーザーが作成したか、ま
たは dbschema によって生成されたコマンドのファイルを読み取り、実行
することができます。
サンプル
ほとんどの IBM Informix 製品には、stores5 と呼ばれるデモンストレーショ
ン・プログラム ( 本書の数多くの例で使用するプログラム ) が付属していま
す。stores5 データベースは、データベースを作成するために IBM Informix
製品を呼び出すオペレーティング・システム・コマンド・スクリプトとし
て用意されています。このコマンド・スクリプトをコピーし、ユーザー自
身のデータ・モデルを自動化するための基盤として使用できます。
9-30 モデルの実装
データベースの作成
表の構築
初期テストでの最も簡単な方法は、INSERT 文を DB-Access または
IBM Informix SQL に入力することによって、表を対話式に作成する方法で
す。または、IBM Informix 4GL かその他の言語でアプリケーション・プログ
ラムを作成している場合は、そのプログラムを使用して行を入力できます。
多くの場合、大きな表の初期行は、他のデータベースまたはオペレーティ
ング・システムに保持されているデータから取り出すことができます。一
括操作によって、データを新規データベースに移動することができます。
データが他の IBM Informix データベースにある場合は、さまざまな方法で
データを抽出できます。
IBM Informix OnLine を使用している場合は、データベースの INSERT 文の一
部として他のデータベースから目的のデータを選択できます。他のデータ
ベース・サーバーの場合は、データをファイルにエクスポートする必要が
あります。DB-Access、IBM Informix SQL、または IBM Informix 4GL の
UNLOAD コマンドを使用したり、ACE または IBM Informix 4GL でレポートを
作成して、出力をファイルに送ることができます。
ソースが別の種類のファイルまたはデータベースである場合は、フラット
ASCII ファイル、つまり各行が 1 つの表の行の内容を表す印字可能なデータ
のファイルに変換する必要があります。
データをファイルに入力すると、dbload ユーティリティーを使用してこの
データを表にロードできます。使用しているデータベース・サーバーのマ
ニュアルの dbload に関する説明を参照してください。DB-Access、
IBM Informix SQL、または IBM Informix 4GL の LOAD コマンドは、フラット
ASCII ファイルから行をロードすることもできます。
トランザクション・ログ機能をオフにすると、数百または数千行を挿入す
る場合の速度が大幅に向上します。障害が発生した場合、失われた作業は
簡単に再作成できるため、このような挿入のログを作成しても意味があり
ません。次に、大規模なバルク・ロード操作の手順を示します。
• 他のユーザーがデータベースを使用している可能性がある場合は、
DATABASE EXCLUSIVE 文を使用して排他的に使用する。
•
IBM Informix OnLine を使用している場合は、データベースのログ機能を
オフにするように管理者に依頼する。
既存のログを使用してデータベースを現在の状態に復旧できるだけでな
く、これらの行が失われた場合、すぐに一括挿入を再度実行してこれら
の行を復旧できます。
• 表にデータをロードする文またはユーティリティーを実行する。
モデルの実装 9-31
サマリー
• 新たにロードされたデータベースをアーカイブする。
IBM Informix OnLine を使用している場合は、完全なアーカイブまたは差
分アーカイブを行うことを管理者に依頼するか、または tbunload ユー
ティリティーを使用してデータベースのバイナリー・コピーを作成す
る。
その他のデータベース・サーバーを使用している場合は、オペレーティ
ング・システムのコマンドを使用して、データベースを表すファイルを
バックアップする。
• トランザクション・ログ機能を復元し、データベースに対する排他ロッ
クを解除する。
データベースを構築する手順をオペレーティング・システム・コマンドの
スクリプトに含めることができます。DB-Monitor と同等なコマンド行のコ
マンドを起動して、IBM Informix OnLine 管理者コマンドを自動化できます。
サマリー
本章では、データ・モデルを実装するために実行する手順について説明し
ました。
• モデルに使用するドメインまたは制約を指定し、各列に制約を割り当て
ることによってモデル・ダイアグラムを作成する。
• 対話型 SQL を使用してデータベースおよび表を作成する。
• データベースを再度作成する必要がある場合は、そのための SQL 文をオ
ペレーティング・システム用のコマンドのスクリプトに記述する。
• まず最初に対話型 SQL を使用し、次に一括操作を実行してモデルの表
を構築する。
• 場合によっては、バルク・ロード操作を繰り返し簡単に実行できるよう
にコマンド・スクリプトに記述する。
これで、データ・モデルを使用して、テストすることができます。デー
タ・モデルに非常に大きな表が含まれているか、または特定のクラスの
ユーザーからその一部を保護する場合は、さらに作業を行う必要がありま
す。このことについては、次の章で説明します。
9-32 モデルの実装
第
モデルの調整
概要 3
IBM Informix OnLine ディスク装置 4
チャンクおよびページ 4
DB 領域および BLOB 領域 5
ディスクのミラーリング 5
データベース 6
表および領域 6
ミラーリングの活用 6
一時スペースの共有 7
専用ハードウェアの割当て 7
追加のアクセス・アームの表への割当て 7
表領域 8
エクステント 9
エクステント・サイズの選択 9
エクステントの上限 11
表のフラグメント化をなくす 12
表サイズの計算 14
固定長の行の見積り 14
可変長の行の見積り 16
インデックス・ページの見積り 17
BLOB ページの見積り 19
BLOB データの格納 20
インデックスの管理 21
インデックスによって消費される領域 22
インデックスによって消費される時間 22
インデックスの選択 23
結合列 23
大きな表におけるフィルター列の選択 24
Order-By 列および Group-By 列 24
インデックスの修正を遅らせる重複キー 25
10
章
インデックスの削除 26
クラスター・インデックス 27
逆正規化 29
問合せを高速化するための行の短縮 29
長い文字列の排除 29
VARCHAR 文字列の使用 29
長い文字列のテキスト (TEXT) 型への変更 30
反復する文字列のシンボル・テーブルの作成 30
文字列の伴表への移動 31
ワイド表の分割 31
バルク別の分割 31
使用頻度別の分割 31
更新頻度別の分割 31
伴表の代償 32
トール表の分割 32
冗長データおよび導出データ 33
導出データの追加 33
冗長データの追加 34
同時実行性の最大化 35
競合の緩和 35
修正のスケジュール変更 36
更新日誌の使用 36
更新の分離および分散 37
分離された揮発性の列への表の分割 37
障害となっている表の分散 38
サマリー 38
10-2 モデルの調整
概要
前の章では、理論的なデータ・モデルの作成および実装の手順について説
明しました。これにより、通常、データベースは、適切なパフォーマンス
を得ることになります。これで、ジョブは完了です。
ただし、パフォーマンス要件がより厳しいアプリケーションもあります。
データベースの中には、非常に大きな表を持つもの、数多くのプログラム
によって並行して使用されるもの、応答時間に対する厳しい要件の下で動
作するプログラムによって使用されるもの、および非常に信頼性の高いも
のなどがあります。
データベース設計を調整することによって、これらの要件を満たすことが
できます。データ・モデルの理論的な正確さを犠牲にして、必要なパ
フォーマンスを得るようにする場合もあります。
ただし、変更を行う場合には、問合せが可能な限り効果的であることを確
認してください。データ・モデルを変更せずにパフォーマンスを向上させ
る方法については、第 4 章『問合せの最適化』を参照してください。
本章の後半部分では、次のトピックについて説明します。
•
IBM Informix OnLine で使用されるディスク記憶方法、およびそのパ
フォーマンスと信頼性
• 表とインデックスのサイズの計算方法、およびこれらの数値を使用して
問合せの実行時間を見積もる方法
• インデックスを追加する利点およびコスト
• パフォーマンスの向上に対する理論的な純度を下げることになるデー
タ・モデルを「非正規化」する方法
• 複数のプログラム間の同時実行性の向上に関する提案
モデルの調整 10-3
IBM Informix OnLine ディスク装置
IBM Informix OnLine ディスク装置
IBM Informix OnLine は、ディスク装置ディレクトリーを管理します。可能
な限りエクステントを大きくするために、ホスト・オペレーティング・シ
ステムをバイパスして、ロウ・ディスク領域を使用します ( このことが可
能なエクステントは、オペレーティング・システムによって異なります )。
デバイス 0x7d
ホスト・ファイル・
システム
デバイス 0x7c
BLOB 領域 rasters
デバイス 0x7f
デバイス 0x7e
DB 領域 large
DB 領域 root
図 10-1
DB 領域 temps
チャンクと DB 領域の関係
ディスク管理の方法は複雑ではありません。ただし、領域の大きさやコン
テキストによって、チャンク、DB 領域 ( または BLOB 領域 )、ページ、エ
クステント、および表領域 など、さまざまな用語が使用されています。
チャンクおよびページ
物理ストレージ域の基本単位は、チャンク です。チャンクは、IBM Informix
OnLine 専用のディスク装置の単位です。チャンクは、通常、物理デバイ
ス、つまりディスク・ドライブです。ただし、チャンクは、ディスクの一
部である場合、または単なるファイルである場合があります。いずれの場
合でも、チャンクは、オペレーティング・システムによって、IBM Informix
OnLine の排他制御の中にあると識別される領域の単位を意味します。
ページ は、ディスク入力 / 出力 (I/O) の基本単位です。各チャンクのすべて
の領域は、ページに分割されます。すべての入出力は、ページ全体の単位
で行われます。ページのサイズは、表に対して使用されるすべてのチャン
クで同じです。このサイズは、IBM Informix OnLine システムのインストー
ル時に設定されます。
10-4 モデルの調整
IBM Informix OnLine ディスク装置
DB 領域および BLOB 領域
領域 は、常に 1 つ以上の完全なチャンクで構成されています。領域には 1
つのチャンクが含まれているため、領域とチャンクは同一となります。た
だし、領域が複数のチャンクで構成されている場合、IBM Informix OnLine
では、複数のチャンクがページの単一のシーケンスとして表示されます。
領域は、使用方法に応じて、DB 領域 または BLOB 領域 のいずれかとなり
ます。領域にデータベースおよび表が含まれている場合、その領域は DB
領域です。バイナリー・ラージ・オブジェクト (BLOB データ型、テキスト
(TEXT) 型およびバイト (BYTE) 型 ) のみが格納されている領域は、BLOB 領域
です。チャンクは、作成時に領域に割り当てられます。また、チャンクは、
後で領域に追加することもできます。
まず最初に、ルート DB 領域が作成されます。この領域は、常に存在しま
す。この領域には、他のすべての領域とチャンクに関する制御情報が格納
されているため、最も重要な領域となります。
単一のデータベースの一部は、複数の DB 領域に出現する場合があります。
ただし、単一の表は、常に完全に単一の DB 領域に含まれています。
ディスクのミラーリング
個々の領域は、ミラーリング することができます。ミラーリングされた領
域のチャンクは、同じサイズの他のチャンクとペアになります。ページが
チャンクの 1 つに書き込まれる場合は、必ずミラー・チャンクにも書き込
まれます。1 つのチャンクにハードウェア障害が発生すると、データベー
ス・サーバーは、そのミラーを使用して、中断することなく処理を続行し
ます。ブレークしたチャンクがサービスに復元される場合 ( または代替
チャンクが割り当てられる場合 )、IBM Informix OnLine は、作動している
チャンクを使用して自動的にチャンクを同じ状態に戻し、操作を続行しま
す。
DB 領域をミラーリングする場合は、ルート DB 領域もミラーリングする必
要があります。このようにしないと、ハードウェア障害が発生した場合に、
ミラーのあるなしに関係なく、IBM Informix OnLine のデータを使用するこ
とができなくなります。
ご使用のデータベースにおいて、ハードウェア障害に直面した場合の信頼
性に対して非常に厳しい要件が設定されている場合は、このデータベース
をミラーリングされた DB 領域内に置くように調整する必要があります。
次のパラグラフで説明されているように、個々の表は、特定の DB 領域内
に置くことができます。これにより、一部の表をミラーリングされた領域
に置き、他の表を通常の領域に置くことも可能になります。
モデルの調整 10-5
IBM Informix OnLine ディスク装置
データベース
データベースは、最初は DB 領域内に常駐しています。データベースは、
CREATE DATABASE 文によってその場所に配置されます。次の例では、
dev0x2d という名前の DB 領域内にデータベースが作成されます。
CREATE DATABASE reliable IN dev0x2d WITH BUFFERED LOG
いずれの DB 領域も指定されていない場合、データベースはルート DB 領域
に配置されます。データベースが DB 領域内にある場合は、次のような状
態になります。
• システム・カタログ表は、DB 領域内に格納されている。
• DB 領域は、表 ( 他の DB 領域内で明示的に作成されたものを除く ) のデ
フォルトの格納場所になる。
表および領域
データベースは、完全に DB 領域内に常駐しています ( この BLOB 値は、別
の BLOB 領域内に常駐している場合もあります )。DB 領域が指定されてい
ない場合、表は、そのデータベースが常駐する DB 領域内に常駐します。
次の部分的な例では、misctabs という名前の DB 領域内に表が作成されま
す。
CREATE TABLE taxrates (…column specifications…) IN misctabs
表を特定の DB 領域に置くと、さまざまな目的を達成することができます。
これらの目的の一部については、次のパラグラフ内で説明します。
ミラーリングの活用
非常に重要なアプリケーションによって使用されるすべての表は、ミラー
リングされた DB 領域内に配置されます。ミラーリングされた DB 領域内に
データベースを作成して、デフォルトで、重要な表をその DB 領域内に常
駐させることもできます。そのデータベースに含まれていても、重要なプ
ログラムでは使用されない表は、ミラーリングされていない領域に配置す
ることができます。
10-6 モデルの調整
IBM Informix OnLine ディスク装置
一時スペースの共有
データベースが大きくてディスク領域が足りない場合、通常の DB 領域で
は、問合せのパフォーマンス向上に役立つ大きな一時表に対して十分なス
ペースを確保できなくなることがあります。ただし、一時表は、それを作
成したプログラムが終了されるまでしか存在しません。また、そのプログ
ラムで表がすぐに削除された場合は、表の存在期間はさらに短くなります。
一時表に対して、単一の DB 領域をセットアップします。この領域は、数
多くのプログラムによって繰り返し使用される場合があります。
専用ハードウェアの割当て
DB 領域は、チャンクと等しい場合があります。また、チャンクは、デバイ
スと等しい場合があります。このため、表は、表専用のディスク・デバイ
ス上に配置することができます。ディスク・ドライブのパフォーマンス・
レベルが異なる場合は、使用頻度の最も高い表を最高速のドライブ上に配
置します。
使用頻度の高い表に専用のアクセス・アームを与えると、他の表を使用す
るアプリケーションとの競合を少なくすることができます。ただし、次の
パラグラフで説明するように、その表自体が複数のデバイスに渡っていな
い限り、同じ表を使用するプログラム間の競合が減少することはありませ
ん。
追加のアクセス・アームの表への割当て
DB 領域は、複数のチャンクで構成されている場合があります。また、各
チャンクは、それぞれ異なるディスクを表す場合があります。このため、
単一の表に複数のディスク・アクセスを割り当てることができます。
図 10-2 に、グラフィック用語の例を示します。
デバイス 0x21
デバイス 0x27
デバイス 0x22
DB 領域 three_arms
図 10-2
3 つのディスクに分散された DB 領域
モデルの調整 10-7
IBM Informix OnLine ディスク装置
three_arms という名前の DB 領域は、3 つの異なるディスク上のチャンクで
構成されています。各チャンクは、重要で使用頻度の高い表の約 1/3 のサ
イズとなります (3 番目のチャンクは、大きめに設定されています )。複数
のプログラムがその表に問合せを行うと、入出力操作は 3 つのディスクに分
散され、ハードウェアの使用の競合が削減されます。
この調整において、複数のディスクは、相互にミラーの役割を果たすこと
ができます。例えば、デバイス 0x21 は 0x27 に、0x27 は 0x22 に、0x22 は
0x21 にミラーリングされます。任意の 2 つのデバイスが操作可能である限
り、その DB 領域は使用可能です ( ただし、ディスク・コントローラーなど
の単一のハードウェアが 3 つのディスクすべてに共通である場合は、この
ミラー調整を行っても、そのコンポーネントは障害に対して脆弱なままで
す )。
表領域
表に割り当てられたすべてのディスク領域の合計が、その表の表領域 で
す。表領域には、データに割り当てられたページ ( 表の行 ) 、およびイン
デックスに割り当てられたページがインクルードされます。表領域内に配
置された BLOB 列で使用されるページはインクルードされますが、異なる
BLOB 領域内の BLOB データで使用されるページはインクルードされませ
ん ( この選択については、10-20 ページの『BLOB データの格納』で説明し
ます )。
表領域は、アカウンティング・エンティティーのみです。DB 領域の特定の
部分には対応していません。表を構成するインデックスおよびデータ・エ
クステントは、DB 領域に渡って分散させることができます。
tbcheck ユーティリティー (-pt オプションを指定されたもの ) は、それぞれ
に割り当てられたページ数や使用中のページ数など、表領域の状態に関す
る情報を戻します。この情報を使用して、表の成長を長時間に渡ってモニ
ターすることができます。
10-8 モデルの調整
IBM Informix OnLine ディスク装置
エクステント
表に行を追加すると、IBM Informix OnLine は、エクステント と呼ばれる単
位で、その行にディスク領域を割り当てます。各エクステントとは、DB 領
域から物理的に連続しているページのブロックのことです。DB 領域が複数
のチャンクを構成する場合でも、エクステントは常に完全に単一のチャン
クに割り当てられ、連続性が保持されます。
連続性は、パフォーマンスにとって重要です。データのページが連続して
いる場合、データベース・サーバーが行を順次に読み取るときのディス
ク・アームの動作は最小化されます。エクステントのメカニズムは、次の
競合する要件間で妥協されています。
•
•
•
•
ほとんどの DB 領域が複数の表によって共有される。
一部の表のサイズが不明である。
表は、一定でない時間および速度で成長することが可能。
表のすべてのページが隣接しており、パフォーマンスが最大化される。
表のサイズが不明であるため、表領域は、事前に割り当てることができま
せん。このため、エクステントは必要な場合にのみ追加されますが、より
良いパフォーマンスを得るために、すべてのエクステント内のすべての
ページは連続したものとなっています。
エクステント・サイズの選択
表を作成する場合は、最初のエクステントのサイズ、および表が成長する
に従って追加されるエクステントのサイズを指定することができます。追
加されたエクステントのサイズは、後で、ALTER TABLE 文を使用して変更
することができます。次の部分的な例では、0.5 MB の初期エクステントお
よび 100 KB の追加エクステントを持つ表が作成されます。
CREATE TABLE big_one (…column specifications…)
IN big_space
EXTENT SIZE 512
NEXT SIZE 100
次の例では、その表の次エクステントのサイズが 50 KB に変更されます。
既存のエクステントに対しては無効です。
ALTER TABLE big_one MODIFY NEXT SIZE 50
モデルの調整 10-9
IBM Informix OnLine ディスク装置
次のような表の次エクステントのサイズは、パフォーマンスにとってあま
り重要ではありません。
• 小さな表には単一のエクステントのみがある ( それ以外の場合は、表は
小さくない )。この表が頻繁に使用される場合、この表の大部分はメモ
リーにバッファリングされます。
• 頻繁に使用されない表は、サイズに関係なく、パフォーマンスにとって
重要ではない。
• 専用の DB 領域内に常駐する表は、常に古いエクステントと隣接する新
しいエクステントを受け取る。これらのエクステントは、隣接して単一
の大きなエクステントとして機能するため、サイズは重要ではありませ
ん。
これらの種類の表にエクステント・サイズを割り当てるときに考慮する必
要があることとは、エクステントを数多く作成せずに済むようにすること
です。エクステントの数が多くなると、データベース・サーバーが記録作
業に割り当てることができる残り時間が少なくなります。また、使用でき
るエクステントの数には上限があります ( これについては、10-11 ページの
『エクステントの上限』のセクションで説明します )。
複数の大きな成長する表が DB 領域を共有する場合、次エクステントのサ
イズが重要になります。異なる表に追加されたエクステントはインター
リーブされるため、新しいエクステントは、それぞれ順次に読み取るとき
に作成される long 型シークを表します。また、ディスク・アームが非順次
で読み取るときの範囲となる合計距離も延長されます。
DB 領域のサイズを除き、エクステントのサイズに上限はありません。表の
最終的なサイズが判明している場合 ( または、25% 以内であると予測でき
る場合 ) は、すべての領域を初期エクステントに割り当てます。表が不明
のサイズまで確実に成長する場合は、それぞれ少数のエクステントで DB
領域を共有できるよう、次エクステント・サイズを割り当てます。次に、
その一例を示します。
• 表間で DB 領域が共有される率を決定する。例えば、3 つの表間で DB
領域を分割する率を
0.4 : 0.2 : 0.3 ( 小さな表およびオーバーヘッド用に 10% を予約 ) にするこ
とができます。
• 各表に、DB 領域でその表が共有する部分の 1/4 を初期エクステントと
して割り当てる。
• 各表に、その共有部分の 1/8 を次のエクステントのサイズとして割り当
てる。
tbcheck を使用して、表の成長を定期的に監視します。
10-10 モデルの調整
IBM Informix OnLine ディスク装置
DB 領域が満たされるに従って指定したサイズのエクステントを作成するの
に十分な連続的な領域がなくなった場合は、どのように対処するとよいの
でしょうか。このような場合には、IBM Informix OnLine によって、可能な
限り大きな連続的なエクステントが割り当てられます。
エクステントの上限
いずれの表でも、数多くのエクステントを取得することはできません。多
くのエクステントを取得する場合もありますが、使用可能なエクステント
の数には上限があります。上限に達してからエクステントを追加しようと
すると、ISAM エラー -136 ( エクステント不足です ) が INSERT 要求の後に発
生します。
上限は、ページ・サイズと表定義によって異なります。特定の表のエクス
テントの上限を知るには、次のように一連の値を計算します。
pagesize =
ページのサイズ ( ヘッド BUFFSIZE の下で tbstat -c によって報
告される )
colspace =
4 ×表内の列数
ixspace =
12 ×表内のインデックス数
ixparts =
extspace =
4 × 各インデックス内で名前が付けられた列数
pagesize - (colspace + ixspace + ixparts + 84)
表は、extspace/8 よりも多くのエクステントを所有することはできません。
ページ・サイズが 2,048 の場合、デモンストレーション・データベースの
customer 表は、図 10-3 で計算された 234 個よりも多くのエクステントを所
有することはできません。
上限を超えていないことを確認する場合に役立つように、IBM Informix
OnLine は、新規のエクステントが作成されるごとに、エクステントの数を
チェックします。作成されたエクステントが 64 番目または 64 の倍数番目
の場合、その表の次エクステントのサイズは自動的に倍になります。
変数
pagesize
colspace
ixspace
ixparts
extspace
limit
図 10-3
値
2,048
40
36
12
1,876
234
基本
tbstat の出力
10 列
3 インデックス
各インデックスごとに 1 列
2,048 - (40 + 36 + 12 + 84)
extspace/8
エクステントの上限を決定するために使用される値
モデルの調整 10-11
IBM Informix OnLine ディスク装置
表のフラグメント化をなくす
表に多くのエクステントが追加されると、問合せのパフォーマンスが低く
なります。このことは、複数の成長している大きな表が DB 領域を共有す
る場合にのみ発生します。表が同時に成長すると、新規エクステントおよ
びインデックス・ページはインターリーブされ、任意の単一の表のエクス
テント間に大きなギャップが発生します。この状態は、図 10-4 で図式化さ
れています。
表1
表2
表3
図 10-4
フラグメント化された DB 領域
また、この図は、未使用の領域のギャップも示します。未使用の領域は、
エクステントが割り当てられたときに存在したがその後削除された表に
よって作成された可能性があります。
図 10-4 に示されているような無秩序な状態は、2 とおりの理由で、パ
フォーマンスに悪影響を与えます。任意の表への順次アクセスの中で、い
くつかの long 型シークが作成されます。任意の表への非順次アクセスの場
合は、ディスクがその DB 領域全体をシークする必要がある場合がありま
す。図 10-5 に示されているように、DB 領域を再作成して、表を再度コン
パクトにすることもできます。DB 領域内の再編成された表の相対順序は重
要ではありません。それぞれの表のページが共に存在していることが重要
です。表を順次に読み取る場合、long 型シークはありません。表を非順次
で読み取る場合、ディスク・アームの範囲は、その表が占有する領域のみ
です。
.
表1
表2
表3
図 10-5
10-12 モデルの調整
DB 領域を再編成して、表をコンパクトにする
IBM Informix OnLine ディスク装置
次の手順に従って、DB 領域を再編成します。
• tbunload ユーティリティーを使用して、DB 領域内の表をそれぞれテー
プにコピーする。
• DB 領域内のすべての表を削除する。
• tbload ユーティリティーを使用して表を再生する。
tbload ユーティリティーは、以前表に含まれていたものと同じプロパ
ティー ( 同じエクステント・サイズなど ) と共に表を再生します。新規のエ
クステントが以前のエクステントに隣接して作成されると、この 2 つのエ
クステントは単一のエクステントとして扱われます。
DB-Access、IBM Informix SQL、または IBM Informix 4GL の UNLOAD コマンド
を使用して表をアンロードし、コンパニオンの LOAD コマンドまたは
dbload ユーティリティーを使用して、表を再ロードすることもできます。
ただし、これらの操作では表が文字フォームに変換されますが、tbload お
よび tbunload では、ディスク・ページのバイナリー・コピーが使用されま
す。
単一の表を再編成する場合、他に 2 つの方法があります。ALTER TABLE コ
マンドを使用して列を追加または削除するか、または列のデータ型を変更
する場合、その表はコピーされて再構成されます。クラスター・インデッ
クスを作成するか、またはインデックスをクラスターに変更する場合、そ
の表はソートされ、再書き込みされます (10-27 ページの『クラスター・イ
ンデックス』を参照 )。いずれの場合でも、表は DB 領域の別のエリアに書
き込まれます。ただし、他の表がその DB 領域内にある場合は、すべての
新規のエクステントが隣接するという保証はありません。
モデルの調整 10-13
表サイズの計算
表サイズの計算
このセクションでは、ディスク・ページ内の表およびインデックスの概算
のサイズを計算する方法について説明します。前のセクションと同様、こ
れは IBM Informix OnLine にのみ適用されます。この種類の見積りは、ディ
スク上のデータベースのレイアウトを計画するときに役立ちます。
これらの計算の目的は、表の異なる部分を保持するために使用されるディ
スク・ページの数を見積もることです。この表がすでに存在するか、また
はシミュレートされたデータを使用して現実的なサイズのデモンストレー
ション表を作成することができる場合は、見積りを行う必要はありません。
tbcheck を実行して、正確な数を取得することができます。
一連の値を計算して、見積りを作成することができます。次の値は、すべ
ての見積りで必要となります。値を次のようにします。
estrows =
表が標準サイズになったときに所有される行数の見積り。
pagesize =
ページのサイズ
( ヘッド BUFFSIZE の下で tbstat -c によって報告される )。
pagesize - 28
( ディスク・ページ上のデータ用に使用可能な領域 )。
pageuse =
この章の計算では、floor(x) は x 未満の最長精度整数を意味し、ceiling(x) は、
x より大きな最短整数を意味します。
固定長の行の見積り
表に可変長文字 (VARCHAR) 型列が含まれていない場合、その行はすべて同
じサイズになります。次の追加の変数を計算します。値を次のようにしま
す。
10-14 モデルの調整
rowsize =
表内のすべての列のサイズの合計 + 4 バイト。異なるデータ
型のサイズについては、第 9 章で説明します。テキスト (TEXT)
型列およびバイト (BYTE) 型列をサイズ 56 として扱います。
homerow =
if (rowsize ≦ pageuse) then rowsize
else 4 + remainder (rowsize/pageuse)
表サイズの計算
行がページより大きい場合は、可能な限り多くの全ページが
行の終わりから削除され、別の拡張ページに格納されます。
homerow がホーム・ページ上に保持される先行部分のサイズ
になります。行がページにフィットする場合、値 homerow は、
単純に rowsize になります。
overpage =
if (rowsize ≦ pageuse) then 0
else floor (rowsize/pageuse)
overpage が各行に必要な拡張ページ数になります。行がペー
ジにフィットする場合は 0 になります。
datrows =
min(255,floor(pageuse/homerow))
datrows が単一のページにフィットする行数 ( または先行する
行数 ) になります。行が非常に短い場合でも、1 つのページに
つき 255 行が上限です。
datpages =
ceiling(estrows/datrows)
expages =
estrows × overpage
表には、行用に約 datpages + expages のディスク・ページが必要です ( テキ
スト (TEXT) 型列およびバイト (BYTE) 型列用の追加ページは、10-19 ページの
『BLOB ページの見積り』で見積もられます )。customer 表用の見積りにつ
いては、図 10-6 に示されています。
図 10-6
変数
estrows
pagesize
pageuse
rowsize
見積り
1,500
2,048
2,020
138
homerow
overpage
datrows
datpages
expages
134
0
14
108
0
見積りの基本
会社のビジネス・プラン
tbstat の出力
pagesize - 28
合計 4+
列
customer_num
fname
lname
company
address1
address2
city
state
zipcode
phone
rowsize ≦ pageuse
rowsize ≦ pageuse
floor (pageuse/homerow)
ceiling (estrows/datrows)
estrows × overpage
データ型
SERIAL
CHAR(15)
CHAR(15)
CHAR(20)
CHAR(20)
CHAR(20)
CHAR(15)
CHAR(2)
CHAR(5)
CHAR(18)
サイズ
4
15
15
20
20
20
15
2
5
18
customer 表のサイズの見積り
モデルの調整 10-15
表サイズの計算
可変長の行の見積り
1 つ以上の可変長文字 (VARCHAR) 型列を含む表の行は、可変長になります。
このため、不確定要素が生じます。このデータに基づいて、それぞれの可
変長文字 (VARCHAR) 型列の標準サイズの見積りを作成する必要があります。
IBM Informix OnLine は、可変サイズの行に領域を割り当てる場合、最大 サ
イズの追加の行に十分なスペースがないと、ページがいっぱいである見な
します。このため、ページに割り当てられる行数が制限される場合があり
ます。次の変数を計算します。
maxrow =
表内のすべての列の最大サイズの合計 + 4 バイト。テキスト
(TEXT) 型列およびバイト (BYTE) 型列をサイズ 56 として扱いま
す。
typrow =
表内のすべての列の見積りの標準サイズの合計 + 4 バイト。
homerow =
if (typrow ≦ pageuse) then typrow
else 4 + remainder (typrow/pageuse)
homerow がホーム・ページにフィットする標準行の数になり
ます。1 ページで十分な場合、これは typrow になります。
overpage =
if (typrow ≦ pageuse) then 0
else floor (typrow/pageuse)
overpage が標準行に必要な拡張ページの数になります。標
準行がページにフィットする場合は 0 になります。
homemax =
if (maxrow ≦ pageuse) then maxrow
else 4 + remainder (maxrow/pageuse)
datrows =
homemax がデータベース・サーバーの予約要求になりま
す。
floor ((pageuse - homemax)/typrow)
datpages =
データベース・サーバーがページがいっぱいであると判別
する前に、datrows がそのページにフィットする標準行の数
になります。
ceiling (estrows/datrows)
expages =
estrows × overpage
表には、行用に約 datpages + expages のディスク・ページが必要です ( テキ
スト (TEXT) 型列およびバイト (BYTE) 型列用の追加ページは、10-19 ページの
『BLOB ページの見積り』で見積もられます )。catalog 表用の見積りについ
ては、図 10-6 に示されています。
10-16 モデルの調整
表サイズの計算
図 10-7
変数
estrows
pagesize
pageuse
maxrow
見積り
5,000
2,048
2,020
381
typrow
homerow
overpage
homemax
datrows
datpages
expages
191
191
0
381
8
625
0
見積りの基本
会社のビジネス・プラン
tbstat の出力
pagesize -28
合計 4+:
列
データ型
最大サイズ標準
catalog_num
SERIAL
4
4
stock_num
SMALLINT
2
2
manu_code
CHAR(3)
3
3
TEXT
56
56
cat_descr
cat_picture
BYTE
56
56
cat_adv
VARCHAR(255,65) 256
66
typrow ≦ pageuse
typrow ≦ pageuse
maxrow ≦ pageuse
floor ((pageuse - homemax)/typrow)
ceiling (estrows/datrows)
estrows × overpage
catalog 表のサイズの見積り
インデックス・ページの見積り
tblspace には、データのページだけでなくインデックス・ページも含まれて
います。インデックス・ページは、全体の大部分を占める場合があります。
インデックス・エントリーは、キー およびポインター で構成されていま
す。キーは、データの単一の行からの 1 つ以上のインデックス付き列のコ
ピーのことです。ポインターは、キー値を持つ行を格納するために使用さ
れる 4 バイトの値のことです。
一意のインデックスには、表内の各行のために上記のような単一のエント
リーが含まれています。また、B+ ツリー構造体を作成するポインターの追
加ページも一部含まれています ( インデックス構造体については、4-29
ページの『インデックスの構造』で説明します )。重複可能な場合、イン
デックスには、ポインターよりも少ない数のキーが含まれています。つま
り、単一のキーの後にポインターをリストし続けることができます。
インデックスに関することがこれですべてである場合は、スペース所要量
の見積りは簡単です。ただし、インデックス・リーフ・ページでは、キー
圧縮 と呼ばれる技法が使用されています。この技法によって、データベー
ス・サーバーは、フィットするよりも多くのキーをページに書き込むこと
ができます。キー圧縮によって節約される領域は、キーのコンテンツ、さ
らにページごとおよびインデックスごとによって異なります。
モデルの調整 10-17
表サイズの計算
コンパクト・インデックスのサイズを見積もるには ( キー圧縮によって保
存された領域は無視 )、値を次のようにします。
keysize =
1 つ以上のインデックス付き列の幅の合計
pctuniq =
このインデックスの中に予期される一意なエントリーの数。
estrows で区切ります。
一意性インデックスか、または重複する値が発生するイン
デックスの場合は、1.0 にします。有効な数値の中に重複が存
在する場合は、pctuniq を 1.0 よりも小さくします。
entsize =
pagents =
(keysize × pctuniq) + 4
floor (pageuse/entsize)
leaves =
それぞれのインデックス・ページには、約 pagents のエント
リーが存在します。
ceiling (estrows/pagents)
インデックスには、約 leaves のリーフ・ページが存在します。
branches =
ceiling (leaves/pagents)
約 branches のノンリーフ・ページが存在します。
コンパクトなインデックスには、leaves + branches のページが含まれていま
す。customer 表内の 2 つのインデックスの見積りについては、10-19 ページ
の図 10-8 に示されています。
行が削除されて新規の行が挿入されると、インデックスは小さくなる場合
があります。つまり、そのリーフ・ページのエントリーは、いっぱいでは
なくなります。一方、キー圧縮が有効な場合、インデックスはさらに小さ
くなる場合があります。この方法では、ほとんどのインデックスに対する
控え目な見積りが作成されます。インデックス領域が重要な場合は、実際
のデータを使用して大きなテスト用インデックスを作成し、tbcheck ユー
ティリティーを使用してそのサイズをチェックします。
10-18 モデルの調整
表サイズの計算
図 10-8
変数
estrows
pagesize
pageuse
見積り
1,500
2,048
2,016
見積りの基本
会社のビジネス・プラン
tbstat の出力
pagesize
keysize
pctuniq
entsize
pagents
leaves
branches
4
1.0
12
168
9
1
customer_num は 4 バイト
一意性インデックス
4 x 1.0 + 8
floor (2,016/12)
ceiling (1,500/168)
ceiling (9/168)
keysize
pctuniq
entsize
pagents
leaves
branches
2
0.033
8.066
249
7
1
state は CHAR(2)
1,500 行の中の 50 の状態
2 x 0.033 + 8
floor (2,016/8.066)
ceiling (1,500/249)
ceiling (7/168)
customer 表からの 2 つのインデックスのサイズの見積り
BLOB ページの見積り
磁気ディスクに格納されたバイト (BYTE) 型データ項目およびテキスト (TEXT) 型
データ項目は、表領域内か、または異なる BLOB 領域内の行やインデック
ス・ページの間に散在する別々のページに格納されます。各 BLOB データ項
目では、ページの 1 つの整数が占有されます。それぞれの BLOB 列ごとに、
値を次のようにします。
typage =
標準サイズの項目を格納するために必要な全ページ数
nnpart =
この列が非 NULL である列の小数部
totpage=
typage × estrows × nnpart
列の値は、約 totpage ページを占有します。catalog 表には (10-15 ページの
図 10-6 を参照 )、2 つの BLOB ページがあります。その見積りは、次のよ
うに推測されます。
cat_descr 列の場合、説明のテキストは大きくてもダブルスペース・ページ
です。これは、250 ワードまたは約 1,500 文字であるため、typage = 1 にな
ります。各エントリーごとに説明があるため、nnpart = 1.0 になります。こ
れにより、totpage = 1 × 5,000 × 1.0= 5,000 ページのデータになります。
cat_picture 列には、コンピューターで読み込めるフォームの線画が含まれ
ています。これらのピクチャーのうち数点を調べると、サイズには大きな
差があり、標準ファイルには約 75,000 バイトのデータが含まれていること
が分かります。このため、typage = 38 となります。マーケティング部門は、
モデルの調整 10-19
表サイズの計算
4 つのうちの 1 つのエントリーを持つピクチャーを格納するものと見積もり
ます (nnpart = 0.25)。このため、totpage =38 × 5,000 × 0.25= 47,500 ページ
のデータになります。
表が作成されてロードされると、tbcheck ユーティリティーの -ptT オプ
ションを使用して、BLOB ページの使用方法をチェックできるようになり
ます。
BLOB データの格納
磁気ディスク上にバイト (BYTE) 型またはテキスト (TEXT) 型の列を作成する
場合は、その列のデータを表領域に格納するか、または BLOB 領域に格納
するかを選択することができます。次の例では、テキスト (TEXT) 型の値は
表領域に格納され、バイト (BYTE) 型の値は、rasters という名前の BLOB 領
域に格納されます。
CREATE TABLE examptab
(
pic_id SERIAL,
pic_desc TEXT IN TABLE,
pic_raster BYTE IN rasters
)
テキスト (TEXT) 型または バイト (BYTE) 型の値は、必ず表の行とは別に格納
されます。56 バイトの記述子のみ、行と共に格納されます。ただし、値自
体は、少なくとも 1 つのディスク・ページを占有します。
BLOB 値が表領域に格納されると、そのデータのページは、行を含むペー
ジ間に散在することになります。この結果、表のサイズが大きくなります。
BLOB ページでは、行を含むページが分離され、ディスク上に広げられま
す。データベース・サーバーが行のみを読み取り、BLOB データを読み取
らない場合に、BLOB ページが別々に格納されていると、ディスク・アー
ムは、通常よりも大きく移動する必要があります。データベース・サー
バーは、BLOB 列を抽出しない任意の SELECT 操作の場合や、フィルター式
を使用して行をテストする場合は、行ページのみを走査します。
DB 領域へのディスクの入出力がバッファーに格納されることも考慮に入れ
る必要があります。ページは、すぐに必要となる場合はストレージに格納
されます。ページの書き込み時に、要求元のプログラムは、実際のディス
ク書き込みが行われる前に続行することができます。
ただし、BLOB 領域へのディスク入出力は、バッファーに格納されませ
ん。BLOB 領域ページは、再度読込みが行われるバッファーには保存され
ません。要求元のプログラムは、そのプログラムへのすべての出力が完了
するまで続行することができません。これは、BLOB 領域への入出力の量
10-20 モデルの調整
インデックスの管理
が多いことが予期されるためです。これらのページが標準のバッファリン
グ機構を介して渡される場合は、バッファーを占領するため、優れたパ
フォーマンスに役立つインデックス・ページやその他のページを排除する
可能性があります。
この場合は、パフォーマンスを最大にするために、テキスト (TEXT) 型また
はバイト (BYTE) 型の行を、次のいずれかの状況にある BLOB 領域に格納し
ます。
• 単一のデータ項目が、それぞれ 1 つまたは 2 つのページよりも大きい場
合。DB 領域に保持されている場合は、これらを転送すると、ページ・
バッファーの効果が減少します。
• BLOB データのページ数が行データのページ数の半数よりも多い場合。
DB 領域に保持されている場合は、表が大きくなり、その表に対する問
合せが遅くなります。
比較的小さく、不揮発性の表の場合は、次の方法で、専用の BLOB 領域の
効果を得ることができます。BLOB 列が NULL である行と共に表全体を
ロードします。すべてのインデックスを作成します。これにより、行ペー
ジおよびインデックス・ページが隣接します。すべての行を更新して、
BLOB データをインストールします。BLOB ページは、表領域内で、行お
よびインデックス・データのページの後に続きます。
インデックスの管理
インデックスは、一意である必要のあるすべての列 ( または列の合成 ) で必
要です。また、第 4 章で説明するように、インデックスを使用して、問合
せオプティマイザーは、いくつかの方法で問合せを高速化することができ
ます。オプティマイザーは、次の場合にインデックスを使用することがで
きます。
• 表の反復する順次走査を非順次アクセスに置き換える。
• インデックス付き列のみを指名する式を処理する場合に、すべての行
データを読み取らないようにする。
•
GROUP BY 節および ORDER BY 節を実行する場合に、
ソート ( 一時表の作
成を含む ) を行わないようにする。
この結果、右の列のインデックスは、数千、数万、極端な場合には数百万
の問合せ中のディスク操作を減らすことができます。ただし、インデック
スに関連する代償もあります。
モデルの調整 10-21
インデックスの管理
インデックスによって消費される領域
インデックスの代償として、まず第 1 にディスク領域を挙げることができ
ます。見積り方法については、10-17 ページの『インデックス・ページの見
積り』で説明します。インデックスは、インデックス付き列の中にすべて
の一意なデータ値のコピーを格納します。また、表内のすべての行に対す
る 4 バイトのポインターも格納します。この情報によって、表領域の所要
量に数多くのページが追加される場合があります。行ページと同じ数のイ
ンデックス・ページを所有することは簡単です。
インデックスによって消費される時間
インデックスの代償の 2 番目として、表の修正にかかる時間を挙げること
ができます。以降の説明では、インデックス・エントリーを格納するため
に、約 2 ページ読み取る必要があるものと想定しています。このことは、
インデックスがルート・ページ、単一の中間レベル、およびリーフ・ペー
ジで構成され、ルート・ページがすでにバッファー内にある場合に当ては
まります。非常に大きな表のインデックスには 2 つの中間レベルがあるた
め、エントリーをルックアップする場合は、約 3 ページ読み取られること
になります。
変更された行を格納するために、単一のインデックスが使用されたものと
想定します。このインデックス・ページは、ページ・バッファーの中で見
つかります。ただし、変更が必要な他のすべてのインデックスのページは、
ディスクから読み取る必要があります。
上記のことを前提とすると、インデックス管理では、次のようにさまざま
な修正時間が加算されます。
• 表から行を削除する場合は、そのエントリーをすべてのインデックスか
ら削除する必要がある。
削除された行のエントリーは、ルックアップ (2 または 3 ページ・イン )
され、リーフ・ページは再書込み (1 ページ・アウト ) される必要があり
ます。つまり、インデックスごとに 3 ~ 4 ページにアクセスすることに
なります。
• 行を挿入する場合は、そのエントリーをすべてのインデックスに挿入す
る必要がある。
挿入された行のエントリーの位置を検索 (2 または 3 ページ・イン ) し、
再書込み (1 ページ・アウト ) する必要があります。つまり、インデック
スごとに 3 ~ 4 ページにアクセスすることになります。
• 行を更新する場合は、変更された列に適用されるインデックスごとにそ
のエントリーをルックアップする必要がある (2 または 3 ページ・イ
ン )。また、リーフ・ページを再書込みして、古いエントリーを除去し
10-22 モデルの調整
インデックスの管理
ます (1 ページ・アウト )。その後、新規の列の値を同じインデックス内
に配置し (2 または 3 ページ・イン )、入力された行に配置する必要があ
ります ( さらに 1 ページ・アウト )。
挿入および削除によって、リーフ・ページ上のエントリー数が変更されま
す。リーフ・ページにはフルのものと空のものがあるため、事実上、すべ
ての pagents 操作ごとに、いくつかの追加作業が行われることになります。
ただし、pagents は、通常、100 よりも大きいため、これが発生するのは 1%
未満の時間であり、見積りでは無視することができます。
つまり、行が無作為に挿入または削除される場合は、インデックスごとに
3 ~ 4 ページの入出力操作を追加することができます。行が更新される場合
は、変更された列に適用される各インデックスごとに、6 ~ 8 ページの入出
力操作を追加することができます。トランザクションがロールバックされ
る場合は、この作業をすべて元に戻す必要があります。このため、トラン
ザクションのロールバックには長時間かかる場合があります。
行の変更そのものに必要な入出力操作は 2 ページのみであるため、インデッ
クス管理が、データ修正で最も時間を消費する部分であることは明らかで
す。10-26 ページの『インデックスの削除』では、この代償を減らす 1 つの
方法について説明します。
インデックスの選択
インデックスは、主キーとして指定されていない一意な列で必須です。ま
た、次の 3 つの場合にも、インデックスを追加する必要があります。
• 外部キーとして指定されていない、結合に使用される列
• フィルター式で頻繁に使用される列
• 整列またはグループ化で頻繁に使用される列
結合列
第 4 章で説明されているように、結合式で指名される列の少なくとも 1 つ
は、インデックスを持っている必要があります。インデックスがない場合、
データベース・サーバーは、通常、結合の前に一時的なインデックスを作
成し、その後、廃棄します。これにより、表に対する順次走査を繰り返し
て結合を行うよりも速くなります。
結合式の両方の列にインデックスがある場合、オプティマイザーは、問合
せ予定を構成するときにより多くの選択肢から選択することができます。
一般的なルールとして、結合式で使用される主キーまたは外部キーとして
識別されない列には、通常、インデックスを配置するようにしてください。
モデルの調整 10-23
インデックスの管理
大きな表におけるフィルター列の選択
大きな表の行をフィルター操作するために頻繁に使用される列がある場合
は、その列にインデックスを配置してください。オプティマイザーは、そ
のインデックスを使用して必要な列を見つけ、表全体の順次走査を回避し
ます。その一例として、大きなメーリング・リストを含む表があります。
行のサブセットをフィルター操作するために郵便番号列が頻繁に使用され
ている場合は、その列が結合に使用されていない場合でも、その列にイン
デックスを配置するようにします。
このストラテジーは、その列の選択頻度が高い場合 ( つまり、行の小さな
部分にすべてのインデックス値が保持されている場合 ) にのみ、最終的な
時間の節約に役立ちます。インデックスを使用した非順次アクセスは、順
次アクセスよりも多くのディスク入出力操作を行うため、列上のフィル
ター式で行が 4 分の 1 よりも多く渡される場合は、データベース・サー
バーもその表を順次読み取ることがあります。ルールとして、フィルター
列にインデックスを付けると、次の場合に時間を節約することができます。
• 数多くの問合せまたは遅い問合せで、フィルター式に列が使用される。
• 少なくとも 100 個の一意な値が列に含まれている。
• ほとんどの列の値が、その行の 10% 未満に存在する。
Order-By 列および Group-By 列
大量の行を整列またはグループ化する必要がある場合、データベース・
サーバーは、行を順序どおりに並べる必要があります。データベース・
サーバーがこれを行う方法として、すべての行を選択して一時表に入れ、
その表をソートするという方法があります。ただし、( 第 4 章で説明してい
るように ) 整列する列がインデックス付けされている場合、オプティマイ
ザーは、インデックスを使用して行をソート順で読み取ろうとして、最終
的にソートを回避する場合があります。
インデックス内のキーはソート順であるため、インデックスは、実際には、
表のソート結果を表しています。整列する 1 つ以上の列にインデックスを
配置すると、問合せ中に行われる数多くのソートを、インデックスの作成
時に行われる 1 回のソートで行うことができます。
10-24 モデルの調整
インデックスの管理
インデックスの修正を遅らせる重複キー
インデックス内で重複キーが許可されている場合、単一値を持つエント
リーはリスト内でグループ化されます。列の選択水準が高い場合、通常、
これらのリストはソートされます。ただし、一意な値が少ない場合、その
リストはかなり長くなり、複数のリーフ・ページに渡ることもあります。
例えば、既婚を表す M の値および独身を表す S の値のみの列のインデック
スの場合、すべてのインデックス・エントリーは、2 つの重複のリストに
のみ含まれることになります。このようなインデックスはあまり使用され
ることはありませんが、少なくとも問合せには使用されます。データベー
ス・サーバーは、いずれか一方の値を持つ行のリストを読み取ることがで
きます。
重複リストからエントリーを削除する必要がある場合、データベース・
サーバーは、そのリスト全体を読み取り、その一部を再書込みする必要が
あります。エントリーを追加する場合、データベース・サーバーは、新規
の行をリストの最後に配置します。リストが短い場合は、いずれの操作も
問題とはならず、通常どおりに行われます。ただし、リストが数多くの
ページに渡る場合、データベース・サーバーは、すべての行を読み取って、
最後を見つける必要があります。エントリーを削除する場合は、通常、リ
ストの半数のページを更新し、再書込みする必要があります。
このため、数多くの行を持つ表の、区別される値が少ない列のインデック
スによって、更新速度が非常に遅くなる場合があります。その一例として、
都道府県の名前または省略形を値とする列を挙げることができます。
100,000 行のメーリング・リスト内に一意な値が 50 個ある場合、平均 2,000
個の値の重複が存在することになります。ただし、実際のデータがそれほ
どきれいに分散していることはありません。このような表では、頻繁に使
用される値が 10,000 以上重複し、そのリストは 50 ページもの長さになる場
合があります。
データベース・サーバーがこのようなリストに対してエントリーの挿入ま
たは削除を行う場合は、長時間に渡ってビジー状態となります。さらに、
この作業を行う間、対象となるすべてのインデックス・ページをロックす
る必要が生じ、その表への並行アクセスが大きく減少することになります。
この問題は、ディスク領域の一部を代償にした非常に単純な方法で回避す
ることができます。データベース・サーバーは、列のインデックスを単独
で使用する場合と同じ方法で、複合インデックスの先行する列を使用する
ということを理解する必要があります。つまり、一意な値がほとんどない
列上にインデックスを作成する代わりに、その列上に複合インデックスを
作成し、その後、値が幅広く分散する別の列が続くようにします。
モデルの調整 10-25
インデックスの管理
例えば、値が M および S のみの列上のインデックスを、その列と誕生日の
列の複合インデックスに変更します。キー値が変更されないか、または実
際のキーと同時に変更される場合は、任意の第 2 の列を使用してキー値を
分散させることができます。第 2 の列の値はインデックスにコピーされて
サイズが大きくなるため、第 2 の列は短いほど良いことになります。
インデックスの削除
一部のアプリケーションでは、大部分の表の更新を単一の時間枠に限定す
ることができます。通常は、すべての更新が夜間または指定された日に適
用されます。
この場合は、更新の実行中にすべての一意でないインデックスを削除し、
その後、新規にインデックスを作成することを検討します。これには 2 つ
の効果があります。
まず、更新するインデックスが少なくなるため、更新プログラムの実行速
度を向上させることができます。通常、インデックスの削除、これらのイ
ンデックスなしでの更新、およびこれらのインデックスの再生にかかる時
間は、合計しても、インデックスを削除せずに更新する時間よりも短くな
ります ( インデックスの更新にかかる時間については、10-22 ページの『イ
ンデックスによって消費される時間』で説明します )。
また、新規に作成されるインデックスは、最も効果的なインデックスです。
頻繁に更新すると、インデックス構造体が弱体化し、一部のみが使用され
ているリーフ・ページが大量に含まれる状態になります。これにより、イ
ンデックスの効果が低下し、ディスク領域を無駄に消費することになりま
す。
時間を節約するもう 1 つの方法として、バッチの更新プログラムが、主
キー・インデックスによって定義された順序で行を呼び出すことを確認し
ます。この順序によって、主キー・インデックスのページが、順序に従っ
て各 1 回のみ読み取られるようになります。
また、インデックスが存在すると、LOAD コマンドまたは dbload ユーティ
リティーを使用した場合の表の移植作業も遅くなります。インデックスが
まったくない表のロードは、非常に高速に ( ディスクからディスクへの順
次コピーとほとんど変わらない速度で ) 処理されますが、インデックスを
更新すると、非常に多くのオーバーヘッドが追加されます。
表のロードを最高速で行う方法は、次のとおりです。
1. 表がある場合は表を削除する。
2. 一意性制約をまったく指定せずに表を作成する。
3. すべての行を表にロードする。
10-26 モデルの調整
インデックスの管理
4. 一意性制約が適用されるように表を変更する。
5. 非一意性インデックスを作成する。
ロードされたデータがすべての一意性制約を満たしているという確信がな
い場合は、行をロードする前に、一意性インデックスを作成する必要があ
ります。これにより、行が少なくとも 1 つのインデックス ( 選択可能な場
合は最も大きなキーを持つインデックス ) に対して正しい順序になってい
る場合は時間が節約されます。この結果、読込みおよび書込みで必要とな
るリーフ・ページ数が最小化されます。
クラスター・インデックス
クラスター・インデックス という用語は、間違った名称です。このイン
デックスに関して特別なことは何もありません。これは、インデックス内
のエントリーの順序に従って、行が物理的に配列されるように修正された
表のことです。
表が特定のインデックスに従って配列されている場合は、ソートを回避す
るための手法を使用することができます。また、その列に対して表の検索
を行う場合は、読込みが非順次ではなく順次に ( 効果的に ) 行われているこ
とを確信することができます。これらのポイントについては、第 4 章で説
明します。
stores5 データベース内の orders 表の郵便番号の列には、インデックス
zip_ix が付けられています。次のコマンドを使用すると、データベース・
サーバーは、customer 表の行を郵便番号の降順に並べます。
ALTER INDEX zip_ix TO CLUSTER
インデックスの付いていない列上の表をクラスター化するには、インデッ
クスを作成する必要があります。次のコマンドを使用すると、orders 表は、
注文日順に再配列されます。
CREATE CLUSTERED INDEX o_date_ix ON orders (order_date ASC)
データベース・サーバーは、表を再配列するために表をコピーする必要が
あります。上記の例では、データベース・サーバーは、表のすべての行を
読み取り、インデックスを構築します。その後、インデックス・エント
リーを順次読み取ります。各エントリーごとに、表の一致する行を読み取
り、新規の表にコピーします。新規の表の行は、要求された順序に並べら
れます。この新規の表は、古い表を置き換えます。
モデルの調整 10-27
インデックスの管理
クラスター化は、表の変更時には保存されません。新規の行を挿入する場
合、これらの行は、その内容に関係なく物理的に表の最後に格納されます。
行を更新してクラスター列の値を変更する場合でも、その行は、表内の元
の位置に書き込まれます。
更新によってクラスター化が妨げられた場合は、クラスター化を復元する
ことができます。次のコマンドは、物理的な順序を復元するように表を再
配列します。
ALTER INDEX o_date_ix TO CLUSTER
ほとんどクラスター化されている表の行の読込みはほぼ順次走査になるた
め、再クラスター化は、通常、元のクラスター化よりも高速で行われます。
クラスター化および再クラスター化には、多くの領域と時間が必要です。
最初から表を望ましい順序で作成すると、一部のクラスター化を回避する
ことができます。行の物理的順序は追加順序であるため、最初に表が順序
付けされたデータと共にロードされた場合、クラスター化は必要ありませ
ん。
10-28 モデルの調整
逆正規化
逆正規化
拡張された関係分析 ( 第 8 章で説明するデータのモデル化方法 ) では、非冗
長データまたは導出データが含まれている、関係理論の原理に従って構成
された表が作成されます。
高いパフォーマンスに対する要求を満たすために、理論的な観点からは望
ましくない方法でデータ・モデルを修正する必要がある場合があります。
このセクションでは、一部の修正およびそれに関連した代償について説明
します。
問合せを高速化するための行の短縮
一般的な原則として、短い行を持つ表は、長い行を持つ表よりもパフォー
マンスが良くなります。これは、ディスク入出力が、行ではなくページで
実行されるためです。表の行が短いほど、ページには多くの行が含まれま
す。ページごとの行が多いほど、表の順次読取りで必要な入出力操作は少
なくなり、非順次アクセスは、バッファーで満たされる可能性が高まりま
す。
拡張された関係分析では、あるエンティティーのすべての属性をエンティ
ティーの単一の表に格納するようにします。このため、エンティティーの
中には、異常な長さの行が作成される場合があります。このような行を短
縮するには、いくつかの方法があります。行が短くなると、問合せのパ
フォーマンスは向上します。
長い文字列の排除
ほとんどのバルクの属性は、通常は文字列です。これらを実体表から削除
すると、行は短縮されます。
VARCHAR 文字列の使用
可変長文字 (VARCHAR) 型は、IBM Informix OnLine にとっては比較的新しい
データ型であるため、既存のデータベースの中には、可変長文字 (VARCHAR) 型に変換した方がよい文字 (CHAR) 型列が含まれている場合がありま
す。可変長文字 (VARCHAR) 型列では、文字 (CHAR) 型列内の平均値が既存の
列の固定幅よりも少なくとも 2 バイト短い場合、平均の行が短縮されます。
この置換によって、モデルの理論的な特性に悪影響が与えられることはあ
りません。また、可変長文字 (VARCHAR) 型のデータには、既存のプログラ
ム、フォーム、およびレポートとの互換性があります。( フォームは再コン
パイルする必要があります。フォームおよびレポートは、サンプル・デー
タベース上でテストする必要があります。)
モデルの調整 10-29
逆正規化
長い文字列のテキスト (TEXT) 型への変更
標準文字列がディスク・ページの半分以上を占める場合は、この文字列を
別の BLOB 領域のテキスト (TEXT) 型列に変換することを検討してください。
行ページ内の列の長さは 56 バイトしかありませんが、非常に多くの行を 1
ページに格納する必要があります。ただし、テキスト (TEXT) 型は、そのま
までは既存のプログラムとの互換性がありません。テキスト (TEXT) 型の値
を取り出すためのコードは、文字 (CHARACTER) 型の値をプログラム内に取
り出すコードよりも複雑です。
反復する文字列のシンボル・テーブルの作成
各行の中の一意でない文字列が列に含まれている場合は、それらの文字列
を一意のコピーのみが格納されている表に移動することができます。
例えば、市町村の名前が含まれている customer.city 列があるとします。一
部の市町村名は、列の中で繰り返されます。また、フィールド内のほとん
どの列には、後続の空白文字が含まれています。可変長文字 (VARCHAR) 型
を使用すると、空白文字を除去することができますが、重複はなくなりま
せん。
次のようにして、cities という名前の表を作成します。
CREATE TABLE cities
(
city_num SERIAL PRIMARY KEY,
city_name VARCHAR(40) UNIQUE
)
その後、customer 表の定義を変更すると、その city 列は、cities 表内の
city_num 列を参照する外部キーになります。
customer に新規の行を挿入するすべてのプログラムを変更して、新規の顧
客の市町村が cities に挿入されるようにする必要があります。SQLCODE
フィールド内のデータベース・サーバーの復帰コードは、重複キーが原因
で挿入に失敗したことを示している場合があります。これは論理エラーで
はありません。既存の一部の顧客がその市町村に配置されていることを意
味しています。( ただし、4GL プログラムは、WHENEVER コマンドを使用し
てエラーをトラップする必要があります。このようにしないと、SQLCODE
内の負の値によって、プログラムが終了することになります。)
データを挿入するプログラムを変更するだけでなく、市町村名を抽出する
すべてのプログラム、および格納されている問合せも変更する必要があり
ます。プログラムや問合せは、新規の cities 表への結合を使用してデータを
取得します。データ・モデル内で理論的に不正確な部分があると、行を挿
10-30 モデルの調整
逆正規化
入するプログラムが複雑になり、一部の問合せも複雑になります。この変
更を行う前に、ディスク領域または実行時間が節約されるかどうかを確認
してください。
文字列の伴表への移動
ページの長さの半分に満たない文字列は、テキスト (TEXT) 型として扱うと
ディスク領域を無駄に消費しますが、これらは主表から伴表に移動するこ
とができます。伴表の使用については、次のセクションで説明します。
ワイド表の分割
パフォーマンスを高めるには、行の幅が広すぎるエンティティーのすべて
の属性について検討します。これらを 2 つのグループに分割することがで
きるテーマまたは原則を見つけ出します。主表および伴表の 2 つに表を分
割して、それぞれで主キーを繰り返します。短い行を使用すると、それぞ
れの表をより迅速に問い合わせたり、または更新することができるように
なります。
バルク別の分割
実体表を分割することができる原則の 1 つとして、バルクを挙げることが
できます。バルクの属性 ( 通常は文字列 ) を伴表に移動します。数値および
その他の小さな属性は主表に残します。デモンストレーション・データ
ベースでは、orders 表から ship_instruct 列を分割することができます。伴
表 orders_ship を呼び出します。orders.order_num のコピーである主キー、
および既存の ship_instruct 列の 2 つの列があります。
使用頻度別の分割
別の原則では、使用頻度ごとにエンティティーを分割します。あまり問合
せが行われない属性がある場合は、これらを伴表に移動することができま
す。デモンストレーション・データベースでは、ship_instruct 列、
ship_weight 列、および ship_charge 列に対しては、1 つのプログラムでのみ
問合せが行われます。この場合、これらの列は伴表に移動することができ
ます。
更新頻度別の分割
更新は、問合せよりも時間がかかります。また、プログラムの更新では、
データのインデックス・ページおよび行がロックされ、問合せのみが行わ
れるプログラムがスローダウンします。エンティティーの特定の属性が頻
繁に更新され、その他の数多くの属性はほとんどまたはまったく更新され
モデルの調整 10-31
逆正規化
ず、さらに、数多くの問合せでは後者が選択されて前者は不必要な場合は、
揮発性の列を伴表に分割することができます。複数のプログラムの更新に
は、その表が同時に使用されます。プログラムの問合せには、主表が使用
されます。
伴表の代償
表を分割すると、ディスク領域が余分に消費され、複雑になります。主
キーのコピーは、各行ごとに 2 つ ( 各表ごとに 1 つ ) 存在します。また、主
キーのインデックスは 2 つです。上記のセクションで説明した方法で、追
加されるページ数を見積もることができます。
戻される列が少なくなるため、SELECT * を使用する既存のプログラム、レ
ポート、およびフォームを修正する必要があります。両方の表の属性を使
用するプログラム、レポート、およびフォームは、これらをまとめるため
に結合を実行する必要があります。
行を挿入または削除する場合は、1 つではなく 2 つの表を変更する必要があ
ります。2 つの表を合わせて変更しない ( 例えば、単一トランザクション内
で変更を行う ) と、意味整合性が失われます。
トール表の分割
大きな表は、大きな管理上の問題を引き起こします。400 MB の表は、問合
せにも長時間かかりますが、バックアップおよび復元にも長時間かかりま
す。ソートは 3 つ以上のマージ・レベルに渡って行われるため、極端に遅
くなります。数多くのディスク領域が必要になるため、ソートできなくな
る場合もあります。また、インデックス構造体には 3 つ以上の中間レベル
が存在するため、インデックスの効果も低くなります。
このような表に関しては、セグメントに分割することを検討してください。
セグメントの列、インデックス、および制約は同じように配列されますが、
行のサブセットは異なります。行グループへの分割は、ほとんどの問合せ
で使用される属性の値 ( 主キー ) をベースにして実行し、プログラムまたは
ユーザーが、行が所属する副表を簡単に識別することができるようにしま
す。例えば、主キーが数値である場合は、中央の桁をベースにして、行を
10 個の副表に割り当てることができます。
行に時間または日付の属性がインクルードされており、特に新しい行が古
い行よりも頻繁に使用される場合は、表を経過日数でセグメントに分割し
た方がよい場合があります。
大きな表を分割すると、コピー、ソート、インデックス付け、アーカイブ、
復元を行う場合にセグメントを個々に扱うことができるようになります。
これらの操作をすべて簡単に行うことができます。セグメントをさまざま
10-32 モデルの調整
逆正規化
な方法で表領域に割り当てると、ディスク・デバイスを最良の方法で使用
することができます。また、ほとんどの問合せがセグメント化に使用され
る属性に基づいている場合、問合せは非常に高速になります。
表の分割の欠点として、表全体に適用される操作が非常に複雑になること
を挙げることができます。問合せで単一の副表を指示することができない
場合は、それぞれ異なる副表に対する数多くの副問合せの UNION の形式で
書き込む必要があります。この場合、レポートおよびブラウズ・プログラ
ムの設計は非常に複雑になります。
冗長データおよび導出データ
第 8 章の方法で作成されたデータ・モデルには、冗長データ ( 単一の表に
すべての属性が存在する ) および導出データ ( 既存の属性から計算できる
データが、それらの属性に基づいた表現式として選択される ) は含まれて
いません。
これらの機能によって、使用するディスク領域の量が最小化され、表の更
新が可能な限り簡単になります。ただし、これらの機能は結合および集計
関数を使用することを強制するため、許容範囲以上の時間が必要となる場
合があります。
これらの機能の代わりに、リスクを理解した上で、冗長データまたは導出
データを含む新列を導入することができます。
導出データの追加
stores5 データベースの orders 表には、注文の合計価格用の列はありませ
ん。その理由は、この情報は items 表の行から導出することができるため
です。注文番号 1009 の日付および合計価格をレポートするプログラムで
は、この情報を次の問合せで取得することができます。
SELECT order_date, SUM (total_price)
FROM orders, items
WHERE orders.order_num = 1009
AND orders.order_num = items.order_num
GROUP BY orders.order_num, orders.order_date
items 表への結合では、3 つまたは 4 つの追加ページだけが読み取られます
が、対話式プログラムにとっては時間がかかりすぎる場合があります。解
決方法の 1 つとして、orders 表に order-total 列を追加する方法があります。
導出データでは、ディスク領域、複雑さ、およびデータ整合性が代償にな
ります。
モデルの調整 10-33
逆正規化
同じ情報が 2 回格納されるため、order-total 列専用のディスク領域が消費さ
れます。また、この列によって、表の行の幅が広がることもあります。
ページ内の行の数が減り、表に対する問合せが遅くなります。最も重要な
こととして、基本属性を更新するすべてのプログラムを変更して、導出列
も更新するよう変更する必要があります。導出列が間違っており、導出列
に正しい導出値が含まれていない場合があります。
導出データは信頼できるデータではありません。導出された注文価格の例
では、注文の入力時に信頼性が失われます。items 表に行が追加される場
合、orders の中の注文合計が、対応する items の行の合計と等しくなくな
る場合があります。一般的に、データベース内の導出データを許容する前
に、その正確性を可能な限り注意深く判別する必要があります。実際に、
どのような条件の場合に導出列が信頼できなくなる のかについて、注意深
く判別する必要があります。表を経過日数でセグメントに分割すると役立
つ場合があります。
冗長データの追加
正しいデータ・モデルでは、どの属性もそれが記述するエンティティーの
表内にのみ存在するようにすることにより、冗長が回避されます。別のコ
ンテキストでその属性データが必要な場合は、表を結合することによって
接続します。ただし、結合には時間がかかります。頻繁に使用される結合
によってパフォーマンスが低下する場合は、結合されたデータを他の表に
複写することにより、これを除去することができます。
デモンストレーション・データベースでは、manufact 表にはメーカーの名
前および商品が含まれています ( 実際のデータベースでは、1 つのサプライ
ヤーに関して、住所や販売担当者の名前など、他にも多くの属性が含まれ
ています )。
manufact のコンテンツは、主に stock 表の補足です。時間が重要なアプリ
ケーションで、特定の製品の発注から配達までの時間は頻繁に参照しても、
manufact の他のコラムは参照しないものががあるとします。データベー
ス・サーバーは、このような参照ごとに 2 ページまたは 3 ページのデータ
を読み取って、ルックアップする必要があります。
新列 lead_time を stock 表に追加して、manufact の対応する行の lead_time
列のコピーで埋めることができます。これによってルックアップしなくて
すみ、アプリケーションの速度が向上します。
導出データと同様、冗長データの場合も、領域を消費して、整合性に関す
るリスクが発生します。この例では、各メーカーの発注から配達までの時
間の余分なコピーが、1 つではなく数多く存在します ( 各メーカーは、
stock の中に何度も出現する場合があります )。manufact の行を挿入または
更新するプログラムは、stock の複数の行も更新するよう変更する必要があ
ります。
10-34 モデルの調整
同時実行性の最大化
整合性に関するリスクとは、データの冗長コピーが正確ではない可能性が
あるということを意味します。manufact の中の発注から配達までの時間が
変更された場合、stock 列は、更新されるまで無効になります。導出データ
の場合と同様、冗長データが間違っている可能性のある条件を判別する必
要があります。
同時実行性の最大化
データベースの中には、一度に 1 つのプログラムによって使用されるもの、
および複数のプログラムによって並行して使用されるものがあります。並
行して実行されるプログラムは、次の 2 つの要因で、同じ量の作業を連続
して行う場合よりも本質的に遅くなります。
• 複数のプログラムが、バッファーおよびディスク領域の使用を互いに妨
害する。単一のプログラムのページの読取りは、次のプログラムの問合
せによってバッファーから追い出されるため、再度読み取る必要がある
場合があります。単一の問合せのディスク入出力がディスク・アクセ
ス・アームに置き換わり、もう一方のプログラムの順次アクセスを遅ら
せます。
• データ・ロック・ページを修正するプログラムは、同じデータを使用す
る他のすべてのプログラムを遅らせる。
競合の緩和
同じ資源を使用するプログラム間の競合は避けることができません。これ
に対処する一般的な方法として、次の 3 つの方法があります。
1. プログラムが実行する作業を減らすか、または作業効率を上げて、プロ
グラムが使用する資源を減らす。
2. 例えば、DB 領域に表を割り当て競合を最小化したりして、資源をより
良く調整する。
3. メモリーを増やすか、ディスク・ドライブやコンピューターを増やして
高速にし、より多くの資源を提供する。
最初のポイントは、問合せの高速化と関係しており、第 4 章の主題となっ
ています。問合せの作業を減らす、つまりオンライン・ユーザーが使用す
ることができる機能の削減を検討する必要がある場合もあります。大きな
表 ( さまざまな種類の加算、平均、または管理レポート、特に結合を必要
とするもの ) の全体の走査を行う使用可能なトランザクションを検索しま
す。これらのトランザクションをオンライン・プログラムから除去するこ
とを検討します。その代わりに、対話式でオフピークのジョブをスケ
ジュールし、翌日に出力を戻す新規の機能を提供します。
モデルの調整 10-35
同時実行性の最大化
修正のスケジュール変更
可能な限り範囲を広げるには、いずれの対話式ユーザーもデータベースを
使用していない時間に修正をスケジュールします。この理由の 1 つは、並
行して行われる修正は、そこに存在するすべてのインデックスを使用して
上記の時間的な代償をすべて引き起こすためです。もう 1 つの理由は、修
正によって表の行がロックされるだけでなくインデックス・ページもロッ
クされるためです。これにより、使用中のロック数が増加し、そのロック
の数によってすべてのユーザーに対して遅延が生じます。
修正をスケジュール変更する方法は、使用するアプリケーションの詳細に
依存します。
更新日誌の使用
データが使用可能な場合は、更新を実行する代わりに、更新日誌 の作成を
検討します。更新日誌とは、保留中の更新を表す行が含まれている表のこ
とです。その行には、次の情報が含まれています。
• 一部の基本表で変更されるデータ項目。NULL は、変更しないことを意
味します。
• 監査情報。これにより、間違った更新は、行に入力されたトランザク
ションにトレースバックされます。
更新日誌への新行の挿入は、通常、1 つ以上の基本表への更新を実行する
よりも高速で行われます。日誌には、更新するインデックスは多くても 1
つのみ含まれていますが、基本表には、通常、複数存在するためです。ま
た、インデックスのない表に行を挿入する場合は、挿入された行のロック
が 1 つしか必要ではないため、ロックの遅延はほとんどありません。別の
プログラムは、最初のプログラムがそのトランザクションをコミットする
前でも、行を挿入することができます。
また、主表では更新は実行されないため、そのページはロックされません。
このため、問合せプログラムは、遅延せずに実行できます。
使用のピーク時間 ( 終業後など ) が過ぎた後にバッチ・プログラムを実行し
て、挿入された行ごとに、更新の妥当性を検査して適用します。システム
障害の可能性とは関係なく、いずれの更新も忘れられておらず、2 回適用
されていないことを確認することができます。
10-36 モデルの調整
同時実行性の最大化
基本表を更新する方法の 1 つは、2 つのカーソルを使用する方法です。カー
ソルの 1 つは、HOLD カーソルで、日誌の行を走査するために使用します
(7-35 ページの『HOLD カーソル』を参照 )。プログラムは、日誌のそれぞ
れの行ごとに次の手順に従います。
1. BEGIN WORK コマンドを出す。
2. UPDATE カーソルを使用して、更新中の表から行を取り出す ( これらの
行のみロックされる )。
3. ターゲットの行のデータに対して、日誌にある更新情報の妥当性を検査
する。
4. ターゲットの表に更新を適用する。
5. 何らかの方法で、日誌の行に終了のマークを付けて更新する。
6. COMMIT WORK コマンド ( またはエラーが見つかった場合は ROLLBACK
WORK コマンド ) を出す。
日誌のすべての行の妥当性が検査され、この行が適用されてマーク付けさ
れた後でのみ、別のプログラムを実行して日誌の表を削除および再作成し
ます。
更新日誌の欠点は、現行のデータの大部分が基本表には反映されないこと
です。更新結果をすぐに反映させることが重要な場合、日誌スキーマは使
用することができません。
ピーク時に入出力を削減して、ロックの遅延を削減することができるため、
更新日誌が支持されています。据置き更新は、多くのアプリケーションで
受け入れられています。例えば、いずれの銀行でも、前日の終業時間での
顧客の口座の残高を正確に知ることが保証されています。これは、銀行は
その日のトランザクションを日誌に記録し、夜間に更新を適用するためで
す。
更新の分離および分散
更新をピーク時に対話式に実行する必要がある場合は、更新から問合せを
分離するための別の方法を見つけなければなりません。
分離された揮発性の列への表の分割
この概念については、前のセクションで説明しました。ピーク時に更新を
実行する必要がある場合は、表の構造を検証します。常に更新される揮発
性の列、およびあまり更新されない静的な列に列を分離することは可能で
しょうか。可能な場合は、表を分割して、揮発性の列を伴表内で分離する
ことを検討します。
モデルの調整 10-37
サマリー
その後、操作の混合およびユーザーの優先順位に従って、静的な副表か揮
発性の副表のいずれかを最高速のディスク・ドライブに書き込みます。
障害となっている表の分散
小さな表は、サマリー、使用方法に関するレコード、および監査に使用さ
れる場合があります。例えば、使用する対話式プログラムが、それぞれの
許可ユーザーごとの行を持つ表を管理している場合があります。ユーザー
がプログラムを始動または終了するごとに、そのユーザーの行が更新され、
オンにした時間、オフにした時間、トランザクション数、またはその他の
作業をモニターしたデータが表示されます。
読込みのみが行われる小さな表はパフォーマンス上の問題を引き起こすこ
とはありませんが、同時更新の対象となる小さな表は、このような問題を
引き起こす場合があります。トランザクションごとに更新する必要のある
小さな表は、各オンライン・プログラムがキューに入って待機する場合の
障害となる可能性があります。
この問題をなくすには、すでに説明したようにオフピークに更新を行う日
誌を使用するか、または数多くの表を作成して障害を分散します。ユー
ザーをモニターするには、それぞれのユーザーごとに 1 行の表を作成しま
す。
サマリー
表のサイズが適度で、一度に 1 人のユーザーのみがデータベースにアクセ
スする場合は、関係理論を注意深く適用するだけで十分に高いパフォーマ
ンスを実現することができます。
表の数およびユーザー数が大きくなって応答時間が低下し始めた場合は、
実用的な解決策を講じる必要があります。
まず最初の手順として、IBM Informix OnLine で提供されているツールの利
点について理解し、これらのツールを使用します。これにより、最大限の
利益を得ることができるように、ハードウェア上の表を調整することがで
きます。その後、1 段階ずつ、常に結果を確認しながら、データ・モデル
およびそれを使用するプログラムの構造を複雑化していきます。
10-38 モデルの調整
セキュリティー、ス
トアード・プロシー
ジャー、および
ビュー
概要 3
データベースへのアクセスの制御 4
データベース・ファイルの保護 4
マルチユーザー・システム 4
シングルユーザー・システム 5
機密データの保護 5
アクセス権の付与 6
データベース・レベル・アクセス権 6
Connect アクセス権 6
Resource アクセス権 7
データベース管理者のアクセス権 8
所有権 8
表レベル・アクセス権 9
アクセス権 9
インデックス、変更、および参照アクセス権 11
列レベル・アクセス権 11
プロシージャー・レベル・アクセス権 14
アクセス権の自動化 14
IBM Informix 4GL での自動化 15
コマンド・スクリプトでの自動化 16
ストアード・プロシージャーの使用 17
ストアード・プロシージャーの作成および実行 17
データの読込みの制約 19
第
11
章
データの変更の制約 20
データの変更の監視 20
オブジェクト作成の制約 22
ビューの使用 23
ビューの作成 24
ビューからの行の重複 25
ビューの制約事項 25
基本変更時 26
ビュー全体を通した修正 27
ビュー全体を通した削除 28
ビューの更新 28
ビューへの挿入 29
WITH CHECK OPTION の使用 29
アクセス権およびビュー 30
ビュー作成時のアクセス権 31
ビュー使用時のアクセス権 31
サマリー 34
11-2 セキュリティー、ストアード・プロシージャー、およびビュー
概要
データベースには、すべてのユーザーがすべてのデータにアクセスできる
データがあります。また、それとは反対に、一部のユーザーが、データの
一部またはすべてに対するアクセスを拒否される場合もあります。データ
へのアクセスを、次の 5 つのレベルで制約できます。
1. データベースがオペレーティング・システム・ファイルに格納されてい
る場合、オペレーティング・システムのファイル許可機能を使用できる
ことがあります。
このレベルは、IBM Informix OnLine がデータベースを保持するときは使
用できません。これは、独自のディスク領域を管理し、オペレーティン
グ・システムのルールは適用されません。
2. GRANT 文および REVOKE 文を使用して、データベースまたは特定の表
へのアクセスを付与または拒否することができ、ユーザーが作成できる
データベースの使用の種類を制御できます。
3. CREATE PROCEDURE 文を使用して、ストアード・プロシージャーを書
き、コンパイルできます。このストアード・プロシージャーでは、デー
タベース表を読み込み、修正、または作成できるユーザーを制御および
監視します。
4. CREATE VIEW 文を使用して、データの制限付きまたは変更された
ビューを PREPARE 文で処理できます。制約事項として、特定の列を除
く垂直方向、または特定の行を除く水平方向、またはその両方の場合が
あります。
5. GRANT 文および CREATE VIEW 文を結合して、ユーザーが修正できる表
の部分およびどのデータを使用するかを正確に制御することができま
す。
以上の 5 項目が、この章の主題です。
セキュリティー、ストアード・プロシージャー、およびビュー 11-3
データベースへのアクセスの制御
データベースへのアクセスの制御
標準データベース・アクセス権機構は、GRANT 文および REVOKE 文を基に
しています。これらは、11-6 ページの『アクセス権の付与』のセクション
で説明します。ただし、場合によっては、データベースへのアクセスを制
御する他の方法として、オペレーティング・システムの機能を使用するこ
ともできます。
データベース・ファイルの保護
IBM Informix OnLine 以外のデータベース・サーバーは、オペレーティング・
システム・ファイルにデータベースを格納します。通常、データベースは
ファイル数で表されます。つまり、表ごとに 1 つ、表ごとのインデックス
に 1 つ、またその他にも存在する場合があります。ファイルは、ディレク
トリーに収集されます。ディレクトリーは、全体としてデータベースを表
します。
マルチユーザー・システム
データベース・ディレクトリーへのアクセスを拒否することによって、
データベースへのアクセスを拒否できます。この実行方法は、使用してい
るオペレーティング・システムおよびコンピューター・ハードウェアに
よって異なります。マルチユーザー・オペレーティング・システムには、
VMS のアクセス・コントロール・リスト、または UNIX のファイル許可な
どのソフトウェア機能があります。
注 : UNIX では、データベース・ディレクトリーがグループ ID informix を使
用して作成され、データベース・サーバーは常にグループ ID informix の下
で実行されます。したがって、グループ権限を使用して、特定のグループ
のユーザーへのアクセスを制限することはできません。すべてのグループ
権限を除去することのみが可能であり ( ファイル・モード 700)、ディレク
トリーの所有者を除くユーザーへのアクセスを拒否できます。
また、次のような方法で、個々の表へのアクセスを拒否することもできま
す。例えば、他のファイルをアクセス可能にしたまま、それらの個々の表
を表すファイルを特定のユーザーが使用できないようにします。ただし、
データベース・サーバーは、この種の実行を念頭に入れて設計されていま
せん。未公認のユーザーが表の 1 つに問合せをしようとすると、データ
ベース・サーバーはおそらくファイルが見つからないというエラー・メッ
セージを戻します。これによって、ユーザーは混乱する場合があります。
11-4 セキュリティー、ストアード・プロシージャー、およびビュー
データベースへのアクセスの制御
シングルユーザー・システム
標準シングルユーザー・システムは、ファイル・アクセスにおいてソフト
ウェア制御がほとんどありません。データベースを他のユーザーがアクセ
スできないようにするには、マシンから切り離してロックできるディスク
にデータベースを書き込むことによってのみ行うことができます。
これらの技法は、IBM Informix OnLine データベース・サーバーを使用する
ときには適用されません。このサーバーは、デバイス・レベルで独自の
ディスク領域を制御し、オペレーティング・システムのファイル・アクセ
スをバイパスします。
機密データの保護
オペレーティング・システムによって与えられるアクセス制御がどんなも
のでも、データベース全体の内容が機密性の高いものである場合は、マシ
ンに固定された一般のディスクにそれを残しておきたくありません。デー
タを保護する必要がある場合は、標準のソフトウェア制御を回避できます。
ユーザーまたは他の権限保持者がデータベースを使用していない場合は、
データベースをオンラインで使用可能にしておく必要はありません。次の
いくつかの方法で、データベースをすべての閲覧者がアクセスできないよ
うにすることができますが、不便さの度合いは異なります。
• 物理的メディアをマシンから切り離して取り出す。ディスク自体がリ
ムーバブルでない場合、ディスク・ドライブは通常、リムーバブルで
す。
• データベース・ディレクトリーをテープにコピーし、テープを保管す
る。
• 暗号化ユーティリティーを使用したデータベース・ファイルをコピーす
る。暗号化されたバージョンのみを保持します。
最後の 2 つのケースでは、コピーを作成した後に、NULL データで消去済
みファイルを上書きするプログラムを使用して、元のデータベース・ファ
イルを消去することを覚えておく必要があります。
データベース・ディレクトリー全体を除去する代わりに、個々の表を表す
ファイルをコピーしてから、そのファイルを消去できます。ただし、イン
デックス・ファイルには、インデックス付きの 1 つまたは複数の列からの
データのコピーが含まれていることを見逃さないようにしてください。表
ファイルと共に、インデックス・ファイルを除去するようにしてください。
セキュリティー、ストアード・プロシージャー、およびビュー 11-5
アクセス権の付与
アクセス権の付与
データベースの使用許可は、アクセス権 と呼ばれます。例えば、データ
ベースを全体において使用する許可は、Connect アクセス権と呼ばれ、行を
表に挿入する許可は、Insert アクセス権と呼ばれます。これらのアクセス権
を他のユーザーに付与したり、取り消したりすることによって、データ
ベースの使用を制御します。
アクセス権は 2 つのグループ内で設計されます。1 つのグループはデータ
ベース全体に影響を与え、もう 1 つのグループは個々の表に関連します。
データベース・レベル・アクセス権
次に挙げるデータベース・アクセス権の 3 つのレベルによって、データ
ベースにアクセスするユーザーを制御する総合的な手段が提供されます。
Connect アクセス権
アクセス権の最小レベルは Connect で、これによって、ユーザーに表の問
合せおよび修正の基本機能が与えられます。Connect アクセス権を持つユー
ザーは、次の機能を実行することができます。
•
SELECT、INSERT、UPDATE、および DELETE 文を実行する ( 必要な表レ
ベルのアクセス権がある場合 )。
• ストアード・プロシージャーを実行する ( 必要な表レベルのアクセス権
がある場合 )。
• ビューを作成する ( ビューを基にした表の問合せができる場合 )。
• 一時表を作成し、その一時表にインデックスを作成する。
11-6 セキュリティー、ストアード・プロシージャー、およびビュー
アクセス権の付与
Connect アクセス権は、ユーザーがデータベース全体にアクセスできるよう
にするために必要です。通常、高機密データまたはプライベート・データ
を含まないデータベースでは、データベース作成後、パブリック・データ
へのアクセス権を許可します。
ユーザーおよび PUBLIC
アクセス権は、シングル・ユーザーには名前で、すべてのユーザーに
PUBLIC の名前で付与されます。パブリック・ユーザーに対する認可は、
デフォルト・アクセス権として機能します。
文を実行する前に、データベース・サーバーはユーザーに必要なアクセ
ス権があるかどうかを判別します ( 情報は、システム・カタログ内にあ
ります。11-10 ページの『システム・カタログ内のアクセス権』を参照し
てください )。
データベース・サーバーは、最初に、要求しているユーザーに固有に付
与されたアクセス権を探します。このような認可を見つけたら、その情
報を受け取って停止します。そのユーザーに何の認可もない場合、デー
タベース・サーバーはパブリックに付与されたアクセス権を探します。
関連のあるアクセス権を見つけたら、それを使用します。
このように、パブリックにアクセス権を付与することによって、すべて
のユーザーのアクセス権を最小レベルに設定できます。特別な場合は、
ユーザーに高位の個別アクセス権を与えることによって上書きできま
す。
パブリックへの Connect アクセス権を許可しない場合、データベース・
サーバーを介してデータベースにアクセスできる唯一のユーザーは、特別
に Connect アクセス権を許可する相手です。特定のユーザーのみがアクセ
スを持つようにする場合、このような方法で、特定ユーザーにアクセスを
提供し、他のユーザーに対してはアクセスを拒否します。
Resource アクセス権
Resource アクセス権は、Connect アクセス権と同じ許可を持ちます。さら
に、Resource アクセス権を持つユーザーは、新規で永続的な表、インデッ
クス、およびストアード・プロシージャーを作成できるため、ディスク領
域が永続的に割り当てられます。
セキュリティー、ストアード・プロシージャー、およびビュー 11-7
アクセス権の付与
データベース管理者のアクセス権
データベース・アクセス権の最高レベルは、データベース管理者 、つまり
DBA です。データベースの作成者は、自動的に管理者になります。DBA ア
クセス権の所有者は、次の機能を実行できます。
•
DROP DATABASE、STARTDATABASE、および ROLLFORWARD DATABASE
のコマンドを実行する。
• システム・カタログ表の NEXT SIZE ( 他の属性ではない ) を変更して、
systables 以外の任意のシステム・カタログ表の行を挿入、削除、または
更新する。
警告 : DBA アクセス権を持つユーザーはシステム・カタログ表を修正でき
ますが、普通のユーザーは、システム・カタログ表の行を更新、削除、ま
たは変更しないことを強くお勧めします。システム・カタログ表の修正に
よって、データベースの整合性が壊れる可能性があります。
• オブジェクトを誰が所有しているかにかかわらず、オブジェクトを削除
または変更する。
• 他のユーザーによって所有される表、ビュー、およびインデックスを作
成する。
•
DBA アクセス権などのデータベース・アクセス権を、別のユーザーに
許可する。
所有権
データベース、およびデータベース内のすべての表、ビュー、インデック
ス、プロシージャー、およびシノニムには所有者があります。オブジェク
トの所有者は、普通は、それを作成したユーザーですが、DBA アクセス権
を持つユーザーは、他のユーザーによって所有されるオブジェクトを作成
できます。
オブジェクトの所有者は、そのオブジェクトへのすべての権利を持ち、追
加のアクセス権を必要とせずに、そのオブジェクトを変更または削除でき
ます。
11-8 セキュリティー、ストアード・プロシージャー、およびビュー
アクセス権の付与
表レベル・アクセス権
7 つのアクセス権を、表ごとに適用して、非所有者に所有者アクセス権を
許可することができます。そのうちの 4 つ、Select、Insert、Delete、および
Update の各アクセス権は、表の内容へのアクセスを制御します。Index アク
セス権は、インデックス作成を制御します。Alter アクセス権は、表定義変
更の許可を制御します。References アクセス権は、表に参照制約を指定す
る許可を制御します。
ANSI 準拠のデータベースでは、表の所有者のみがすべてのアクセス権を持
ちます。他のデータベースでは、表作成の一部として、データベース・
サーバーが自動的に、すべての表のアクセス権 (Alter および References を除
く ) をパブリックに許可します。つまり、Connect アクセス権を持つユー
ザーは、新規に作成された表にアクセスできます。これが不都合な場合、
例えば、Connect アクセス権を持つユーザーの中に、この表にアクセスでき
ないようにしたいユーザーがいる場合は、表を作成した後に、表にあるす
べてのアクセス権をパブリックから取り消す必要があります。
アクセス権
次の 4 つのアクセス権が、ユーザーが表にアクセスする方法を制御します。
表の所有者は、これらのアクセス権を自主的に許可したり、許可しなかっ
たりできます。
•
•
•
•
Select アクセス権は、一時表への選択などの選択を許可します。
Insert アクセス権は、ユーザーに新規行の追加を許可します。
Update アクセス権は、ユーザーに既存の行の修正を許可します。
Delete アクセス権は、ユーザーに行の削除を許可します。
セキュリティー、ストアード・プロシージャー、およびビュー 11-9
アクセス権の付与
Select アクセス権は、ユーザーが表の内容を抽出するために必要です。た
だし、Select アクセス権は、他のアクセス権の前提条件ではありません。
ユーザーは、Select アクセス権がなくても、Insert または Update の各アクセ
ス権を持つことができます。
システム・カタログ内のアクセス権
アクセス権は、システム・カタログ表に記録されます。Connect アクセ
ス権を持つユーザーは、システム・カタログ表を問い合わせて、アク
セス権が認可されている対象とユーザーを判別できます。
データベース・アクセス権は、sysusers 表に記録されています。その表
では、主キーがユーザー ID で、唯一の他の列には、アクセス・レベル
用に単一文字 C、R、または D が含まれます。PUBLIC のキーワードの
認可は、public ( 小文字 ) のユーザー名として反映されます。
表レベルのアクセス権は、systabauth に記録されており、ここでは表番
号、権限授与者、および被権限授与者の複合主キーを使用します。
tabauth 列では、アクセス権は次のような 6 文字のリストで符号化され
ています。
無条件更新
無条件選択
挿入
su-idxar
インデックス
参照
変更
削除
列のアクセス権が付与されている場合
*
ハイフン (-) は未許可のアクセス権を意味するため、すべてのアクセス
権が認可されている場合は su-idxar として示され、更新のみの認可の場
合は -u------ と示されます。コード文字は、通常小文字ですが、キー
ワード WITH GRANTOPTION が GRANT 文で使用されているときは大文字
です。
3 番目の位置にアスタリスクが表示される場合、その表および被権限授
与者にいくつかの列レベルのアクセス権が存在します。特定のアクセ
ス権は、syscolauth に記録されています。主キーは、表番号、権限授与
者、被権限授与者、および列番号の複合物です。唯一の属性は、アク
セス権の型を示している 3 文字リスト s、u、または r です。
11-10 セキュリティー、ストアード・プロシージャー、およびビュー
アクセス権の付与
例えば、アプリケーションが使用方法の表を持つとします。あるプログラ
ムが開始されると、使用方法の表に行が挿入され、その行が使用されたこ
とが記録されます。プログラムは、終了前にその行を更新して、どのくら
いの時間実行されたかを示し、おそらく、そのユーザーによって実行され
た作業のカウント数を記録します。
プログラムのどのユーザーも、この使用方法の表で行の挿入および更新が
できるようにする場合は、表での Insert および Update の各アクセス権をパ
ブリックに許可します。ただし、Select アクセス権は、非常に少数のユー
ザーのみに許可できます。
インデックス、変更、および参照アクセス権
Index アクセス権の所有者は、表でのインデックスの作成および変更が可能
です。Index アクセス権は、Select、Insert、Update、および Delete の各アク
セス権と同様に、表が作成されるときに自動的にパブリックに許可されま
す。
Index アクセス権はどのユーザーにも許可できますが、その機能を実行する
には、Resource データベース・アクセス権も同時に保持しておく必要があ
ります。したがって、Index アクセス権が自動的に許可されても (ANSI 準拠
データベースを除く )、データベースへの Connect アクセス権しか持たない
ユーザーは Index アクセス権を実行することはできません。これは、イン
デックスは大容量のディスク領域を満たす可能性があるため、合理的です。
Alter アクセス権の所有者は、列の追加および削除、SERIAL 列の開始ポイン
トのリセットの機能などを含む ALTER TABLE 文を表で使用できます。Alter
アクセス権は、データ・モデルを熟知しており、大変慎重にこれらの機能
を実行すると見なされるユーザーにのみ許可するようにしてください。
References アクセス権を使用すると、表に参照制約を課すことができます。
Alter アクセス権と同様に、References アクセス権もデータ・モデルを熟知
したユーザーにのみ許可するようにしてください。
列レベル・アクセス権
Select、Update、および References の各アクセス権を、特定の列の名前で修
飾できます。これによって、非常に特定した表へのアクセスが許可されま
す。つまり、ユーザーに特定の列だけを参照すること、特定の列だけを更
新すること、または特定の列だけに参照制約を課すことを許可することが
できます。
セキュリティー、ストアード・プロシージャー、およびビュー 11-11
アクセス権の付与
IBM Informix OnLine を使用すると ( データベース・サーバーへの呼び出し
を介して表データのみが検査できるように )、この機能により、特定のユー
ザーのみが、従業員の給与、功績評価、またはその他の機密属性を知るべ
きであるという早期に提示された問題を解決することができます。具体的
なサンプルで説明します。図 11-1 のように、定義済みの従業員データの表
があると仮定します。
CREATE TABLE hr_data
(
emp_key INTEGER,
emp_name CHAR(40),
hire_date DATE,
dept_num SMALLINT,
user-id CHAR(18),
salary DECIMAL(8,2)
performance_level CHAR(1),
performance_notes TEXT
)
図 11-1
機密従業員情報表
この表には機密データが含まれるため、表の作成直後に、次の文を実行し
ます。
REVOKE ALL ON hr_data FROM PUBLIC
選択した人事課の従業員およびすべてのマネージャーには、次のような文
を実行します。
GRANT SELECT ON hr_data TO harold_r
このようにして、特定のユーザーがすべての列を表示できるように許可し
ます。( この章の最終セクションで、マネージャーの表示を自分の部下だけ
に制限する方法を説明します。) 功績評価を実行する最初の行のマネー
ジャーには、次のような文を実行できます。
GRANT UPDATE (performance_level, performance_notes)
ON hr_data TO wallace_s, margot_t
11-12 セキュリティー、ストアード・プロシージャー、およびビュー
アクセス権の付与
この文によって、マネージャーは従業員の評価を入力することができるよ
うになります。人事課のマネージャーのみ、または給与レベルを変更する
権限のあるユーザーには、次のような文を実行します。
GRANT UPDATE (salary) ON hr_data to willard_b
人事課のクラークには、次のような文を実行できます。
GRANT UPDATE (emp_key, emp_name, hire_date, dept_num)
ON hr_data TO marvin_t
この文によって、特定のユーザーに機密性のない列を管理する機能が与え
られますが、功績評価や給与を変更するための許可は拒否されます。コン
ピューターのユーザー ID を割り当てる MIS 部門の従業員は、次のような文
を受け取ります。
GRANT UPDATE (user_id) ON hr_data TO eudora_b
データベースへのアクセスが許可されていても、給与や功績評価を参照す
ることが許可されていないすべてのユーザーに代わって、次のような文を
実行し、機密性のないデータを参照できるようにします。
GRANT SELECT (emp_key, emp_name, hire_date, dept_num, user-id)
ON hr_data TO george_b, john_s
このようなユーザーは、次のような問合せを実行できます。
SELECT COUNT(*) FROM hr_data WHERE dept_num IN (32,33,34)
ただし、以下のような問合せを実行しようとすると、エラー・メッセージ
が表示され、データは作成されません。
SELECT performance_level FROM hr_data
WHERE emp_name LIKE "*Smythe"
セキュリティー、ストアード・プロシージャー、およびビュー 11-13
アクセス権の付与
プロシージャー・レベル・アクセス権
プロシージャーで Execute アクセス権を適用して、非所有者にプロシー
ジャーの実行を許可することができます。ANSI 準拠ではないデータベース
でプロシージャーを作成する場合、デフォルトのプロシージャー・レベル
のアクセス権は Public です。そのため、最初に Execute アクセス権を取り消
した場合を除いて、特定のユーザーに Execute アクセス権を許可する必要は
ありません。ANSI 準拠のデータベースでプロシージャーを作成する場合
は、デフォルトでユーザーに Execute アクセス権は与えられません。特定の
ユーザーに Execute アクセス権を付与する必要があります。次の例では、
ユーザー orion が read-address という名前のストアード・プロシージャーを使用
できるように、orion に Execute アクセス権を付与します。
GRANT EXECUTE ON read_address TO orion;
プロシージャー・レベルのアクセス権は、sysprocauth システム・カタログ
表に記録されています。sysprocauth 表は、プロシージャー番号、権限授与
者、および被権限授与者の主キーを使用します。procauth 列で、Execute ア
クセス権は小文字 “e” で示されています。Execute アクセス権が WITHGRANT オプションと共に付与された場合、アクセス権は大文字 “E” で表さ
れます。
アクセス権の自動化
この設計では、最初にデータベースをセットアップするときに、多数の
GRANT 文を強制的に実行させられるように見えるかもしれません。さら
に、アクセス権は、ユーザーがジョブを変更するときに一定の管理を必要
とします。例えば、人事課のクラークが終了すると、Update アクセス権を
できるだけ早く取り消さなければなりません。そうしないと、不運にも次
のような文を実行している従業員が損害を被ります。
UPDATE hr_data
SET (emp_name, hire_date, dept_num) = (NULL, NULL, 0)
それほど劇的ではなくても、同様に必要とされるアクセス権の変更は、機
密データを含むモデルでは、日単位、または時間単位で必要です。アクセ
ス権の変更が必要な場合は、アクセス権の管理に役立ついくつかの自動化
ツールを用意することができます。
11-14 セキュリティー、ストアード・プロシージャー、およびビュー
アクセス権の付与
まず最初のステップでは、表の構造を基にしたアクセス権クラスではなく、
ユーザーのジョブを基にしたアクセス権クラスを指定します。例えば、最
初の行のマネージャーは、次のアクセス権が必要です。
• 仮定の hr_data 表での Select アクセス権および限定された Update アクセ
ス権
• 当該およびその他のデータベースへの Connect アクセス権
• これらのデータベース内のいくつかの表でのある程度のアクセス権
マネージャーが幹部職に昇進し、他の部門に異動したときは、これらのす
べてのアクセス権を取り消し、アクセス権の新規セットを付与する必要が
あります。
サポートするアクセス権クラスを定義し、クラスごとに、アクセスを与え
る必要があるデータベース、表、および列を指定します。次に、クラスご
とに 2 つの自動化プロシージャーを作成します。1 つはユーザーへのクラス
の付与、もう 1 つはその取り消しです。
IBM Informix 4GL での自動化
使用する機構は、使用しているオペレーティング・システムおよびその他
のツールによって異なります。プログラマーの場合、最も柔軟なツールは、
おそらく IBM Informix 4GL です。4GL を使用すると、次のコード・サンプル
に示すように、単純なユーザー対話をプログラミングすることが極めて簡
単になります。
DEFINE mgr_id char(20)
PROMPT "What is the user-id of the new manager? " FOR mgr_id
CALL table_grant ("SELECT", "hr_data", mgr_id)
IBM Informix 4GL によって、GRANT 文および REVOKE 文を他のプログラム
文と自由に混合させることができますが、残念ながら、パラメーターをプ
ログラム変数から作成することはできません。ユーザーが入力したユー
ザー ID を使用して、GRANT 文をカスタマイズするには、プログラムは、
その文をストリングとして作成し、それを PREPARE 文で処理してから、
EXECUTE 文で実行する必要があります。( これらの文の詳細は、第 6 章に
説明されており、次の例が詳細に分析されています。)
セキュリティー、ストアード・プロシージャー、およびビュー 11-15
アクセス権の付与
図 11-2 には、上述の例の CALL 文によって起動された 4GL 関数
table_grant() の 1 つの可能な定義が示されています。
FUNCTION table_grant (priv_to_grant, table_name, user_id)
DEFINE priv_to_grant char(100),{may include column-list}
table_name CHAR(20),
user_id CHAR(20),
grant_stmt CHAR(200)
LET grant_stmt =
"GRANT ", priv_to_grant,
" ON ", table_name,
" TO ", user_id
WHENEVER ERROR CONTINUE
PREPARE the_grant FROM grant_stmt
IF status = 0 THEN
EXECUTE the_grant
END IF
IF status <> 0 THEN
DISPLAY "Sorry, got error #", status, "attempting:"
DISPLAY " ",grant_stmt
END IF
WHENEVER ERROR STOP
END FUNCTION
図 11-2
GRANT 文を作成し、PREPARE 文で処理して実行する 4GL 関数
コマンド・スクリプトでの自動化
ユーザーのオペレーティング・システムは、おそらくコマンド・スクリプ
トの自動実行をサポートしていると思われます。通常の稼働環境では、対
話型 SQL ツールである DB-Access および IBM Informix SQL は、コマンド行か
ら実行するために、コマンドおよび SQL 文を適用します。これらの 2 つの
機能を結合させると、アクセス権の管理を自動化することができます。
詳細は、ユーザーのオペレーティング・システムと、使用している
DB-Access または IBM Informix SQL のバージョンによって異なります。基本
的に、次の関数を実行するコマンド・スクリプトを作成できます。
• パラメーターとして、変更されるアクセス権を持つユーザー ID を受け
取る。
• そのユーザー ID を含めるようカスタマイズされた GRANT 文または
REVOKE 文のファイルを準備する。
• データベースを選択して GRANT 文または REVOKE 文の準備済みファイ
ルを実行することを指示するパラメーターを使用して、DB-Access また
は IBM Informix SQL を起動する。
この方法で、ユーザーのアクセス権クラスの変更を 1 つまたは 2 つのコマ
ンドまで削減できます。
11-16 セキュリティー、ストアード・プロシージャー、およびビュー
ストアード・プロシージャーの使用
ストアード・プロシージャーの使用
ストアード・プロシージャーは、Informix ストアード・プロシージャー言
語 (SPL) を使用して書かれたプログラムです。プロシージャーは、一度作成
されると、データベース内に実行可能なフォーマットで格納されます。こ
れは、表などのデータベース・オブジェクトであるため、プロシージャー
で適切なアクセス権を持つユーザーであれば実行することができます。ス
トアード・プロシージャーは、それ自身に含まれる SQL コードに値を追加
します。ストアード・プロシージャーは、作成後に簡単に実行できます。
これらは、実行可能なフォーマットで保管されるため、非常に効率的でも
あります。
ストアード・プロシージャーを使用して、データベース内の個々の表およ
び列へのアクセスを制御できます。プロシージャーを介して、さまざまな
レベルのアクセス制御を達成できます。SPL の強力な機能は、ストアード・
プロシージャーを DBA アクセス権のあるプロシージャーとして指定できる
ことです。DBA アクセス権のあるプロシージャーを作成すると、表アクセ
ス権がほとんどまたは全然ないユーザーが、プロシージャーを実行すると
きに、DBA アクセス権を持つことができるようになります。そのプロシー
ジャーによって、ユーザーは、一時的な DBA アクセス権を使用して、非常
に特定化されたタスクを実行できます。DBA アクセス権の機能によって、
次のタスクを達成できます。
• 個々のユーザーが表から読み取ることができる情報量を制限できる。
• データベースに加えられるすべての変更を制限して、表全体が誤って空
にされたり変更されたりしないことを保証できる。
• 削除または追加など、表に加えられる変更のすべての特定クラスを監視
できる。
• 表、インデックス、およびビューが作成される仕様を完全に制御するた
めに、すべてのオブジェクト作成 ( データ定義 ) をストアード・プロ
シージャー内で発生するように制限できる。
ストアード・プロシージャーの作成および実行
ストアード・プロシージャーを作成するには、CREATEPROCEDURE 文の内
部にプロシージャーの一部として稼働させる SQL 文を書きます。また、追
加の SPL 文を使用して、文の内部で操作の流れを制御することもできます。
これらの追加の文には、IF THEN ELSE、FOR、およびその他の文が含まれま
す ( ストアード・プロシージャーおよび SPL の詳細な説明については、
「IBM Informix SQL リファレンス・ガイド」を参照してください )。
セキュリティー、ストアード・プロシージャー、およびビュー 11-17
ストアード・プロシージャーの使用
例えば、ユーザーが、顧客の名前および住所を読み込むことができるよう
にする場合のストアード・プロシージャーは、図 11-3 に示すとおりです。
CREATE PROCEDURE read_address (lastname CHAR(15))
RETURNING CHAR(15), CHAR(15), CHAR(20), CHAR(15),CHAR(2), CHAR(5);
DEFINE p_lname,p_fname, p_city CHAR(15);
DEFINE p_add CHAR(20);
DEFINE p_state CHAR(2);
DEFINE p_zip CHAR(5);
SELECT fname, lname, address, city, state, zipcode
INTO p_fname, p_lname, p_city, p_state, p_zip
FROM customer
WHERE lname = lastname;
RETURN p_fname, p_lname, p_city, p_state, p_zip;
END PROCEDURE;
図 11-3
customer 表から読み取るプロシージャー
ストアード・プロシージャーは、データベース・ユーザー用の処理を単純
化できます。つまり、ユーザーは SQL のいくつかの複雑なパーツを認識す
る必要はありません。その代わりに、複雑な動作は、SQL を認識している
ユーザーが単純化できます。つまり、そのユーザーは、動作を処理するた
めのストアード・プロシージャーを書き、他のユーザーに、プロシー
ジャーがデータベースに格納され、それを実行できるということを伝えま
す。SQL 機能をプロシージャーの中で非表示にし、さらに、データベースお
よびデータベース内のデータに生じる作業を制御することによって、プロ
シージャーを活用することができます。
プロシージャーを実行するには、DB-Access または埋込み SQL プログラムか
ら、EXECUTEPROCEDURE 文を使用します。read_address プロシージャーを
実行して、“Putnam” という名前の顧客のフルネームおよび住所を参照する
には、次の文を使用します。
EXECUTE PROCEDURE read_address ("Putnum");
次のセクションでは、ストアード・プロシージャーを使用してデータへの
アクセスを制御する 4 つの方法を説明します。
11-18 セキュリティー、ストアード・プロシージャー、およびビュー
ストアード・プロシージャーの使用
データの読込みの制約
図 11-3 でのプロシージャーは、SQL 構文をユーザーに非表示にしますが、
ユーザーは customer 表で SELECT アクセス権を持つ必要があります。ユー
ザーが選択できる項目を制限する場合は、次の環境で稼働するプロシー
ジャーを作成できます。
• 自分が、データベースの DBA である。
• ユーザーが、データベースへの CONNECT アクセス権を持っている。表
における SELECT アクセス権を持つ必要はありません。
• 使用しているストアード・プロシージャー ( またはストアード・プロ
シージャーのセット ) が、DBA キーワードを使用して作成されている。
• 使用しているストアード・プロシージャー ( またはストアード・プロ
シージャーのセット ) がユーザーの表から読み取りを行う。
ユーザーが顧客の名前、住所、および電話番号のみを読み取るようにする
場合は、図 11-3 でのプロシージャーを修正できます。図 11-4 のようにな
ります。
CREATE DBA PROCEDURE read_customer(cnum INT)
RETURNING CHAR(15), CHAR(15), CHAR(18);
DEFINE p_lname,p_fname CHAR(15);
DEFINE p_phone CHAR(18);
SELECT fname, lname, phone
INTO p_fname, p_lname, p_phone
FROM customer
WHERE customer_num = cnum;
RETURN p_fname, p_lname, p_phone;
END PROCEDURE;
図 11-4
顧客データ上の読み取りを制限するストアード・プロシージャー
セキュリティー、ストアード・プロシージャー、およびビュー 11-19
ストアード・プロシージャーの使用
データの変更の制約
ストアード・プロシージャーを使用して、表に加えられる変更を制限でき
ます。単に、すべての変更をストアード・プロシージャーに送ります。す
ると、ユーザーが直接変更するのではなく、ストアード・プロシージャー
が変更を行います。表からすべての行を誤って削除してしまわないように、
ユーザーが一度に削除する行を 1 行に制限する場合は、次のアクセス権を
使用してデータベースをセットアップします。
• 自分が、データベースの DBA である。
• すべてのユーザーが、データベースへの Connect アクセス権を持ってい
る。Resource アクセス権を持っている場合もあります。保護されている
表における Delete ( この例の場合 ) アクセス権は持ちません。
• 使用しているストアード・プロシージャーが、DBA キーワードを使用し
て作成されている。
• 使用しているストアード・プロシージャーが削除を実行する。
図 11-5 の例に類似したストアード・プロシージャーを作成します。ここで
は、WHERE 節にユーザー提供の customer_num を使用して、customer 表か
ら行を削除します。
CREATE DBA PROCEDURE delete_customer(cnum INT)
DELETE FROM customer
WHERE customer_num = cnum;
END PROCEDURE;
図 11-5
行を削除するストアード・プロシージャー
データの変更の監視
ストアード・プロシージャーを使用して、データベースに加えられる変更
を作成できます。特定のユーザーによって加えられた変更を記録したり、
変更が行われるたびに記録を作成したりできます。
11-20 セキュリティー、ストアード・プロシージャー、およびビュー
ストアード・プロシージャーの使用
シングル・ユーザーによってデータベースに加えられるすべての変更を監
視できます。単に、すべての変更を、各ユーザーによって加えられた変更
を追跡するストアード・プロシージャーに送ります。ユーザー acctclrk が
データベースを修正するたびに記録が行われる場合は、次のアクセス権を
使用してデータベースをセットアップします。
• 自分が、データベースの DBA である。
• 他のすべてのユーザーが、データベースへの Connect アクセス権を持っ
ている。Resource アクセス権を持っている場合もあります。保護されて
いる表における Delete ( この例の場合 ) アクセス権は持ちません。
• 使用しているストアード・プロシージャーが、DBA キーワードを使用し
て作成されている。
• 使用しているストアード・プロシージャーが、削除を実行し、変更が特
定のユーザーによって実行されたことを記録する。
図 11-6 の例に類似したストアード・プロシージャーを作成します。ここで
は、ユーザー提供の顧客番号を使用して表を更新します。ユーザーが偶然
にも acctclrk であった場合、削除の記録はファイル “updates” に書き込まれ
ます。
CREATE DBA PROCEDURE delete_customer(cnum INT)
DEFINE username CHAR(8);
DELETE FROM customer
WHERE customer_num = cnum;
IF username = "acctclrk" THEN
SYSTEM "echo Delete from customer by acctclrk >> /mis/records/updates" ;
ENF IF
END PROCEDURE;
図 11-6
行を削除し、特定のユーザーによって加えられた変更を記録する
ストアード・プロシージャー
セキュリティー、ストアード・プロシージャー、およびビュー 11-21
ストアード・プロシージャーの使用
プロシージャーを使用して実行されるすべての削除を、IF 文を除去して
SYSTEM 文をより一般的にすることによって監視できます。図 11-6 のプロ
シージャーを、すべての削除を記録するように変更する場合、図 11-7 のプ
ロシージャーのようになります。
CREATE DBA PROCEDURE delete_customer(cnum INT)
DEFINE username CHAR(8);
LET username = USER ;
DELETE FROM tbname WHERE customer_num = cnum;
SYSTEM
"echo Deletion made from customer table, by "||username ||">>/hr/records/deletes";
END PROCEDURE;
図 11-7
行を削除してユーザーを記録するストアード・プロシージャー
オブジェクト作成の制約
作成されるオブジェクトおよびその作成方法についての制約を決定する場
合は、次の設定内でストアード・プロシージャーを使用します。
• 自分が、データベースの DBA である。
• 他のすべてのユーザーが、データベースへの Connect アクセス権を持っ
ている。Resource アクセス権は持っていません。
• 使用しているストアード・プロシージャー ( またはストアード・プロ
シージャーのセット ) が、DBA キーワードを使用して作成されている。
• 使用しているストアード・プロシージャー ( またはストアード・プロ
シージャーのセット ) が、表、インデックス、およびビューを ( ユー
ザーがこれらをどのように定義したかにかかわらず ) 作成する。このよ
うなプロシージャーを使用して、トレーニング・データベース環境を
セットアップできます。
プロシージャーには、図 11-8 に示すように、1 つまたは複数の表および関
連インデックスの作成が含まれることがあります。
CREATE DBA PROCEDURE all_objects()
CREATE TABLE learn1 (intone SERIAL, inttwo INT NOT NULL, charcol CHAR(10) )
CREATE INDEX learn_ix ON learn1 (inttwo).
CREATE TABLE toys (name CHAR(15) NOT NULL UNIQUE,
description CHAR(30), on_hand INT);
END PROCEDURE;
図 11-8
表およびインデックスをデータベースに追加する DBA モード・プロシージャー
11-22 セキュリティー、ストアード・プロシージャー、およびビュー
ビューの使用
all_objects プロシージャーを使用して表への列の追加を制御するには、
データベース上の Resource アクセス権をすべてのユーザーから取り消しま
す。これにより、ユーザーがプロシージャーの内部で SQL 文を使用して、
表、インデックス、またはビューを作成しようとしても、作成することは
できません。ユーザーがプロシージャーを実行すると、一時的な DBA アク
セス権を持つため、例えば CREATE TABLE 文は続行され、追加されたすべ
ての列が、それらに設定された制約を持つことが保証されます。さらに、
ユーザーが作成したオブジェクトは、そのユーザーによって所有されます。
all_objects プロシージャーの場合、2 つの表およびインデックスはプロシー
ジャーの実行者によって所有されます。
ビューの使用
ビュー は、合成表です。これは、表であるかのように問い合わせることが
できます。また、表であるかのように更新できる場合もあります。しかし、
これは表でなく、むしろ、実表と他のビュー内に存在するデータの合成で
す。
ビューの基本は、SELECT 文です。ビューの作成時には、ビューがアクセス
された時にビューの内容を生成する SELECT 文を定義します。また、ユー
ザーは SELECT 文を使用して、ビューの問合せも実行します。データベー
ス・サーバーは、ユーザーの SELECT 文と、ビューに定義された文とを
マージし、次に、実際に結合された文を実行します。
その結果、表のように見えます。他のビュー、または表と他のビューとの
結合に基づく表のように見えます。
ビューの内容を決定する SELECT 文を作成するため、次のどの目的にも
ビューを使用できます。
• ユーザーのアクセスを特定の表の列に制約する。
ビュー内の選択リストで許可された列だけを命名します。
• ユーザーのアクセスを特定の表の行に制約する。
許可された行だけを戻す WHERE 節を指定します。
• 挿入および更新された値を特定の範囲に制約する。
制約を施行するには、WITH CHECK OPTION (11-29 ページ ) を参照してく
ださい。
• データベース内に冗長データを格納する必要なく、導出データへのアク
セスを提供する。
セキュリティー、ストアード・プロシージャー、およびビュー 11-23
ビューの使用
データをビュー内の選択リストに導出する表現式を書きます。ビューを
問い合わせるたびに、データが新しく導出されます。導出データは、常
に最新のものですが、冗長データはデータ・モデルへ導入されません。
• 複雑な SELECT 文の詳細を非表示にする。
ユーザーもアプリケーション・プログラマーも反復する必要がないよう
に、ビュー内の複数表結合の複雑な内容が表示されないようにします。
ビューの作成
次の例では、デモンストレーション・データベース内に表を基にした
ビューを作成します。
CREATE VIEW name_only AS
SELECT customer_num, fname, lname FROM customer
ビューは、表の 3 つの列だけを公開します。WHERE 節は含まれないため、
ビューは表示できる行を制約しません。
次の例は、2 つの表の結合を基にしています。
CREATE VIEW full_addr AS
SELECT address1, address2, city, state.sname, zipcode
FROM customer, state
WHERE customer.state = state.code
州名の表はデータベースの冗長度を減らします。"Minnesota" などのロン
グ・ネームは 1 回だけ格納できます。この full_addr ビューによって、ユー
ザーは、州の完全名がすべての行に格納されているかのように住所を抽出
できます。次の 2 つの問合せは、同じものです。
SELECT * FROM full_addr WHERE customer_num = 105
SELECT address1, address2, city, state.sname, zipcode
FROM customer, state
WHERE customer.state = state.code
AND customer_num = 105
ただし、結合を基にしたビューを定義するときには管理をする必要があり
ます。このようなビューは、修正可能 ではありません。つまり、これらは
UPDATE 文、DELETE 文、または INSERT 文を使用できません ( ビューの修正
については、11-27 ページから始まるセクションで説明されています )。
11-24 セキュリティー、ストアード・プロシージャー、およびビュー
ビューの使用
次の例は、ビュー内で表示できる行を制約します。
CREATE VIEW no_cal_cust AS
SELECT * FROM customer WHERE NOT state = "CA"
このビューは、customer 表のすべての列を公開しますが、行は特定の行の
みです。次の例は、ユーザーに関係する行だけにユーザーを制約する
ビューです。
CREATE VIEW my_calls AS
SELECT * FROM cust_calls WHERE user_id = USER
cust_calls 表のすべての列が使用できますが、問合せを実行するユーザーの
ユーザー ID を含む行でのみ使用できます。
ビューからの行の重複
基礎表が一意な行しか持たない場合でも、ビューが重複行を作成する場合
があります。ビュー SELECT 文が重複行を戻すことができる場合、ビュー
自体が重複行を含むように見える場合があります。
この問題は、2 つの方法で回避できます。1 つの方法は、ビュー内の選択リ
ストで DISTINCT を指定します。ただし、これによってビュー内を修正でき
なくなります。代替の方法は、一意であるように制約されている列または
列グループを常に選択することです ( 主キーまたは候補キーの列を選択す
る場合は、確実に一意な列のみが戻されます。主キーおよび候補キーにつ
いては、第 8 章に説明されています )。
ビューの制限事項
ビューは実際には表ではないため、インデックス付けできず、ALTERTABLE および RENAME TABLE などの文のオブジェクトにはなれません。
ビューの列は、RENAMECOLUMN を使用して名前変更できません。ビュー
の定義について変更する場合は、ビューを削除して再作成する必要があり
ます。
セキュリティー、ストアード・プロシージャー、およびビュー 11-25
ビューの使用
ユーザーの問合せとマージされる必要があるため、ビューを基にした
SELECT 文に次の節を含めることはできません。
INTO TEMP
ユーザーの問合せには、INTO TEMP が含まれる場合があり
ます。ビューにもこれが含まれる場合、データは移動先が
分からなくなります。
UNION
ユーザーの問合せには、UNION が含まれる場合がありま
す。実際、ビューでの問合せが、ユーザーの問合せ内の
UNION 節に表示される場合があります。入れ子にされた
UNION 節には、何の意味も定義されていません。
ORDER BY
ユーザーの問合せには、ORDER BY が含まれる場合があり
ます。ビューにもこれが含まれる場合、列またはソート出
力先の選択が競合する可能性があります。
基本変更時
ビューを基にした表およびビューは、いくつかの方法で変更される可能性
があります。ビューには、自動的にほとんどの変更が反映されます。
表またはビューが削除されると、同じデータベース内でそれに依存してい
るすべてのビューが自動的に削除されます。
ビューの定義を変更する唯一の方法は、そのビューを削除してから再作成
することです。したがって、他のビューが依存しているビューの定義を変
更する場合は、他のビューも再作成する必要があります ( 他のビューもす
べて削除されたため )。
表が名前変更されると、同じデータベース内でそれに依存しているすべて
のビューが新規名を使用するように修正されます。列が名前変更されると、
同じデータベース内でその表に依存しているビューが正確な列を選択する
ように更新されます。ただし、ビュー自体にある列名は変更されません。
この例の場合、customer 表で次のビューを再呼び出しします。
CREATE VIEW name_only AS
SELECT customer_num, fname, lname FROM customer
ここで、customer 表が次の方法で変更されるものと想定します。
RENAME COLUMN customer.lname TO surname
11-26 セキュリティー、ストアード・プロシージャー、およびビュー
ビューの使用
顧客のラストネームを直接選択するには、ここで新列名を選択する必要が
あります。ただし、ビューで表示される列名は未変更のままです。次の 2
つの問合せは、同じものです。
SELECT fname, surname FROM customer
SELECT fname, lname FROM name_only
列を削除して表を変更するとき、ビューは修正されません。ビューが使用
されると、エラー -217 ( どの表にも列が見つかりません ) が生じます。
ビューが削除されない理由は、列を削除して、次に同名の新規列を追加す
ることによって、表内の列の順序を変更できるからです。これを行うと、
その表を基にしたビューは作業を続行します。ビューは、既存のシーケン
スの列を保存します。
IBM Informix OnLine では、ビューは外部データベース内の表およびビュー
に基づいて作成できます。他のデータベースの表およびビューへの変更は、
ビュー内に反映されません。このような変更は、他のユーザーがビューを
問い合わせし、外部表が変更されたためにエラーを受け取るまで、明白に
ならない場合があります。
ビュー全体を通した修正
表であるかのようにビューを修正できます。修正できるビューもあればで
きないものもあり、これは各ビューの SELECT 文によって決まります。制
約事項は、DELETE 文、UPDATE 文、または INSERT 文のどれを使用してい
るかによって異なります。
SELECT 文に次の機能のいずれかが含まれている場合、ビューで修正はでき
ません。
• 複数の表の結合
データベース・サーバーが、結合された表を渡って変更されたデータを
正確に分散しようとすると、多くの変則的な状況が生じます。
• 集計関数または GROUP BY 節
ビューの行は、多くの結合されたデータの行を表します。データベー
ス・サーバーは、変更されたデータをそれらの行に分散できません。
•
DISTINCT キーワードまたはそのシノニム UNIQUE
ビューの行には、多数存在する可能性のある重複行の中からの選択が示
されます。データベース・サーバーは、変更を受け取らなければならな
い既存の行を認識できません。
セキュリティー、ストアード・プロシージャー、およびビュー 11-27
ビューの使用
ビューがこれらのすべてを回避できれば、ビューのそれぞれの行は、表の
1 行と厳密に対応します。このようなビューは、修正可能 です ( もちろん、
適切なアクセス権を持つ特定ユーザーのみがビューを修正できます。
ビューにおけるアクセス権については、11-31 ページから始まるセクション
で説明します )。
ビュー全体を通した削除
修正可能ビューは、表であるかのように DELETE 文と共に使用できます。
データベース・サーバーは、基礎表の適切な行を削除します。
ビューの更新
修正可能ビューは、表であるかのように UPDATE 文と共に使用できます。
ただし、修正可能ビューにはまだ、導出列、つまり、CREATE VIEW 文の選
択リストの表現式によって作成された列が含まれている可能性があります。
導出列 ( 仮想 列と呼ばれることもある ) は更新できません。
列が、定数値を使用した列の単純な算術計算の組合せから導出される場合
( 例えば、order_date+30)、データベース・サーバーは、原則として表現式
の切り替え方法 ( この場合は、更新値から 30 を減ずる ) を見つけだし、更
新を実行できます。ただし、これより非常に複雑な表現式が考えられ、そ
れらのほとんどは簡単に切り替えできません。したがって、データベー
ス・サーバーは、導出列の更新をサポートしません。
図 11-9 には、導出列を含む修正可能ビューおよびそれに対して受け入れる
ことができる UPDATE 文が示されています。
CREATE VIEW call_response(user_id,received,resolved,duration)AS
SELECT user_id,call_dtime,res_dtime, res_dtime -call_dtime
FROM cust_calls
WHERE user_id = USER
UPDATE call_response SET resolved = TODAY
WHERE resolved IS NULL
図 11-9
修正可能ビューおよび UPDATE 文
ビューの期間列は、表現式を表すため更新できません ( データベースは、
表現式内に指定された 2 つの列の間での更新値の分配方法をほとんど判別
できません )。しかし、SET 節に導出列が指定されていない限り、ビューが
表であるかのように更新を実行できます。
11-28 セキュリティー、ストアード・プロシージャー、およびビュー
ビューの使用
ビューは、基礎表の行が一意な場合でも重複行を戻す可能性があります。
重複行を他の行と区別することはできません。重複行のセットの 1 つを更
新する場合 ( 例えば、カーソルを使用して WHERE CURRENT を更新する )、
基礎表内のどの行が更新を受け取るのかは確実には分かりません。
ビューへの挿入
ビューが修正可能、かつ 、導出列を含まない場合、行をビューに挿入でき
ます。2 つ目の制約の理由は、挿入された行はすべての列に値を提供する
必要があり、データベース・サーバーは表現式を介して挿入された値の分
散方法を認識できないためです。図 11-9 に示されるように、call_response
ビューに挿入しようとすると、失敗します。
修正可能ビューに導出列が含まれない場合、ビューが表であるかのように
そのビューに挿入できます。ただし、データベース・サーバーは、ビュー
によって公開されない列の値に NULL を使用します。このような列で
NULL が許可されない場合には、エラーが発生し、挿入は失敗します。
WITH CHECK OPTION の使用
ビューの条件を満たさない行、つまり、ビューを通じて不可視である行を
ビューに挿入できます。また、ビューの条件を満たさないように、ビュー
の行を更新することもできます。
これが不適切な場合、ビューの作成時に WITHCHECK OPTION 節を追加でき
ます。この節は、すべての挿入済みまたは更新済み行を検査して、その行
がビューの WHERE 節で設定された条件に合うことを確認するように、デー
タベース・サーバーに依頼します。データベース・サーバーは、条件が合
わない場合は、エラーを表示し操作を拒否します。
図 11-9 では、call_response という名前のビューが、次のように定義されて
います。
CREATE VIEW call_response(user_id,received,resolved,duration)AS
SELECT user_id,call_dtime,res_dtime,res_dtime -call_dtime
FROM cust_calls
WHERE user_id = USER
次の例のようにして、ビューの user_id 列を更新できます。
UPDATE call_response SET user_id = "lenora"
WHERE received BETWEEN TODAY AND TODAY-7
セキュリティー、ストアード・プロシージャー、およびビュー 11-29
アクセス権およびビュー
ビューには、user_id が USER と等しい行が必要です。この更新が tony とい
う名前のユーザーによって実行される場合、更新済み行はビューからなく
なります。しかし、次の例のようにしてビューを作成できます。
CREATE VIEW call_response (user_id,received,resolved,duration)AS
SELECT user_id,call_dtime,res_dtime,res_dtime-call_dtime
FROM cust_calls
WHERE user_id = USER
WITH CHECK OPTION
次に、tony による上述の更新がエラーとして拒否されます。
WITH CHECK OPTION 機能を使用して、ブール (Boolean) 式として記載できる
任意の種類のデータの制約を強制できます。例えば、データ上のすべての
論理的制約が、WHERE 節の条件として表現されている表のビューを作成し
ます。次に、ビューを通じて実行される表のすべての修正を要求します。
CREATE VIEW order_insert AS
SELECT * FROM orders O
WHERE order_date = TODAY -- no back-dated entries
AND EXISTS -- ensure valid foreign key
(SELECT * FROM customer C
WHERE O.customer_num = C.customer_num)
AND ship_weight < 1000 -- reasonableness checks
AND ship_charge < 1000
WITH CHECK OPTION
EXISTS および他の検査のすべてが、既存の行を抽出するときに正常終了す
ると予期されているため、このビューは orders からデータを表示するには
最も非効率的です。ただし、orders への挿入がこのビューを通してのみ行
われる ( また、データを制約するために整合性制約をまだ使用していない )
場合、過去の注文、無効な顧客番号、または超過した発送重量や発送料金
を挿入することはできません。
アクセス権およびビュー
ユーザーがビューを作成する と、データベース・サーバーは、基礎表と基
礎ビューにおけるユーザーのアクセス権を検査します。ユーザーがビュー
を使用する と、そのビュー自体に関するユーザーのアクセス権のみが検査
されます。
11-30 セキュリティー、ストアード・プロシージャー、およびビュー
アクセス権およびビュー
ビュー作成時のアクセス権
ユーザーがビューを作成すると、データベース・サーバーは、ユーザーが
ビュー定義での SELECT 文の実行に必要なすべてのアクセス権を持ってい
ることを確認する検査を行います。持っていない場合、ビューは作成され
ません。
この検査によって、ユーザーが、表でビューを作成してそのビューを問い
合わせた場合、表への無許可アクセス権を取得することが確実にできなく
なります。
ビューの作成後は、データベース・サーバーによって、ビューの作成者か
つ所有者であるユーザーに、少なくともビューでの Select アクセス権が与
えられます。新規に作成された表の場合のように、パブリックへの自動付
与は行われません。
データベース・サーバーは、ビュー定義を検査して、ビューが修正可能か
どうかをチェックします。修正可能である場合、データベースは、ビュー
における Insert、Delete、および Update の各アクセス権を、ユーザーがこれ
らのアクセス権を基礎表または基礎ビューにも持つという条件で、ユー
ザーに付与します。つまり、新規ビューが修正可能である場合、データ
ベース・サーバーは Insert、Delete、および Update の各アクセス権を基礎表
または基礎ビューからコピーし、それらを新規ビューで許可します。した
がって、基礎表において Insert アクセス権しか持たない場合には、ビュー
は Insert アクセス権しか受け取りません。
この検査によって、ユーザーは、まだ持っていなかったアクセス権を取得
する場合にビューを使用できないことが確実になります。
ビューを変更またはインデックス付けできないため、Alter アクセス権およ
び Index アクセス権は、ビューに対して許可されません。
ビュー使用時のアクセス権
ユーザーがビューを使用しようとすると、データベース・サーバーは、
ビューでユーザーに許可されたアクセス権のみを検査します。基礎表への
アクセス権も検査しません。
ビューを作成した場合、ユーザーのアクセス権は前のパラグラフに示され
たものです。作成者でない場合は、作成者または WITH GRANT OPTION アク
セス権を持つユーザーによって付与されたアクセス権を持ちます。
セキュリティー、ストアード・プロシージャー、およびビュー 11-31
アクセス権およびビュー
このことは、表を作成して、その表へのパブリック・アクセスを取り消す
ことができることを意味しています。次に、ビュー全体を通して表への限
定されたアクセス権を付与できます。これは、hr_data 表を使用した以前の
例によって説明できます。その定義を、図 11-10 に繰り返します。
CREATE TABLE hr_data
(
emp_key INTEGER,
emp_name CHAR(40),
hire_date DATE,
dept_num SMALLINT,
user-id CHAR(18),
salary DECIMAL(8,2)
performance_level CHAR(1)
performance_notes TEXT
)
図 11-10
従業員機密情報の表 ( 図 11-1 の複製 )
図 11-10 では、この表に直接アクセス権を付与することを中心に例が展開
されました。次の例では、違ったアプローチを取ります。表が作成された
ときに、次の文が実行されたものと仮定してください。
REVOKE ALL ON hr_data FROM PUBLIC
( これは、ANSI 準拠データベースでは必要ありません。) 次に、異なるクラ
スのユーザー用に一連のビューを作成します。機密でない列への読取り専
用アクセスを持つべきユーザーには、次のビューを作成します。
CREATE VIEW hr_public AS
SELECT emp_key, emp_name, hire_date, dept_num, user_id
FROM hr_data
このビューの Select アクセス権を付与されているユーザーは、機密でない
データを参照できますが、更新はできません。新規行を入力する必要のあ
る人事課のクラークの場合は、次のような異なるビューを作成します。
CREATE VIEW hr_enter AS
SELECT emp_key, emp_name, hire_date, dept_num
FROM hr_data
11-32 セキュリティー、ストアード・プロシージャー、およびビュー
アクセス権およびビュー
これらのユーザーに、このビューにおける Select アクセス権および Insert ア
クセス権の両方を付与します。表およびビューの両方の作成者であるユー
ザーは、その表およびビューにおいて Insert アクセス権を持つため、
ビューでの Insert アクセス権を、表でのアクセス権を持たない他のユー
ザーに付与することができます。
新規ユーザー ID を入力または更新する MIS 部門のクラークの代わりに、次
のように別のビューを作成します。
CREATE VIEW hr_MIS AS
SELECT emp_key, emp_name, user_id
FROM hr_data
このビューは、部門番号および雇用日付を公開しない点で、上述のビュー
とは異なります。
最後に、マネージャーはすべての列へのアクセスを必要とし、自分の部下
のみの功績評価データを更新する機能を必要とします。これらの要件は、
次の方法で満たすことができます。
hr_data 表には、部門番号および従業員ごとのコンピューターのユーザー
ID が含まれています。マネージャーは、自らが管理する部門のメンバーで
あると規定します。次に、次のビューでマネージャーを自分の部下のみを
示す行に制約します。
CREATE VIEW hr_mgr_data AS
SELECT * FROM hr_data
WHERE dept_num =
(SELECT dept_num FROM hr_data
WHERE user_id = USER)
AND NOT user_id = USER
マネージャーが表の独自の行への更新アクセスを持たないように、最終の
条件が必要となります。このため、このビューの Update アクセス権をマ
ネージャーに付与しますが、選択した列だけの Update アクセス権を付与す
る方が安全です。次の文のようになります。
GRANT SELECT, UPDATE (performance_level, performance_notes)
ON hr_mgr_data TO peter_m
セキュリティー、ストアード・プロシージャー、およびビュー 11-33
サマリー
サマリー
パブリック資料を含むデータベース、またはユーザー自身と信頼できる同
僚だけが使用するデータベースにおいては、セキュリティーは重要な考慮
事項ではなく、この章での考え方はほとんど必要ありません。しかし、
データを使用および修正できるユーザーが増えるにつれて、また、データ
がより機密性が高くなるにつれて、ユーザーがデータにアクセスできる方
法を制御するために、より多くの時間を費やし、これまで以上に工夫をす
る必要があります。
ここで説明した技法は、次の 2 つのグループに分けることができます。
• データの機密を保持する。
データベースがオペレーティング・システム・ファイルにあるときは、
そのオペレーティング・システムの機能を使用して、データベースへの
アクセスを拒否できます。いかなる場合でも、ユーザーをデータベース
外にとどめておくために、Connect アクセス権の付与を制御します。
異なるクラスのユーザーが異なる許可のレベルを持つとき、それらの
ユーザーすべてに Connect アクセス権を許可する必要があります。表レ
ベルのアクセス権を使用して、機密の表または列へのアクセスを拒否で
きます。または、ストアード・プロシージャーを使用して、機密の表ま
たは列への限定されたアクセスを提供することもできます。さらに、表
への全アクセスを拒否し、機密の行または列を公開しないビューを介し
てのみアクセスを許可することができます。
• データおよびデータベース構造への変更を制御する。
Resource、Alter、References、および DBA の各アクセス権の許可を制約
することによって、データ・モデルの整合性を保護します。Delete およ
び Update のアクセス権の許可を制御することによって、また、できる
限り少ない列で Update アクセス権を許可することによって、確実に権
限保持者だけがデータを修正するようにします。データ上の論理的制約
を表現するビューでのみ Insert アクセス権を許可することによって、一
貫した、合理的なデータのみが確実に入力されるようにします。代わり
に、データの挿入および修正、またはデータベース自体の修正を、制約
的なストアード・プロシージャーへのアクセスを制限することによって
制御することもできます。
11-34 セキュリティー、ストアード・プロシージャー、およびビュー
ネットワークと分散
概要 3
ネットワークの構成 3
ローカル・エリア・ネットワーク 4
データベース・サーバーのネットワーキング 6
ネットワークの透過性 8
データへの接続 8
LAN での接続 8
IBM Informix NET を介した接続 9
IBM Informix NET のロール 9
データベースのオープン 9
ファイル指定を使用した明示的な格納場所 10
データベース・サーバー名による
明示的な格納場所 11
暗黙的なデータベース格納場所 11
分散型データ 13
外部表の命名 13
外部表を使用したシノニムの使用 14
シノニム連鎖 15
外部表の修正 16
サマリー 17
第
12
章
12-2 ネットワークと分散
概要
アプリケーション、データベース・サーバー、およびデータがすべて同じ
コンピューター上に配置されている状態を考えるのが最もシンプルです。
しかし、他にもさまざまな配置方法が可能です。アプリケーションとデー
タベース・サーバーは異なるコンピューターにあり、データは数多くの他
のコンピューターを経由して分散される場合もあります。
この章では、概念的なレベルで可能な配置、およびパフォーマンスと有用
性におけるいくつかの影響について説明します。また、次の 3 つのネット
ワークについても説明します。
• ローカル・エリア・ネットワーク (LAN)
• アプリケーションが、他のマシン ( 通常 UNIX) で実行されているデータ
ベース・サーバーと連動する一般的なネットワーク
•
IBM Informix STAR によって実装された分散問合せ
実際的なコンピューター・ネットワークが機能するようにするは、ハード
ウェアとソフトウェアに関する数多くの技術の詳細を把握しておく必要が
あります。これらの詳細は、膨大な量であるだけでなく、変更されるのも
速いため、本書ではすべて説明することはできません。使用する
IBM Informix クライアント・サーバーに付随のマニュアルを参照してくだ
さい。
ネットワークの構成
図 12-1 に、最も簡単なデータベース構成を図式化して示します。システム
のコンポーネントは、次のとおりです。
• アプリケーション・プログラム。問合せを実行するプログラムが含まれ
ています。IBM Informix 4GL または埋込み SQL を持つ他の言語で書かれ
たプログラムに加え、コンパイル済みのスクリーン・フォームとレポー
トも含まれています。
• データベース・サーバー。アプリケーションから SQL 文を受け取り、
データの選択済み行をそのアプリケーションに戻します。
ネットワークと分散 12-3
ネットワークの構成
• オペレーティング・システム。コンピューター・ファイル・システムを
管理します。直接ディスク領域を管理するデータベース・サーバーもあ
ります。
• ディスク装置。ここに、表が実際に格納されています。
.
アプリケーショ
ン・プログラム
B
図 12-1
データベー
ス・サーバー
オペレーティン
グ・システム
A
簡単なデータベース構成
図 12-1 には、幅広いシステムが示されています。例えば、オペレーティン
グ・システムは PC-DOS または MS-DOS、データベース・サーバーは
IBM Informix SE が利用可能です。プログラムは、IBM Informix 4GL で作成で
きます。
また、少しの変更で、図 12-1 は、UNIX または NetWare オペレーティング・
システムのいずれか、および IBM Informix OnLine データベース・サーバー
にすることもできます。この図では、並行して実行されている 1 つのアプ
リケーション・プログラムではなく複数のアプリケーション・プログラム
の状態であり、そのすべてのアプリケーション・プログラムが、対応する
データベース・サーバーからサービスを受けています。
これらの構成での共通点は、すべてのコンポーネントが同じコンピュー
ターで実行されているということです。ただし、ダイアグラムの中で A お
よび B とマークされたいずれかのポイントでシステムを分け、ソフトウェ
アとハードウェアの層を挿入し、これにより、システムを 2 つ以上のコン
ピューターに分散することもできます。
ローカル・エリア・ネットワーク
図 12-1 の A のポイントで分割が生じる構成は、ローカル・エリア・ネット
ワーク (LAN) です。LAN では、ユーザーは、オペレーティング・システム、
データベース・サーバー、およびアプリケーションを含むコンピューター
を 1 つ持ちます。ただし、表が含まれるディスクは、図 12-2 に示されるよ
うに、ファイル・サーバー と呼ばれる他のコンピューターに接続されてい
ます。
12-4 ネットワークと分散
ネットワークの構成
ファイル・サーバーは、要求を受け取りディスク・ファイルを他のマシン
に配布します。LAN ソフトウェアは、あらゆる実用的な目的のために、
ファイル・サーバーのディスクが直接それぞれのユーザーのコンピュー
ターに接続されているように見せます。PC-DOS と MS-DOS の Informix デー
タベース・エンジンは、この構成をサポートしています。
LAN の利点は、データベース表が単一の場所に保持されていても、ネット
ワーク上のすべてのユーザーがそれらを利用できるということです。LAN
は、より多くのユーザーに対して簡単に経済的にサービスするように拡張
することができます。
アプリケーショ
ン・プログラム
データベー
ス・サーバー
オペレーティン
グ・システム
ファイル・
サーバー
アプリケーショ
ン・プログラム
図 12-2
データベー
ス・サーバー
オペレーティン
グ・システム
LAN の構成
LAN 構成には、パフォーマンスの問題があります。データベース・サー
バーが読み込むすべてのデータは、ファイル・サーバーからネットワーク
上を通過する必要があります。このプロシージャーは、ローカル・ディス
クへのアクセスよりも常に遅くなります。また、すべてのユーザーからの
ディスク入出力要求は、ネットワーク上をファイル・サーバーを介して通
過する必要があります。このため、いくつかのユーザーが同時にビジー状
態の場合には、遅延が生じることがあります。
ネットワークと分散 12-5
ネットワークの構成
データベース・サーバーのネットワーキング
明らかに、LAN の問題は、図 12-1 を B とマークされたポイントで分割する
ことで解決されます。つまり、データベース・サーバーをアプリケーショ
ンから離し、ディスクが接続されているコンピューターに移動します。こ
のようにすると、処理されたデータのみ、つまり問合せを満たす選択済み
行が、ネットワーク上で受け渡されます。
IBM Informix NET 製品は、この構成をサポートしています。いくつかの
IBM Informix NET 製品があり、そのそれぞれが異なる型のネットワーク用に
作られています。標準構成は、図 12-3 に示されています。
ネットワークには、データベース・サーバーを含む 1 つまたは複数のコン
ピューターを含めることができます。図 12-3 では、1 つのコンピューター
が示されています。これには、IBM Informix SE または IBM Informix OnLine
のデータベース・サーバーが含まれます。マシンごとに、異なるデータ
ベース・サーバーをネットワーク上に持つこともできます。また、それぞ
れのデータベース・サーバーの複数のコピーを、ネットワーク上、同じマ
シン、または異なるマシンに保持することもできます。
それぞれのデータベース・サーバーは、ネットワーク・サービスを提供し
ます。ネットワーク・サービスが定義され、ネットワークで使用可能にす
る手順は、使用中のクライアント / サーバーのソフトウェアの型によって
異なります。
12-6 ネットワークと分散
ネットワークの構成
アプリケーショ
ン・プログラム
アプリケーショ
ン・プログラム
IBM Informix
データベース・サーバー
製品
アプリケーショ
ン・プログラム
図 12-3
• IBM Informix NET
•
製品
•
IBM Informix
クライアント /
サーバー製品
IBM Informix NET
製品
IBM Informix NET 製品の標準構成
図 12-3 には、アプリケーション・プログラムが含まれるマシンが 2 つ描か
れています。上部のマシンには、いくつかのアプリケーションが含まれま
す。このマシンは、複数の同時実行プログラムをサポートするため、UNIX
などのオペレーティング・システムを実行している必要があります。
図 12-3 の下部のマシンには、1 つのアプリケーションしか含まれません。
これは、PC-DOS または MS-DOS を実行している可能性があります。これら
のすべての構成は、IBM Informix NET のバージョンによってサポートされて
います。
ネットワークと分散 12-7
データへの接続
ネットワークの透過性
これらのすべてのネットワーク構成において、アプリケーション・プログ
ラムは基本的に変更されない、ということを理解しておくことが大切です。
ネットワーク・データベースと連動するレポート、フォーム、またはプロ
グラムに特別なことはありません。
次の項で説明する 1 つの可能な変更を除き ( データベースを参照するとき
のデータベース・サーバー名の使用 )、アプリケーションをローカル・デー
タベースに対して実行し、その後、同一のアプリケーションを別のマシン
のデータベースに対して実行することができます。プログラムは、いずれ
の場合も同等に正しく実行されます。実際は、データ・モデルが同じであ
る限り、プログラムは、ローカル・データベース・サーバーとリモート・
データベース・サーバーとの違いを認識することができません。
データへの接続
アプリケーションとそのデータが異なるコンピューターに移動される場合、
すぐに次の 2 つの疑問が生じます。それらを再接続するにはどうすればよ
いでしょうか ? 別の場所に移動してしまったデータを、アプリケーショ
ンはどのように検索するのでしょうか ?
LAN での接続
LAN は、ファイル・サーバーに接続されたディスクを、ユーザーのマシン
に接続されているように見せるように設計されています。結果として、
データベースと表は、それらが保管されているディスクとディレクトリー
を指定することによって、通常と同じように検索されます。
データベース・サーバーは、データベースの検索に、環境変数 DBPATH を
使用します。データベースへのパスによってネットワーク上のどこかにあ
るディスクが指定される場合、データベース・サーバーはデータベースが
存在する場所の違いを認識することはありません。
Informix DOS エンジンを使用すると、次の例のように特定の格納場所に表
を作成できます。
CREATE TABLE net_tab
(
col_1 integer,
col_2 float
)
IN "F:\tables"
12-8 ネットワークと分散
データへの接続
この機能によって、特定のディスク上に表を配置することができるように
なります。例えば、ファイル・サーバーごとに異なる表を書き込み、ネッ
トワーク・ロードのバランスを取ることができます。
注 : IBM Informix UNIX データベース・サーバーでは、特定のパス名
(IBM Informix SE) または DB 領域 (IBM Informix OnLine) に表を作成できます
が、すべての表はデータベース・サーバーが実行されているコンピュー
ターに接続されたディスク上にある必要があります。
IBM Informix NET を介した接続
IBM Informix NET 製品は、さまざまな種類のネットワーク型、オペレーティ
ング・システム、およびデータベース・サーバーをサポートします。アプ
リケーションをそのデータに接続させる基本的なメソッドは決まっていま
すが、オペレーティング・システム、ネットワーク、およびデータベー
ス・サーバーのすべての組み合わせには、特別なケースがあります。ここ
では、基本的なアイデアだけを説明します。詳細については、使用してい
る IBM Informix NET 製品のドキュメントを参照してください。
IBM Informix NET のロール
アプリケーションは実行を開始すると、環境変数を使用して、使用する
データベース・サーバーを検出します。IBM Informix NET をインストールす
る前には、アプリケーションはデータベース・サーバーを検出します。イ
ンストール後、代わりに IBM Informix NET を検出します。IBM Informix NET
は、アプリケーションの要求を監視し、それらの要求を実際のデータベー
ス・サーバーに渡します。アプリケーションは、ソフトウェアのこの追加
の階層を認識しません。
データベースのオープン
他の処理を実行できるようになる前に、アプリケーションはデータベース
をオープン する必要があります。ほとんどの場合、DATABASE 文を実行す
ると、オープンします。あまりないケースですが、CREATE DATABASE 文を
使用して実行されることもあり、これによりデータベースが作成されて
オープンされます。データベースがオープンされるまでは、DROP DATABASE などの他の少数の SQL 文のみを実行できます。
ネットワークと分散 12-9
データへの接続
データベースがオープンされるとすぐに、IBM Informix NET はデータベース
の格納場所を決定し、それを制御するデータベース・サーバーを検索しま
す。IBM Informix NET は、DATABASE 文や CREATE DATABASE 文のなかの情
報、および DBPATH 環境変数の内容から、データベースがアプリケーショ
ンと同じマシンに配置されているか、または異なるマシンに配置されてい
るかを判断します。異なるマシンに配置されていた場合、IBM Informix NET
は、そのマシン内のデータベース・サーバーとの通信を確立し、次に、ア
プリケーションとデータベース・サーバーとの間で要求とデータを渡すた
めのチャネルとして機能します。
ファイル指定を使用した明示的な格納場所
データベースの格納場所を、データベース名の一部として指定することが
できます。DOS マシンで実行されているアプリケーションにおける例を示
します。
DATABASE "D:\DBS\TESTDB"
次に、UNIX 系アプリケーションからの類似例を示します。( スラッシュ (/)
が使用されているために分かります。)
DATABASE "/usr/maxtel/testdb"
データベースは、おそらくローカルです。IBM Informix NET は、このマシン
でコピーの IBM Informix SE データベース・サーバーを開始し、アプリケー
ションがそのデータベース・サーバーを使用します。
いくつかの UNIX システム上では、同一のフォームを持つ DATABASE 文が
異なるマシンを指す可能性があります。次のような場合です。
DATABASE "/subtle/dbdir/testdb"
この例では、subtle という名前の UNIX ファイル・システムが異なるマシン
に物理的に接続されていると考える必要があります。これは、ネットワー
ク・ファイル・システム (NFS) 機能またはリモート・ファイル共用 (RFS) 機
能を使用して、アプリケーション・マシンにマウントされています。ファ
イル指定内の項目は、このことを反映していません。ただし、IBM Informix
NET は、ファイル・システムがアプリケーション・マシンのローカルでは
ないことを認識します。subtle を所有するマシンで、コピーの IBM Informix
SE を開始して、アプリケーションの要求をマシンに渡します。
12-10 ネットワークと分散
データへの接続
データベース・ファイル指定の最初にある 2 つのスラッシュ (/) は、ネット
ワーク・マシン名を示します。これらは、DOS アプリケーションで使用さ
れる場合でも、常に正方向のスラッシュです。次に、その例を示します。
DATABASE "//avignon/usr/maxtel/testdb"
パス名の最初にあるダブル・スラッシュは、IBM Informix NET に、データ
ベースが異なるマシン ( この場合は、avignon としてネットワークに登録さ
れているマシン ) 上に配置されていることを伝えます。完全なファイル指
定を処理するために、IBM Informix SE がデータベースを管理する必要があ
ります。(IBM Informix OnLine は標準ファイル・システムを使用しません。)
IBM Informix NET は、マシン avignon でデータベース・サーバーを開始し、
そのデータベース・サーバーとアプリケーションとの間のチャネルとして
機能します。
データベース・サーバー名による明示的な格納場所
完全なファイル指定が必要でない場合は、データベースの格納場所を、次
のような異なるフォームで指定できます。
DATABASE telefonen@munchen
データベース名は telefonen です。これは、munchen としてネットワークに
登録されているマシンに配置されます。このメソッドは、データベースが
IBM Informix OnLine データベース・サーバーによって管理されるときに、
データベースの格納場所を指定するために使用します。
CREATEDATABASE コマンドと DROP DATABASE コマンドを使用して、同じ
フォームの文を使用できます。ただし、これらのコマンドの 1 つに明示的
な格納場所を指定する場合は、アプリケーションをその格納場所に制限し
ます。これは、異なる格納場所でデータベースを使用する場合は、変更す
る必要があります。
暗黙的なデータベース格納場所
コマンド内のデータベース名は、ID のみで構成されるため、格納場所への
手掛かりが分からないことがよくあります。この場合、DATABASE、CREATE DATABASE、および DROP DATABASE の文を作成するのが最善の方法で
す。これは、データベースの格納場所が変更されるときにアプリケーショ
ンを変更する必要がなくなるためです。
ネットワークと分散 12-11
データへの接続
名前だけを与えているデータベースをアプリケーションがオープンしよう
とするときは、IBM Informix NET は DBPATH 環境変数を見て情報を入手しま
す。
この環境変数は、データベースが検索される可能性のあるすべての格納場
所をリストします。ネットワークが使用されていない場合、変数の内容に
より、IBM Informix SE は、データベースが検索される可能性のあるファイ
ル・ディレクトリーを認識します。
DBPATH 変数が定義されていない場合、IBM Informix NET はデフォルトのア
クションを実行します。このマシンに IBM Informix OnLine がインストール
済みの場合には、それが使用されます。そうでない場合は、データベース
は IBM Informix SE によって管理され、カレント・ディレクトリーに配置さ
れます。
DBPATH が存在する場合、IBM Informix NET は変数の内容を調べて、データ
ベースが配置されている場所を検索します。次の 3 種類の項目を、DBPATH
にリストできます。
• ローカル・ディレクトリー
名前付きデータベースがここに表示される場合、そのデータベースにア
クセスするためにローカルの IBM Informix SE が使用されます。
•
UNIX システムにおいて、NFS または RFS によってマウントされたディ
レクトリーのパス
名前付きデータベースがここに表示される場合、コピーの IBM Informix
SE がファイル・システムを所有するマシン上で開始され、アクセスす
るために使用されます。
• ダブル・スラッシュで始まるリモート・サーバー名
IBM Informix NET は、そのネットワーク・サイトに問い合わせて、デー
タベース・サーバーの種類、指定された名前のデータベースをオープン
できるかどうかを調べます。
このようにして、ローカル・データベース用に作成されたアプリケーショ
ンを取得し、環境変数 DBPATH を変更することによって、異なるコン
ピューターに配置されたデータベースと連動させることができます。
12-12 ネットワークと分散
分散型データ
分散型データ
LAN またはその他のネットワークを使用することによって、アプリケー
ションをデータから分離させることができますが、アプリケーションは単
一データベースの内容に制限されたままです。ほとんどのデータベース・
サーバーでは、現行のデータベース内の表を問い合わせるか、または修正
することしかできません。
IBM Informix OnLine データベース・サーバーによって、それが制御する任
意のデータベース内でデータを問い合わせることができます。つまり、現
行のデータベース以外のデータベースで表の問合せと修正ができます。た
だし、これらの他のデータベースが同じ IBM Informix OnLine データベー
ス・サーバーによって管理されている ( また、IBM Informix STAR も OnLine
データベース・サーバーと同じマシンに常駐している ) 場合に限ります。
IBM Informix STAR 製品が IBM Informix OnLine に追加されると、ネットワー
ク内の任意の IBM Informix OnLine データベース・サーバーの管理下にある
データベースで、表の問合せと修正ができるようになります。
IBM Informix TP/XA 機能が IBM Informix OnLine に (IBM Informix ESQL/C と共
に ) 追加されると、異なるベンダーから複数のコンピューター・システム
および複数の XA 準拠のデータベース・システムにも広がる広域トランザ
クションを作成できます。
外部表の命名
DATABASE 文または CREATE DATABASE 文によってオープンされるデータ
ベースは、現行 データベースです。その他のデータベースは、外部 データ
ベースです。外部データベース内の表を参照するには、そのデータベース
名を表名の一部に含めます。
SELECT name, number FROM salesdb:contacts
外部データベースは、salesdb です。その中の表は、contacts と呼ばれてい
ます。結合内で同じ表記を使用できます。複数の外部表がある場合は、長
い表名は短縮された別名を使用しない限り、扱いにくくなることがありま
す。
SELECT C.custname, S.phone
FROM salesdb:contacts C, stores:customer S
WHERE C.custname = S.company
ネットワークと分散 12-13
分散型データ
データベース名を、サーバー名、つまり別の IBM Informix OnLine データ
ベース・サーバーが実行されているネットワーク・マシン名で修飾できま
す。これは、異なるデータベース・サーバーによって管理される外部デー
タベースを指定する方法です。
SELECT O.order_num, C.fname, C.lname
FROM masterdb@central:customer C, sales@boston:orders O
WHERE C.customer_num = O.Customer_num
INTO TEMP mycopy
この例では、2 つの外部表が結合されています。結合行は、現行のデータ
ベース内の一時表に格納されています。外部表は、異なる 2 つのデータ
ベース・サーバー内に配置されます。1 つは central、もう 1 つは boston と
呼ばれます。
通常は、表名またはデータベース名を重複指定 することが許可されていま
す。つまり、現行のデータベースが masterdb で、現行のデータベース・
サーバーが central である場合でも、問い合わせるときに、
masterdb@central:customer という名前の表を参照することが許可されてい
ます。
外部表を使用したシノニムの使用
シノニム は、別の名前の代わりに使用できる名前です。シノニムの主な使
用目的は、外部表の参照をより便利にすることです。また、シノニムを使
用して外部表の格納場所を隠蔽することもできます。
上述の例を、外部表がシノニムを使用するように修正した例を示します。
CREATE SYNONYM mcust FOR masterdb@central:customer;
CREATE SYNONYM bords FOR sales@boston:orders;
SELECT bords.order_num, mcust.fname, mcust.lname
FROM mcust, bords
WHERE mcust.customer_num = bords.Customer_num
INTO TEMP mycopy
CREATE SYNONYM 文は、現行データベース内のシステム・カタログ表
syssyntable に、シノニム名を格納します。シノニムは、そのデータベース
内部で作成されたすべての問合せに使用できます。
シノニムが短いほど、問合せの書き込みは簡単になりますが、シノニムは
他のロールを実行することができます。これらは、問合せを変更せずに、
表を異なるデータベースへ、または異なるコンピューターへも移動させる
ことができます。
12-14 ネットワークと分散
分散型データ
表名 customer と orders を参照する多くの問合せがあると仮定します。それ
らの問合せは、プログラム、フォーム、およびレポートに埋め込まれてい
ます。表は、データベース・サーバー avignon 上に保管されているデータ
ベース stores5 に含まれています。
これで、同じプログラム、フォーム、およびレポートを、ネットワーク上
の異なるコンピューターのユーザーが使用できようになると判断されます
( データベース・サーバー nantes)。これらのユーザーは、注文データが含
まれる orders という名前の表を含むデータベースを持っていますが、avignon にある customer 表へのアクセス権が必要です ( そうでなければ、表を
重複して持つ必要があり、管理上の問題が発生します )。
これらのユーザーにとって、customer 表は外部のものです。これは、プロ
グラムとレポートの特別なバージョン、つまり、customer 表がデータベー
ス・サーバー名で修飾されているバージョンを準備する必要があることを
意味するのでしょうか ? これよりも良いソリューションは、次のようにし
て、ユーザーのデータベースにシノニムを作成することです。
DATABASE stores5@nantes;
CREATE SYNONYM customer FOR stores5@avignon:customer
格納された問合せがユーザーのデータベースで実行されると、customer と
いう名前により、実際の表が参照されます。他のデータベースで実行され
ると、その名前はシノニムを介して外部表への参照に変換されます。
シノニム連鎖
上述の例で、新規コンピューターがネットワークに追加されたと想定しま
す。このコンピューター名は、db_crunch です。customer 表とその他の表
はそのコンピューターに移動され、avignon 上の負荷が削減されます。新規
データベース・サーバーで簡単に表を再現できますが、どのようにすれば
全アクセス先をその表に変更できるでしょうか ? このことを行う 方法の 1
つは、シノニムをインストールして以前の表を置き換えることです。
DATABASE stores5@avignon EXCLUSIVE;
RENAME TABLE customer TO old_cust;
CREATE SYNONYM customer FOR stores5@db_crunch:customer;
CLOSE DATABASE
stores5@avignon 内で問合せを実行すると、customer 表への参照によってシ
ノニムを検索し、新規コンピューター上のバージョンを参照するように変
更されます。これは、データベース・サーバー nantes から実行される問合
せの場合にも当てはまります。データベース stores5@nantes 内のシノニム
ネットワークと分散 12-15
分散型データ
は、引き続き customer への参照先をデータベース stores5@avignon に変更
しますが、そこにある新規のシノニムは、問合せをデータベース
stores5@db_crunch に送信します。
シノニムの連鎖は、この例のように、1 つの操作で全アクセス先を表に変
更する場合に有効です。ただし、それらのシノニムが直接表を指すように、
即時にすべてのユーザーのデータベースを更新しなければなりません。さ
らに多くのシノニムを処理するには多くのオーバーヘッドがかかり、連鎖
内のコンピューターがダウンしている場合は、表を検索することができま
せん。
外部表の修正
次の例は、外部表の修正方法を示しています。
DATABASE stores5@nantes;
BEGIN WORK;
UPDATE stores5@avignon:customer
SET phone = "767-8592"
WHERE customer_num = 149;
COMMIT WORK
同じトランザクションで複数の表を修正することができます。ただし、同
じ IBM Informix OnLine データベース・サーバー (OnLine を IBM Informix
STAR または IBM Informix TP/XA と共に使用していない場合 ) は、単一トラ
ンザクションですべての表を管理する必要があります。上述の例では、
データベース・サーバー avignon にある外部表が更新されます。また、同
じトランザクションで avignon にある他の表も修正することができます。
ただし、現行データベースにある表は、現行データベースが nantes によっ
て管理されているために修正することができません。
12-16 ネットワークと分散
サマリー
サマリー
最も簡単なネットワーク、LAN では、複数のワークステーションがディス
クを共用できます。それぞれのワークステーションは、そのアプリケー
ション・プログラムとデータベース・サーバーの独自のコピーを持ってい
ますが、使用する表は 1 つまたは複数のコンピューターに接続されたディ
スク上に配置できます。複数のワークステーションがデータを共用します
が、すべての出入力がネットワーク上を経由するために、パフォーマンス
上の問題を引き起こす可能性もあります。
IBM Informix NET ( および IBM Informix STAR) 製品によってサポートされて
いるネットワークでは、一般にアプリケーションをデータベース・サー
バーから分離します。アプリケーションが 1 つのマシンで実行される一方、
データベース・サーバーはデータが物理的に接続されているコンピュー
ターで作動します。ネットワーク・ソフトウェア、オペレーティング・シ
ステム、およびデータベース・サーバーには、数多くの可能な組合せがあ
り、それぞれの組合せの詳細について把握しておく必要があります。
一般的なネットワーキングでは、アプリケーションがデータベースをオー
プンするときに重大な処理が実行されます。その時点で、ネットワーク・
ソフトウェアは、コマンドまたは環境変数内の情報に基づいてデータベー
スを配置し、そのデータベースを管理するデータベース・サーバーへの通
信をセットアップします。
IBM Informix STAR 機能がインストールされた IBM Informix OnLine を使用す
る場合、複数の IBM Informix OnLine データベース・サーバーの管理下にあ
る複数のデータベースから、表の問合せや修正を行うことができます。ま
た、シノニムを使用して、これらの表の格納場所を隠蔽することも可能で
す。
ネットワークと分散 12-17
サマリー
12-18 ネットワークと分散
付録
特記事項
本書に記載の製品、サービス、または機能が日本においては提
供されていない場合があります。日本で利用可能な製品、サー
ビス、および機能については、日本 IBM の営業担当員にお尋
ねください。本書で IBM 製品、プログラム、またはサービス
に言及していても、その IBM 製品、プログラム、またはサー
ビスのみが使用可能であることを意味するものではありませ
ん。これらに代えて、IBM の知的所有権を侵害することのな
い、機能的に同等の製品、プログラム、またはサービスを使用
することができます。ただし、IBM 以外の製品とプログラムの
操作またはサービスの評価および検証は、お客様の責任で行っ
ていただきます。
IBM は、本書に記載されている内容に関して特許権 ( 特許出願
中のものを含む ) を保有している場合があります。本書の提供
は、お客様にこれらの特許権について実施権を許諾することを
意味するものではありません。実施権についてのお問い合わせ
は、書面にて下記宛先にお送りください。
〒 106-0032
東京都港区六本木 3-2-31
IBM World Trade Asia Corporation
Licensing
A
以下の保証は、国または地域の法律に沿わない場合は、適用されません。
IBM およびその直接または間接の子会社は、本書を特定物として現存するままの状
態で提供し、商品性の保証、特定目的適合性の保証および法律上の瑕疵担保責任を
含むすべての明示もしくは黙示の保証責任を負わないものとします。国または地
域によっては、法律の強行規定により、保証責任の制限が禁じられる場合、
強行規定の制限を受けるものとします。
本書は定期的に見直され、必要な変更 ( たとえば、技術的に不適切な記述
や誤植など ) は、本書の次版に組み込まれます。IBM は予告なしに、随時、
この文書に記載されている製品またはプログラムに対して、改良または変
更を行うことがあります。
本書において IBM 以外の Web サイトに言及している場合がありますが、便
宜のため記載しただけであり、決してそれらの Web サイトを推奨するもの
ではありません。それらの Web サイトにある資料は、この IBM 製品の資料
の一部ではありません。それらの Web サイトは、お客様の責任でご使用く
ださい。
IBM は、お客様が提供するいかなる情報も、お客様に対してなんら義務も
負うことのない、自ら適切と信ずる方法で、使用もしくは配布することが
できるものとします。
本プログラムのライセンス保持者で、(i) 独自に作成したプログラムとその
他のプログラム(本プログラムを含む)との間での情報交換、および (ii) 交
換された情報の相互利用を可能にすることを目的として、本プログラムに
関する情報を必要とする方は、下記に連絡してください。
IBM Corporation
J46A/G4
555 Bailey Avenue
San Jose, CA 95141-1003
U.S.A.
本プログラムに関する上記の情報は、適切な使用条件の下で使用すること
ができますが、有償の場合もあります。
本書で説明されているライセンス・プログラムまたはその他のライセンス
資料は、IBM 所定のプログラム契約の契約条項、IBM プログラムのご使用
条件、またはそれと同等の条項に基づいて、IBM より提供されます。
A-2
IBM Informix チュートリアル・ガイド
この文書に含まれるいかなるパフォーマンス・データも、管理環境下で決
定されたものです。そのため、他の操作環境で得られた結果は、異なる可
能性があります。一部の測定が、開発レベルのシステムで行われた可能性
がありますが、その測定値が、一般に利用可能なシステムのものと同じで
ある保証はありません。さらに、一部の測定値が、推定値である可能性が
あります。実際の結果は、異なる可能性があります。お客様は、お客様の
特定の環境に適したデータを確かめる必要があります。
IBM 以外の製品に関する情報は、その製品の供給者、出版物、もしくはそ
の他の公に利用可能なソースから入手したものです。IBM は、それらの製
品のテストは行っておりません。したがって、他社製品に関する実行性、
互換性、またはその他の要求については確証できません。IBM 以外の製品
の性能に関する質問は、それらの製品の供給者にお願いします。
IBM の将来の方向または意向に関する記述については、予告なしに変更ま
たは撤回される場合があり、単に目標を示しているものです。
表示されている IBM の価格は IBM が小売価格として提示しているもので、
現行価格であり、通知なしに変更されるものです。卸価格は、異なる場合
があります。
この情報には、日常の業務処理で用いられるデータや報告書の例が含まれ
ています。より具体性を与えるために、それらの例には、個人、企業、ブ
ランド、あるいは製品などの名前が含まれている場合があります。これら
の名称はすべて架空のものであり、名称や住所が類似する企業が実在して
いるとしても、それは偶然にすぎません。
著作権使用許諾 :
本書には、様々なオペレーティング・プラットフォームでのプログラミン
グ手法を例示するサンプル・アプリケーション・プログラムがソース言語
で掲載されています。お客様は、サンプル・プログラムが書かれているオ
ペレーティング・プラットフォームのアプリケーション・プログラミン
グ・インターフェースに準拠したアプリケーション・プログラムの開発、
使用、販売、配布を目的として、いかなる形式においても、IBM に対価を
支払うことなくこれを複製し、改変し、配布することができます。このサ
ンプル・プログラムは、あらゆる条件下における完全なテストを経ていま
せん。従って IBM は、これらのサンプル・プログラムについて信頼性、利
便性もしくは機能性があることをほのめかしたり、保証することはできま
せん。お客様は、IBM のアプリケーション・プログラミング・インター
フェースに準拠したアプリケーション・プログラムの開発、使用、販売、
配布を目的として、いかなる形式においても、IBM に対価を支払うことな
くこれを複製し、改変し、配布することができます。
特記事項 A-3
商標
それぞれの複製物、サンプル・プログラムのいかなる部分、またはすべて
の派生した創作物には、次のように、著作権表示を入れていただく必要が
あります。
©( お客様の会社名 ) ( 西暦年 ). このコードの一部は、IBM Corp. の
サンプル・プログラムから取られています。
© Copyright IBM Corp. - 年を入れる -. All rights reserved.
この情報をソフトコピーでご覧になっている場合は、写真やカラーの図表
は表示されない場合があります。
商標
AIX; DB2; DB2 Universal Database; Distributed Relational Database
Architecture; NUMA-Q; OS/2, OS/390, and OS/400; IBM Informix®; C-ISAM®;
Foundation.2000TM; IBM Informix® 4GL; IBM Informix® DataBlade® Module;
Client SDKTM; CloudscapeTM; CloudsyncTM; IBM Informix® Connect;
IBM Informix® Driver for JDBC; Dynamic ConnectTM; IBM Informix® Dynamic
Scalable ArchitectureTM (DSA); IBM Informix® Dynamic ServerTM; IBM Informix®
Enterprise Gateway Manager (Enterprise Gateway Manager); IBM Informix®
Extended Parallel ServerTM; i.Financial ServicesTM; J/FoundationTM; MaxConnectTM;
Object TranslatorTM; Red Brick Decision ServerTM; IBM Informix® SE;
IBM Informix® SQL; InformiXMLTM; RedBack®; SystemBuilderTM; U2TM;
UniData®; UniVerse®; wintegrate® は、IBM Corporation の商標です。
Java およびすべての Java 関連の商標およびロゴは、Sun Microsystems, Inc.
の米国およびその他の国における商標または登録商標です。
Windows、Windows NT および Excel は、Microsoft Corporation の米国および
その他の国における商標です。
UNIX は、The Open Group がライセンスしている米国およびその他の国にお
ける登録商標です。
本書で言及しているその他の会社名、製品名およびサービス名はそれぞれ
各社の商標または登録商標です。
A-4
IBM Informix チュートリアル・ガイド
索引
索引
あ
アーカイブ
説明 5-24
トランザクション・ログ 5-24
IBM Informix OnLine の方法 5-25
説明 1-12
アイコン、説明 13
アクセス権
インデックス 11-11
概要 1-9
許可の自動化 11-14
更新 11-9, 11-11, 11-31
削除 11-9, 11-31
システム・カタログ内で符号化された 11-10
接続 11-6
選択 11-9, 11-11, 11-31
挿入 11-9, 11-31
必要
ビューの作成 11-31
必要性
データの変更 5-15
ビュー 11-30, 11-33
ビュー上 11-31
表示 5-16
付与 11-6, 11-16
変更 11-11
列レベル 11-11
DBA 11-8
Resource 4-34, 11-7
アクセス制御。アクセス権を参照
アクセスの制約、ファイル・システムの使用 11-4
アクティブ・セット
カーソル 6-24
定義 2-27
アスタリスク (*)
SELECT での使用方法 2-12
Bookname
February 6, 2003 3:24 pm
アプリケーション
エラーの処理 6-16
注文入力の設計 5-21
ネットワーク 12-8
共通機能 1-19
スクリーン・フォーム 1-18
説明 1-18
パフォーマンス解析 4-5
ユーザー作成 1-19
レポート生成プログラム 1-18
一時表
カーソルのアクティブ・セット 6-24
共有ディスク領域 10-7
問い合わせを速めるために使用 4-39
列名の割り当て 3-12
一次表
例 5-11
意味整合性 5-18, 9-3
インデックス
管理 10-21
クラスター化された 10-27
削除 10-26
使用するディスク領域 10-17, 10-22
消費時間 10-22
重複するエントリー 10-17, 10-25
パフォーマンスへの追加 10-23
オプティマイザー 4-36
オプティマイザーが使用 4-12, 4-15
オプティマイザーが使用しない場
合 4-35, 4-37, 4-38
更新効果 4-36
使用されるディスク領域 4-34
テストまたは修復するためのユー
ティリティー 4-36
パフォーマンス効果 4-26
パフォーマンス用に追加 4-34
複合 4-36
物理的順序と 4-13
GROUP BY 内 4-16
ORDER BY 内 4-16
埋め込み SQL
定義済み 6-4
利用できる言語 6-4
エクステント
サイズ 10-9
上限 10-11
説明 10-9
エラー
カーソルのオープン時に検出 6-20
カーソルを使用した挿入 7-11
更新中 5-21
2
索引
Bookname
February 6, 2003 3:24 pm
コード 6-11
削除後の 7-4
処理 6-16
ISAM エラー・コード 6-12
エラー・メッセージ用メッセージ・ファ
イル 18
エンティティー
表による表現 8-9
保全性 5-18
命名 8-8
オプティマイザー
インデックスが使用されない場
合 4-38
最適化レベルの高位か低位かの指
定 4-14
システム・カタログ使用 4-9, 4-15
自動作成されたインデックス・パ
ス 4-36
使用されないインデックス 4-35, 4-37
使用されるインデックス 4-15
説明 4-8
ソート 4-18
ソート・マージ結合 4-13
ディスク・アクセス 4-21
と GROUP BY 4-13, 4-16, 4-18
と ORDER BY 4-13, 4-16, 4-18
と SET OPTIMIZATION 文 4-14
問い合わせ予定 4-8
問い合わせ予定の表示 4-19
フィルター選択の水準 4-17
複合インデックス使用 4-36
メソッド 4-14
か
カーソル
アクティブ・セット 6-24
オープン 6-20, 6-24
クローズ 7-35
更新用 7-16, 7-25
順次 6-23, 6-25
使用
PREPARE 文で処理された文 6-32
スクロール 6-23
宣言 6-20
挿入用 7-9
保持 7-35
FETCH 文を使用した値の抽出 6-21
WITH HOLD 7-35, 10-37
カーソルのオープン 6-20, 6-24
カーソルの選択
使用 6-20
外部キー 5-19
外部結合
入れ子 3-25
説明 3-19
外部データベース 12-13
外部表、シノニムの使用 12-14
拡張された関係分析
概要 8-3
基本的な考え方 8-6
定義された手順 8-8
定義済み手順 8-24, 9-20, 9-23
表を表す図のフォーマット 8-11
可変長文字 (VARCHAR) 型
説明 9-17
パフォーマンスのための使用 10-29
表サイズに対する効果 10-16
LENGTH 関数 2-56
環境変数 11
関係演算子
等号 2-28
不等号 2-29
BETWEEN 2-30
EXISTS 3-29
IN 3-29
LIKE 2-34
NOT 2-30
NULL 2-33
OR 2-31
WHERE 節 2-27, 2-40
関係モデル
エンティティー 8-8
逆正規化 10-29
結合 2-9
射影 2-7
説明 8-6, 8-24
選択 2-5
属性 8-22
多対多の関係 8-16
標準フォーム 8-22
1 対 1 の関係 8-15
1 対多の関係 8-15
説明 1-12
操作 1-14
関数
集計 2-47
日付指向 2-49
SELECT 文 2-47
キーロック 7-24
規則
構文 11
文字の 11
疑問符 (?)
PREPARE での位置指定子とし
て 6-29
規約
例コード 16
逆正規化 10-29
行
関係モデル 1-13
関係モデル内 8-6
固定長のサイズ 10-14
削除 5-4
挿入 5-7
定義 8-6
ディスクからの読み取りのコス
ト 4-24
行 ID 3-15, 3-19
行 ID 関数 4-26
業界標準、準拠 21
競合
削減 10-35, 10-38
障害となっている表の 10-38
ディスク・アクセス・アームのため
の 10-7
行ロック 7-24
切り捨て、SQLAWARN でシグナルされ
た 6-12
金額 (MONEY) 型 9-12
説明 9-11
表示フォーマット 9-12
クラスター・インデックス
説明 10-27
結合
外部結合 3-19
結合性 2-67
最適化における大きな結合の効
果 4-14
作成 2-62
自己結合 3-11
自然 2-65
修正可能ビューでの制約事項 11-27
ソート・マージ 4-13
定義 2-9
等価結合 2-62
複数表結合 2-68
索引 3
Bookname
February 6, 2003 3:24 pm
結合列 外部キーを参照
現行データベース
説明 12-13
更新日誌 10-36
構造化照会言語 SQL を参照
構文図
エレメント 15
規則 11
候補キー
説明 8-7
属性の依存先 8-22
固定小数点 9-11
コマンド・スクリプト、データベースの
作成 9-30
さ
最適化
技法 4-3
サイト名
表名内 12-14
DATABASE 文の使用 12-11
サブスクリプト付け 2-39
サブ文字列 2-25
算術演算子、式 2-41
参照整合性 5-19, 8-8
参照制約
定義 5-20
シーク時間 4-24, 4-25
時間隔 (INTERVAL) 型
関係式 2-27
精度およびサイズ 9-15
説明 9-14
表示フォーマット 9-16
式
説明 2-41
日付指向 2-49
表示ラベル 2-44
自己結合
説明 3-11
INTO TEMP による列名の割り当
て 3-12
システム・カタログ
アクセス権 5-16, 11-10
問い合わせ 5-16
syscolauth 11-10
systabauth 5-16, 11-10
sysusers 11-10
オプティマイザーが使用 4-9
4
索引
Bookname
February 6, 2003 3:24 pm
表内の行数 4-9
systables 4-9
自然結合 2-65
実数 (FLOAT) データ型
説明 9-9
自動型変換 データ型変換を参照
シノニム 12-14, 12-16
連鎖 12-15
射影 2-7
集計関数
シグナルされた NULL 値 6-12
修正可能ビューでの制約事項 11-27
説明 2-47
副問い合わせ内 3-32
ESQL 内 6-13
GROUP BY 節 3-5
集合の差 3-47
集合の積 3-45
主キー制約
制限 8-7
属性の依存先 8-22
定義 5-20, 8-7
複合 8-10
順カーソル
定義 6-23
準拠
業界標準 21
順次アクセス。ディスク・アクセス、順
次を参照
小桁実数 (SMALLFLOAT) 型
説明 9-9
小数桁数 (SMALLINT) 型
説明 9-7
冗長データ
パフォーマンスのための導入 10-34
所有権 11-8
シリアル (SERIAL) 型
説明 9-7
シンボル・テーブル 10-30
スキーマ。データ・モデルを参照
スクロール・カーソル
アクティブ・セット 6-25
定義 6-23
ストアード・プロシージャー
セキュリティー目的 11-3
正規表現、パフォーマンスにおける効
果 4-37
整合性がある削除 7-6
整数 (INTEGER) 型
説明 9-7
静的 SQL 6-5
制約
オプティマイザーが使用 4-15
ドメインの定義 9-3
セキュリティー
オペレーティング・システム機能の
使用 11-4
行へのアクセスの制約 11-23, 11-25
ストアード・プロシージャー使
用 11-3
挿入値の制御 11-23, 11-29
データベースのアクセス不能化 11-5
データベース・レベル・アクセス
権 11-5
ビューへのアクセスの制約 11-31
表レベル・アクセス権 11-11
ホスト・ファイル・システムの使
用 11-4
列へのアクセスの制約 11-23, 11-24
選択リスト
アスタリスク 2-12
関数 2-47, 2-58
サブ文字列の指定 2-25
式 2-41
すべての列の選択 2-12
特定の列の選択 2-19
表示ラベル 2-44
ラベル 3-41
リテラル 3-43
列の順序 2-13
相関副問い合わせ
定義 3-29
例 3-33
ソート
一時表を使用した回避 4-39
オプティマイザーによるコストの見
積もり 4-18
時間コスト 4-22
ソート・マージ結合 4-13
多重 2-15
パフォーマンスにおける効果 4-33
非順次アクセスの回避 4-40
ORDER BY 2-14
ソート・マージ結合 4-13
属性 8-22
た
単一 SELECT 2-27
チェック制約
定義 5-19
チャンク
説明 10-4
ミラーリングされた 10-5
重複インデックス・キー 10-25
定数データ行の挿入 7-12
ディスク競合
複数のアームによる削減 10-7
効果 4-24
ディスクのミラーリング 10-5
ディスク・アクセス
競合の削減 10-7
チャンク 10-4
DB 領域 10-5
行 ID の使用 4-26
行の読み取りのコスト 4-24
シーク時間 4-24, 4-25
順次 4-25, 4-34
ソートによる非順次の回避 4-40
問い合わせにより強制された順
次 4-35, 4-37, 4-38
パフォーマンス 4-25, 4-27, 4-34
非順次 4-26
待ち時間 4-24, 4-25
ディスク・エクステント 10-9
ディスク・バッファー。ページ・バッ
ファーを参照
ディスク・ページ
サイズ 10-4, 4-23
バッファー 4-23, 4-26
データ型
可変長文字 (VARCHAR) 型 9-17
金額 (MONEY) 型 9-11
固定小数点 9-11
時間隔 (INTERVAL) 型 9-14
自動変換 6-14
小桁実数 (REAL) 型
データ型
小桁 実 数
(SMALLFLOAT)
型 9-9
整数 (INTEGER) 型 9-7
選択 9-20
テキスト (TEXT) 型 9-18
索引 5
Bookname
February 6, 2003 3:24 pm
日時 (DATETIME) 型 9-13
日時順 9-12
バイト (BYTE) 型 9-20
日付 (DATE) 型 9-12
浮動小数点 9-9
変換 5-8, 6-14
文字 (CHAR) 型 9-16
文字データ 9-16
SERIAL 9-7
10 進数 (DECIMAL) 型 9-10, 9-11
データ整合性 5-21, 5-23
データ定義文 6-35
データの終わり
カーソルのオープン時 6-20
SELECT のみのシグナル 7-15
SQLCODE 内のシグナル 6-11, 6-17
データベース
エンジンに一意な命名 9-24
外部 12-13
現行 12-13
新規表の構築 9-31
DB 領域との関係 10-5
stores5 6
アーカイブ 1-12
アプリケーション 1-17
管理 1-11
サーバー 1-17
主幹業務 1-12
定義 1-3
並行使用 1-9
データベース管理者 (DBA) 11-8
データベース・サーバー、定義 1-17
データベース・レベルのアクセス権
説明 5-15
データベース・レベルのアクセス権。ア
クセス権も参照
データベース・ロック 7-22
データ・モデル
エンティティー 8-8
関係の定義 8-14
逆正規化 10-29, 10-35
住所録モデル 8-5, 8-11
説明 8-3
属性 8-22
多対多の関係 8-16, 8-20
ドメイン 9-23
1 対 1 の関係 8-15, 8-20
1 対多の関係 8-15, 8-19
説明 1-3
6
索引
Bookname
February 6, 2003 3:24 pm
データ・モデル。関係モデルを参照
デカルト積
結合の基礎 2-62
説明 2-60
テキスト (TEXT) 型
格納場所の選択 10-20
関係式による制限 2-27
制限
LIKE または MATCHES 2-34
説明 9-18
ディスク装置 10-5
ディスク領域の見積もり 10-19
パフォーマンスのための使用 10-30
LENGTH 関数 2-56
デッドロック検出 7-32
デフォルト値
説明 5-18
デモンストレーション・データベース
インストール・スクリプト 6
概要 6
コピー 7
問い合わせ
時間コスト 4-21
データ・モデルの用語 1-7
パフォーマンス 4-3, 4-45
パフォーマンスの向上 4-30, 4-44
問い合わせオプティマイザー。オプティ
マイザーを参照
問い合わせ予定
インデックス 4-12
オプティマイザーによる選択 4-17
自動作成されたインデックス・パ
ス 4-36
説明 4-8
パフォーマンス解析に使用 4-32
SET EXPLAIN で表示 4-19
等価結合 2-62
等号 (=) 関係演算子 2-28, 2-62
導出データ
パフォーマンスのための導入 10-33
ビューによる作成 11-23
動的 SQL
カーソル使用 6-32
説明 6-5, 6-29
PREPARE 文で処理された文の解
放 6-34
ドキュメント・ノート 21
トランザクション
最後まで保持されているロック 7-26
終了時に解放されたロック 7-25, 7-35
終了時にクローズされたカーソ
ル 7-35
説明 5-21
トランザクション・ログ 5-22, 5-25
必要なトランザクション・ログ 9-25
DELETE を使用した例 7-5
SQLAWARN でシグナルされた使
用 6-12
トランザクション・ログ機能
オフにできない 9-27
迅速にロードを行うためにオフにす
る 9-31
バッファー付き 9-26
CREATE DATABASE による設
定 9-24
IBM Informix OnLine の方法 9-25
な
日時 (DATETIME) 型
関係式 2-27
関数 2-49
順序
ORDER BY シーケンス 2-14
精度およびサイズ 9-14
説明 9-13
表示フォーマット 2-54, 9-16
日誌の更新 10-36
ネットワーキング
構成 12-3
説明 12-3
データへの接続 12-8
ファイル・サーバー 12-4
分散型データ 12-13
LAN ( ローカル・エリア・ネット
ワーク ) 12-4
ネットワーク
シンプル・モデル 4-28
送信されるデータ 4-28
パフォーマンス 4-28
ネットワーク・ファイル・システム
(NFS) 12-10
は
排他レベル
カーソル安定性 7-28
確定読み込み 7-27
繰り返し可能読み込み 7-29
設定 7-26
単純読み込み 7-27
排他ロック 7-22
バイト (BYTE) 型
格納場所の選択 10-20
関係式による制限 2-27
説明 9-20
ディスク装置 10-5
ディスク領域の見積もり 10-19
LIKE または MATCHES による制
限 2-34
バイナリー・ラージ・オブジェクト
(BLOB)
格納場所の選択 10-20
ディスク装置 10-5, 10-6
ディスク領域の見積もり 10-19
バックアップ。アーカイブを参照
バッファー付きログ機能 9-26
パフォーマンス
インデックス修正の時間 10-22
インデックスの効果 10-23, 10-24
クラスター・インデックス 10-27
修正の速度を上げるためのインデッ
クスの削除 10-26
修正を遅らせる重複キー 10-25
障害となっている表 10-38
冗長データの使用 10-34
専用ディスクへの表の割り当て 10-7
ディスク・アームの動作 10-9
導出データの使用 10-33
トール表の分割 10-32
日誌の更新 10-36
バッファー付きログ 9-26
表ごとに複数のアクセス・アー
ム 10-7
フラグメント化 10-12
並行性に依存 7-19
ロックの影響 7-19
ワイド表の分割 10-31
BLOB 格納場所の効果 10-20
DB 領域のフラグメント化をなく
す 10-12
LAN 12-5
4-7
パフォーマンス
一時表を使用した向上 4-39
インデックス損傷の効果 4-36
インデックスの影響 4-26
インデックスの効果 4-12
インデックスの追加 4-34
オプティマイザーの効果 4-8
索引 7
Bookname
February 6, 2003 3:24 pm
行 ID によるディスク・アクセ
ス 4-26
行アクセス 4-24
向上 4-30
更新の効果 4-36
最適化 4-3, 4-45
最適化レベルの指定による向上 4-14
シーク時間 4-24
順次アクセス 4-25, 4-34
正規表現の効果 4-37
相関副問い合わせの効果 4-37
ソートによる非順次アクセスの置き
換え 4-40
測定 4-6
他のブックの参照 4-3
ディスク待ち時間 4-24
ディスク・アクセス 4-21, 4-25, 4-34
問い合わせの時間コスト 4-21
ネットワーク・アクセス 4-28
非順次アクセス 4-26
表サイズの効果 4-27, 4-34
フィルター式の効果 4-10, 4-37, 4-38
フィルター選択の水準 4-17
“ ホット・スポット ” 検索 4-7
4-7
パフォーマンス解析
最適化手法 4-4
測定 4-6
タイミング
監視から 4-6
コマンド・スクリプトから 4-6
4GL プログラムから 4-7
テスト環境のセットアップ 4-31
問い合わせ予定の使用 4-32
非順次アクセス 4-40, 4-44
メソッド 4-30, 4-32
問題の検査 4-5
“80-20 の法則 ” 4-7
比較条件
説明 2-27
非順次アクセス。ディスク・アクセス、
非順次を参照
日付 (DATE) 型
関数 2-49
説明 9-12
表示フォーマット 9-13
ビュー
アクセス権 11-30, 11-33
アクセス時のアクセス権 11-31
仮想列 11-28
基本が削除されるとき削除 11-26
8
索引
Bookname
February 6, 2003 3:24 pm
基本変更の効果 11-26
行の削除 11-28
行の挿入 11-29
修正 11-27, 11-30
使用上の制約事項 11-25
説明 11-23
重複行の更新 11-29
重複行の作成 11-25
表示されない列に挿入された
NULL 11-29
CHECK OPTION の使用 11-29
表
エクステント・サイズ 10-9
エンティティーの表現 8-9
可変長の行 10-16
関係の記録 8-19
関係モデル 1-13
関係モデル内 8-6
固定長の行 10-14
作成
表 9-28
主キー 8-7
障害 10-38
所有権 11-8
図のフォーマット 8-11
専用デバイス 10-7
単一の DB 領域に含まれているも
の 10-5
複数のアクセス・アーム 10-7
フラグメント化 10-12
フラグメント化をなくす 10-12
ミラーリングされた記憶域 10-6
ロック 7-23
DB 領域との関係 10-6
表サイズ
可変長の行を持つ 10-16
計算 10-14, 10-21
固定長の行を持つ 10-14
アクセスのコスト 4-27, 4-34
表示
パフォーマンスにおける効果 4-33
標識変数
定義 6-15
表示ラベル
ORDER BY 節 2-46
表の構築 9-31
表名
サイト名による修飾 12-14
シノニムの使用 12-14
表名の別名 2-70
表領域
説明 10-8
BLOB データ用に使用される 10-20
表レベル・アクセス権
定義および使用 11-9
列固有アクセス権 11-11
ファイル
データベースとの比較 1-3
サーバー 12-4
UNIX での権限 11-4
フィルター式
インデックスから評価 4-16, 4-36
オプティマイザーが使用 4-10, 4-15
選択の水準見積もり 4-17
パフォーマンスにおける効果 4-10,
4-37, 4-38
ブール式
論理演算子 2-33
複合インデックス
使用 4-36
複合キー 8-10
複合問い合わせ 3-37
副問い合わせ
相関 3-29, 3-33
相関の 4-37
パフォーマンス 4-37
DELETE 文内 5-6
SELECT 内 3-29, 3-37
UPDATE による制限 5-13
UPDATE-SET 内 5-13
UPDATE-WHERE 内 5-12
増進可能なロック 7-22, 7-25
不等号関係演算子 2-29
浮動小数点 9-9
部品展開 6-26
フラグメント化 10-12
分散型データ 12-13, 12-16
分散デッドロック 7-32
並行性
最大化 10-35, 10-38
説明 5-26, 7-18
データベース・ロック 7-22
デッドロック 7-32
排他レベル 7-26
パフォーマンスに与える影響 7-19
表ロック 7-23
ロックの継続期間 7-25
ロックの種類 7-22
ロック範囲 7-22
SERIAL 値 9-7
「カーソル安定性」排他レベル 7-28
「確定読み込み」排他レベル 7-27
「繰り返し可能読み込み」排他レベ
ル 7-29
「単純読み込み」排他レベル 7-27
米国規格協会。ANSI を参照
ページ 10-4
ページ・バッファー
BLOB データに関する制限 10-20
説明 4-23
パフォーマンスにおける効果 4-24
非順次アクセスのコスト 4-26
ページ・ロック 7-24
別名
一時表での列名の割り当て 3-12
外部表との使用 12-13
自己結合 3-11
変更への割り込み 5-21
ボールド体タイプ 11
ホスト変数
型の変換 6-14
区切り記号 6-6
シグナルされた切り捨て 6-12
説明 6-6
データの取り出し先 6-21
動的割り当て 6-34
DELETE 文内の 7-4
EXECUTE を使用 6-32
INSERT 内の 7-8
INTO キーワード・セット 6-13
NULL 標識 6-15
PREPARE 文で処理された文の制約事
項 6-29
UPDATE 内の 7-15
WHERE 節 6-13
ま
マシン・ノート 21
待ち時間 4-24, 4-25
マニュアル、タイプ
ドキュメント・ノート 21
マシン・ノート 21
リリース・ノート 21
見積もり
インデックスのサイズ 10-17
エクステントの最大数 10-11
可変長の行を持つ表のサイズ 10-16
索引 9
Bookname
February 6, 2003 3:24 pm
固定長の行を持つ表のサイズ 10-14
BLOB ページ 10-19
ミラー。ディスクのミラーリングを参照
モード ANSI キーワード
ANSI 標準準拠のログ機能 9-26
文字 (CHAR) 型 9-16
可変長文字 (VARCHAR) 型への置
換 10-29
関係式 2-27
サブスクリプト付け 2-39
サブ文字列 2-25
シグナルされた切り捨て 6-12
文字 (CHAR) 型への置換 10-30
文字の表記 11
モデル。データ・モデルを参照
や
ユーティリティー・プログラム
dbload 9-31, 10-13
dbschema 9-30
tbcheck 10-8, 10-14
tbload 5-25, 10-13
tbstat 10-14
tbunload 5-25, 10-13
ら
ラベル 2-44, 3-41
リモート・ファイル共用 (RFS) 12-10
リリース・ノート 21
ルート DB 領域、定義 10-5
列
関係モデル 1-13
関係モデル内 8-6
定義 8-6
ラベル 3-41
列番号 2-23
列フィルター。フィルター式を参照
列レベル・アクセス権 11-11
レポート生成プログラム 1-18
ローカル・エリア・ネットワーク 12-4
ロック
および整合性 7-19
使用
UPDATE カーソル 7-25
説明 7-21
待機ロック・モード 7-30
デッドロック 7-32
10
索引
Bookname
February 6, 2003 3:24 pm
トランザクションの終了時に解放さ
れたロック 7-35
パフォーマンスに対する影響 7-19
非待機ロック・モード 7-31
並行性 5-26
ロックの継続期間 7-25
ロックのタイプ
キーロック 7-24
共有ロック 7-22
行ロック 7-24
データベース・ロック 7-22
排他ロック 7-22
表ロック 7-23
増進可能なロック 7-22, 7-25
ページ・ロック 7-24
ロックの範囲 7-22
ロック・モード 7-30
ロック・モードの設定 7-30
DELETE を使用した 7-4
論理演算子
AND 2-33
NOT 2-33
OR 2-33
わ
ワイルドカード比較
文字クラス 2-37
WHERE 節 2-34, 2-39
A
ALL キーワード
副問い合わせの開始 3-29
Alter アクセス権 11-11
ALTER INDEX 文
クラスター・インデックスの作
成 10-27
ロック表 7-23
ALTER TABLE 文
アクセス権 11-11
制約事項 11-25
列のデータ型の変更 9-20
LOCK MODE 節 7-24
NEXT SIZE 節 10-9
AND 論理演算子 2-33
ANSI 1-16
ANSI 準拠データベース
説明 1-17
ANSI 標準準拠データベース
制限付きのバッファー付きログ機
能 9-26
表アクセス権 11-9
SQLAWARN でシグナルされた 6-12
SQLAWARN 内の非標準構文 6-10
「繰り返し可能読み込み」排他レベル
の標準 7-30
ANSI 標準準拠のデータベース
不要な FOR UPDATE 7-17
ANSI ANSI 標準準拠
レベル 21
ANY キーワード
副問い合わせの開始 3-31
AVG 関数
集計関数 2-47
B
bcheck ユーティリティー 4-36
BEGIN WORK 文
トランザクションの開始の指定 5-23
BETWEEN 演算子 2-30
BLOB 領域 10-5, 10-20
BYTE データ型
GROUP BY による制限 3-6
C
CLOSE DATABASE 文
データベース・ロックに与える影
響 7-23
COBOL 6-6
Codd、E.F. 1-12
COMMIT WORK 文
カーソルのクローズ 7-35
セット SQLCODE 7-5
ロックの解放 7-25, 7-35
Connect アクセス権 11-6
COUNT 関数
集計関数 2-47
副問い合わせ内で使用 3-33
DISTINCT 2-48
GROUP BY 3-6
COUNT 機能
削除する行のカウント 5-5
副問い合わせでの使用 5-6
CREATE DATABASE 文
および DB 領域 10-6
共有ロック 7-22
コマンド・スクリプト 9-30
使用
IBM Informix NET 12-9
使用方法
IBM Informix OnLine 9-24
IBM Informix SE 9-26
SQLAWARN に後続 6-12
CREATE INDEX 文
ロック表 7-23
CREATE SYNONYM 文 12-14
CREATE TABLE 文
コマンド・スクリプト 9-30
初期シリアル値の設定 9-8
説明 9-28
BLOB 列の格納 10-20
EXTENT SIZE 節 10-9
IN 節 12-8
LOCK MODE 節 7-24
NEXT SIZE 節 10-9
CREATE VIEW 文
使用 11-24
制限事項 11-25
CURRENT 関数
列値の比較 2-49
4GL 例 4-7
D
DATABASE 文
使用
IBM Informix NET 12-9
排他モード 7-22
明示的なサイト名 12-11
明示的なパス名 12-10
ロック 7-22
SQLAWARN に後続 6-12
DATE 関数
式での使用方法 2-54
時刻関数 2-49
DATE データ型
ORDER BY シーケンス 2-14
DATETIME データ型
4GL 例 4-7
DAY 関数
時刻関数 2-50
使用
時刻関数 2-49
DB 領域
一時表のための 10-7
索引 11
Bookname
February 6, 2003 3:24 pm
エクステントへの分割 10-9
専用デバイス上の 10-7
定義 10-5
表領域との関係 10-8
複数のアクセス・アーム 10-7
ミラーリングされた 10-5
ルート 10-5
CREATE DATABASE による選
択 9-25
DBANSIWARN 環境変数 6-10
DBDATE 環境変数 5-8, 9-13
dbload ユーティリティー
表へのデータのロード 9-31, 10-13
DBMONEY 環境変数 9-12
DBPATH 環境変数 12-11, 12-12
dbschema ユーティリティー 9-30
DECIMAL データ型
SQLAWARN でシグナルされた 6-12
DECLARE 文
説明 6-20
FOR INSERT 節 7-9
FOR UPDATE 7-16
WITH HOLD 節 7-36
Delete アクセス権 11-9, 11-31
DELETE 文
アクセス権 11-6, 11-9
インデックスの更新にかかる時
間 10-22
埋め込み 6-6, 7-3, 7-8
およびデータの終わり 7-15
カーソルの使用 7-7
行数 7-4, 6-12
整合性がある削除 7-6
説明 5-4
トランザクション 7-5
ビューへの適用 11-28
表のすべての行 5-4
副問い合わせでの使用 5-6
PREPARE 文で処理 6-30
WHERE 節による制限 5-6
DESCRIBE 文
ステートメント・タイプの説明 6-34
DISTINCT キーワード
修正可能ビューでの制約事項 11-27
使用
COUNT 関数 2-48
SELECT 2-20
GROUP BY との関係 3-4
12
索引
Bookname
February 6, 2003 3:24 pm
DROP INDEX 文
インデックスの解放 4-34
ロック表 7-23
E
ESQL
エラー処理 6-16
カーソルからの行の取り出し 6-21
カーソル使用 6-19, 6-28
概要 6-3, 6-38, 7-3, 7-37
スクロール・カーソル 6-23
静的埋め込み 6-5
単一行の選択 6-13
動的埋め込み 6-5, 6-29
標識変数 6-15
プリプロセッサー 6-4
ホスト変数 6-6, 6-7
ホスト変数の範囲設定 6-6
DELETE 文 7-3
INSERT 7-8
SQL 通信領域 6-8
SQLCODE 6-11
SQLERRD フィールド 6-12
UPDATE 7-15
EXECUTE 文
説明 6-32
EXECUTE IMMEDIATE 文
説明 6-35
EXISTS キーワード
条件副問い合わせで使用 11-30
WHERE 節内 3-29
EXTEND 関数
DATE、DATETIME、
INTERVAL 2-49, 2-54
EXTENT SIZE キーワード 10-9
F
FETCH 文
順次 6-23
使用
順カーソル 6-25
説明 6-21
ABSOLUTE キーワード 6-23
FLUSH 文
挿入された行のカウント数 7-11
バッファーへの行の書き込み 7-10
FOR UPDATE キーワード
特定の列 7-17
ANSI 標準準拠のデータベースで不要
の 7-17
ORDER BY との競合 7-8
FREE 文
PREPARE 文で処理された文の解
放 6-34
FROM キーワード
別名 2-70
G
GRANT 文
埋め込み SQL 内 6-35, 6-38
自動化 11-14
データベース・レベル・アクセス
権 11-6
表レベル・アクセス権 11-8
4GL 内 11-15
GROUP BY キーワード
修正可能ビューでの制約事項 11-27
インデックス 4-16, 4-33
行ソート 4-18
使用される複合インデックス 4-36
説明 3-4
列番号 3-7
H
HAVING キーワード
説明 3-8
HOLD カーソル
定義 7-35
I
IBM Informix NET 4-28, 12-6, 12-9
IBM Informix OnLine
アーカイブ 5-25
オプティマイザー入力 4-15
外部表でのビューの有効化 11-27
他のデータベースの問い合わ
せ 12-13
ディスク記憶方法 10-4, 10-13
ディスク・アクセス 4-25
ディスク・ページ・サイズ 4-23
独自のディスク領域の制御 11-5
ネットワーク内 12-6
表がロックされている場合 7-23
SQLAWARN でシグナルされた 6-12
IBM Informix SE
データベースの作成 9-26
ネットワーク内 12-6
IBM Informix STAR 4-28, 12-13
IBM Informix 4GL
エラーで終了 7-14
エラーでの終了 6-37
使用されない標識変数 6-16
タイミング操作 4-7
動的 SQL の例 11-15
プログラム変数 6-5
NULL 値の検出 6-16
SQLCODE の使用 6-11
STATUS 変数 6-11
WHENEVER ERROR 文 6-37
IN 関係演算子 3-29
IN キーワード
使用
CREATE DATABASE におけ
る 10-6
CREATE TABLE における 10-6,
10-9
BLOB 列の格納 10-20
Index アクセス権 11-11
Informix SQL
データベースの作成 6-35, 9-30
UNLOAD 文 9-31
Insert アクセス権 11-9, 11-31
INSERT カーソル
使用 7-12
定義 7-9
INSERT 文
アクセス権 11-6, 11-9
インデックスの更新にかかる時
間 10-22
埋め込み 7-8, 7-14
およびデータの終わり 7-15
行数 6-12
使用
ビュー 11-29
挿入
行 5-7
単一行 5-7
複数行 5-9
挿入された行のカウント数 7-11
重複値 5-8
定数データ 7-12
NULL 値 5-8
SELECT 文 5-9
VALUES 節 5-7
INTO キーワード
格納場所の選択 6-22
索引 13
Bookname
February 6, 2003 3:24 pm
単一行の抽出 6-13
複数行の抽出 6-20
FETCH 文 6-22
INSERT に関する制限 5-10
PREPARE 文で処理された文 6-29
SQLAWARN でシグナルされたミス
マッチ 6-12
INTO TEMP キーワード
説明 2-73
ビューの制約事項 11-26
ISAM エラー・コード 6-12
L
LAN. LAN ( ローカル・エリア・ネット
ワーク ) を参照
LENGTH 関数
可変長文字 (VARCHAR) 型 2-56
式での使用 2-55
テキスト (TEXT) 型 2-56
LIKE 関係演算子 2-34
LIKE テスト 4-37
LOCK MODE キーワード
ページ・ロックまたは行ロックの指
定 7-24
LOCK TABLE 文
明示的な表のロック 7-23
M
MATCHES 関係演算子
文字クラス 2-37
WHERE 節 2-34
MAX 関数
集計関数 2-47
MDY 関数
時刻関数 2-49
MIN 関数
集計関数 2-47
MODE ANSI キーワード
トランザクションの指定 5-23
ANSI 準拠データベース 1-17
MONEY データ型
INSERT 内 5-8
MONTH 関数
時刻関数 2-49
N
NEXT SIZE キーワード
エクステントのサイズの指定 10-9
NFS. ネットワーク・ファイル・システ
ムを参照
NOT 関係演算子 2-30
NOT 論理演算子 2-33
NOT NULL キーワード
使用
CREATE TABLE 9-28
NULL 値
主キーの制限 8-7
テスト 2-33
ESQL での検出 6-15
INSERT 文内 5-8
Null 値
論理演算子 2-33
NULL 関係演算子 2-33
O
OnLine
ファイル 21
Online
ヘルプ 21
OPEN 文
カーソルの活動化 6-20
SELECT または UPDATE カーソルの
オープン 6-20
OR 関係演算子 2-31
OR 論理演算子 2-33
ORDER BY キーワード
行のソート 2-14
昇順 2-14
番号による列の選択 2-23
ビューの制約事項 11-26
表示ラベル 2-46
複数列 2-15
DESC キーワード 2-15, 2-25
FOR UPDATE の制限 7-8
INSERT に関する制限 5-10
インデックス 4-16, 4-33
行ソート 4-18
GROUP BY との関係 3-6
P
PREPARE 文
シグナルされた WHERE の欠落 6-10
14
索引
Bookname
February 6, 2003 3:24 pm
複数の SQL 文 6-31
GRANT の PREPARE 文での処
理 11-15
PREPARE 文で処理された文
説明 6-30
SQLERRD 内のエラー戻り 6-12
PUBLIC キーワード
すべてのユーザーに付与されたアク
セス権 11-7
PUT 文
挿入された行のカウント数 7-11
定数データ 7-12
バッファーへの戻りデータの送
信 7-10
R
RENAME COLUMN 文
制約事項 11-25
RENAME TABLE 文
制約事項 11-25
Resource アクセス権 4-34, 11-7
REVOKE 文
アクセス権の付与 11-6, 11-16
埋め込み SQL 内 6-35, 6-38
ビューの使用 11-32
RFS. リモート・ファイル共用を参照
ROLLBACK WORK 文
カーソルのクローズ 7-35
セット SQLCODE 7-5
トランザクションのキャンセル 5-23
ロックの解放 7-25, 7-35
ROLLFORWARD DATABASE 文
復元されたデータベースへのログの
適用 5-24
S
Select アクセス権
定義 11-9
ビューの使用 11-31
列レベル 11-11
SELECT 文
アクセス権 11-6, 11-9
アクティブ・セット 2-27
アスタリスク 2-12
埋め込み 6-13, 6-16
カーソル 6-19, 6-20
外部結合 3-19, 3-28
外部表 12-14
関数 2-47, 2-58
簡単な説明 2-3, 2-73
行 ID 3-19
行 ID 3-15
結合 2-62, 2-69
結合された表 2-60, 2-73
高度な文の説明 3-49
サブ文字列の選択 2-25
式の選択 2-41
自己結合 3-11
自然結合 2-65
集計関数 2-47
修正可能ビュー内 11-27
使用
結合 2-9
射影 2-7
選択 2-5
詳細な説明 3-3
選択リスト 2-12
単一 2-27
単一表 2-12, 2-58
日付指向関数 2-49
表示ラベル 2-44
複合問い合わせ 3-37
副問い合わせ 3-29, 3-37
別名 2-70
DISTINCT キーワード 2-20
INTO TEMP 節 2-73
ORDER BY 節 2-14
SELECT 節 2-12, 2-26
UNION 演算子 3-37
SERIAL データ型
開始値の挿入 5-8
SQLERRD での生成番号 6-12
SET キーワード
UPDATE 内で使用 5-12
SET 節 5-14
SET EXPLAIN 文
出力の解釈 4-32
問い合わせ予定の書き込み 4-19
SET ISOLATION 文
制限 7-26
ロック効果の制御 5-26
SET LOCK MODE 文
説明 7-30
ロック効果の制御 5-26
SET LOG 文
バッファー付きとバッファーな
し 9-26
索引 15
Bookname
February 6, 2003 3:24 pm
SITENAME 関数
使用
SELECT 2-55, 2-58
SITENAME 機能
使用法
SELECT 内 3-18
SOME キーワード
副問い合わせの開始 3-29
SPL
プログラム変数 6-5
SQL
エラー処理 6-16
カーソル 6-19
最適化。最適化を参照
説明 1-15
対話型の使用 1-18
標準化 1-16
履歴 1-16
ANSI 標準 1-16
Informix SQL および ANSI SQL 1-16
SQL 通信域 (SQLCA)
行の挿入 7-11
SQL 通信領域 (SQLCA)
説明 6-8
トランザクションの終わりによって
変更された 7-5
SQLAWARN 配列
説明 6-12
命名構文 6-11
PREPARE 文の使用 6-30
SQLCODE フィールド
カーソルのオープン後 6-20
シグナルされたデータの終わり 6-17
説明 6-11
DELETE による設定 7-4
DESCRIBE による設定 6-34
PUT、FLUSH による設定 7-11
SELECT のみのデータの終わり 7-15
SQLERRD 配列
行のカウント数 7-15
削除された行数 7-4
説明 6-12
挿入された行のカウント数 7-11
命名構文 6-11
START DATABASE 文
トランザクション・ログの追加 9-27
STATUS 変数 (4GL) 6-11
stores5 データベース
概要 6
コピー 7
16
索引
Bookname
February 6, 2003 3:24 pm
IBM Informix OnLine での作成 7
IBM Informix SE での作成 8
SUM 関数
集計関数 2-47
T
tbcheck ユーティリティー 4-36, 10-8,
10-14
tbload ユーティリティー 5-25, 10-13
tbstat ユーティリティー 10-14
tbunload ユーティリティー 5-25, 10-13
TEXT データ型
制限
GROUP BY による 3-6
TODAY 関数
使用
定数式 2-55, 5-8
U
UNION 演算子
説明 3-37
ビューの制約事項 11-26
表示ラベル 3-41
UNIQUE キーワード
修正可能ビューでの制約事項 11-27
CREATE TABLE の制約 9-28
UNLOAD 文
ファイルへのデータのエクスポー
ト 9-31
Update アクセス権
定義 11-9
ビューの使用 11-31
列レベル 11-11
UPDATE カーソル
定義 7-16
UPDATE 文
アクセス権 11-6, 11-9
インデックスの更新にかかる時
間 10-22
埋め込み 7-15, 7-18
およびデータの終わり 7-15
行数 6-12
シグナルされた WHERE の欠落 6-10
説明 5-11
ビューへの適用 11-28
複数の割り当て 5-14
副問い合わせに関する制限 5-13
PREPARE 文で処理 6-30
USER 関数
使用
式 2-55, 2-56
USER 機能
使用法
式内 3-17
USING キーワード
使用
EXECUTE 内 6-32
V
VALUES キーワード
使用
INSERT 内 5-7
W
WEEKDAY 関数
時刻関数 2-49, 2-53
WHERE キーワード
値の範囲 2-30
関係演算子 2-27
行の選択 2-26
使用
NOT キーワード 2-30
OR キーワード 2-31
データ制約の施行 11-30
比較条件 2-27, 2-40
日付指向関数 2-53
ブール式 2-33
ホスト変数 6-13
文字部分列のテスト 2-39
ワイルドカード比較 2-34
DELETE 内 5-4, 5-6
NULL データ・テスト 2-33
インデックス使用の回避 4-35, 4-37,
4-38
副問い合わせ 3-29
WHERE CURRENT OF キーワード
X
X/Open 準拠レベル 21
Y
YEAR 関数
時刻関数 2-49
数字
10 進数 (DECIMAL) 型
固定小数点 9-11
浮動小数点 9-10
10 進数 (NUMERIC) 型 9-7
記号
「カーソル安定性」排他レベル 7-28
「確定読み込み」排他レベル 7-27
「繰り返し可能読み込み」排他レベル
説明 7-29
「単純読み込み」排他レベル 7-27
使用
UPDATE での 7-16
DELETE での使用 7-7
WITH CHECK OPTION キーワード 11-29
WITH HOLD キーワード
HOLD カーソル 7-36
HOLD カーソルの宣言 10-37
索引 17
Bookname
February 6, 2003 3:24 pm
18
索引
Bookname
February 6, 2003 3:24 pm
򔻐򗗠򙳰
Printed in Japan
GB88-8615-00
Fly UP