gihyo.jp
リレーショナルではない操作
リレーショナルな操作のおさらい
リレーションの演算 |
SELECTによる表現 |
制限 |
基本形: WHERE句 |
射影 |
基本形: select list |
直積 |
基本形: FROM句, JOIN句 |
結合 |
基本形: FROM句, JOIN句 |
積 |
基本形: FROM句, JOIN句 |
和 |
UNION |
差 |
NOT EXISTSサブクエリ, MINUS |
属性名変更 |
基本形: select list |
拡張 |
基本形: select list |
- IN, ANY, EXISTSサブクエリはJOINとDISTINCTを用いて書けることが知られている
- 他のはリレーショナルな演算でない
ソート
- ORDER BY句による結果セットの並べ替えはリレーショナルモデル上の演算ではない
- ORDER BYはカーソルの操作である (SQL標準より)
- アプリケーション開発上有用だが、リレーショナルモデルから逸脱する危険な要素であるため要注意
明示的に定義されていないカラム
- ROWID、ROWNUMなど
- やはり順序絡みなのでリレーショナルモデルを逸脱する。要注意
ストアドファンクション(ユーザ定義関数)
- ストアドファンクションのロジックは手続き型で記述される
- ストアドファンクションがSELECTに含まれると、手続き型の処理になる
- オプティマイザ困惑
- SQLは宣言型プログラミング言語である
コラム: 集約とGROUP BY
- GROUP BYは数学的には「要約」(Summarizatoin)だよ、という話
- リレーションからリレーションを求める
- cf. 「集約」(Aggregate)はリレーションからスカラを求める
- 要約は拡張の一種
- リレーションの演算以外の何らかの方法で集計を行い、新たに属性を追加している
- 学生の人数を学科ごとに集計する例
SELECT department
, COUNT(*)
FROM students
GROUP BY department;
SELECT department
, (SELECT COUNT(*)
FROM students
WHERE department = t1.department
) AS COUNT
FROM (SELECT DISTINCT
department
FROM students
) AS t1;
SELECT DISTINCT
department
FROM students
SELECT COUNT(*)
FROM students
WHERE department = t1.department
リレーショナルではない操作の扱い方
- アプリケーション開発ではリレーショナルではない操作も必要
- 大事なのは、リレーショナルな操作とそうでない操作とを明確に区別すること
- 指針
- リレーショナルモデルの範疇でできることをリレーショナルではない操作で実装しない
- オプティマイザによる最適化はリレーショナルモデルの範疇で最大の威力を発揮するため
- リレーショナルモデルの範疇でうまく記述できないと思ったら、DB設計を見直す
- 見直しができない場合、泥沼に足を踏み入れることになる
- リレーショナルではない操作がどうしても必要な場合は、リレーショナルな操作に関するロジックを必ず先に行う
- 【補】リレーショナルな操作の入力はリレーション
- 先にリレーショナルではない操作を行ってしまうと、後にリレーショナルな操作を続けられない
インデントでSQLを読みやすくする