Viewを使って
開発を楽にする話
2015-09-20
第11回 中国地方DB勉強会 in 広島
はじめに
突然の仕様変更
テーブル追加
項目の追加
プログラムの改修
etc
このタイミングで
そんな要求?
そのデータどうやって
引っ張ってこよう
SQL長くて
見づらくならない?
もっと楽できないか?
もっとシンプルに
ならないか?
今日はそんなお話です
アジェンダ
・はじめに
・自己紹介
・Viewって?
・Viewの使い方
・デモ
・まとめ
自己紹介
 
渡邉   勇
わたなべ   いさむ
• システム保守運用会社にてIT業界のキャリアをスタート。
• 100台規模に渡る、Windows サーバの構築・保守運用を
手掛け、2003年 楽天グループ会社に入社後、システム
開発会社、インターネット上での配信プラットフォーム
事業社、WEBサービス事業社を経て現在に至る。
• 各種ASPやWEBサービス開発に携わる傍ら、Linuxサーバ
の構築、ネットワーク機器設定等、プログラムからイン
フラまでマルチにこなす。
ファナフェクト 株式会社 取締役
Viewって?
Wikipedia より
1つ以上の表(または他のビュー)から任意の
データを選択し、それらをカスタマイズして表
したものである。
ビューは、実表と同じく行と列に編成されるが、
実表とは異なりデータそのものは含まれない。
ビューを使用すると、複数の表またはビューを
1つの表であるかのように見ることができる。
いまいちよく分からない
壮大なデータの海から
必要な情報を切り取って取
得できる
とても便利な機能
※背景はオーシャンビューでお送りします
雑すぎるので・・・
Viewを使うと
商品ID 商品名 商品名かな 原価 販売価格
1 商品1 しょうひんいち 400 1000
2 商品2 しょうひんに 350 980
3 商品3 しょうひんさん 300 950
商品ID 商品名
1 商品1
2 商品2
3 商品3
テーブルのようなものが作れる
一度作成すれば
普通のテーブルと
同じように利用可能
Viewとテーブルを
繋げてデータを
取得することが可能
Viewを作るのは
とてもカンタン
見ためがシンプルになる
メンテナンスが楽になる
プログラム改修が
楽になる
Viewの使い方
CREATE□VIEW□
<<VIEW_NAME>>□AS□<<SELECT文>>;
※ □はスペース <>は実際は入力しない
Viewを作る
CREATE□OR□REPLACE□VIEW□<<VIEW
_NAME>> AS <<SELECT文>>;
※ □はスペース <>は実際は入力しない
Viewの内容を変更する
DROP□VIEW□<<VIEW_NAME>>;
※ □はスペース <>は実際は入力しない
Viewを削除する
■Viewの作成と更新
http://dev.mysql.com/doc/refman/5.6/ja/create-
view.html
https://www.postgresql.jp/document/9.4/html/sql-
createview.html
■Viewの削除
http://dev.mysql.com/doc/refman/5.6/ja/drop-
view.html
https://www.postgresql.jp/document/9.4/html/sql-
dropview.html
各種詳細URL
デモ
※ これより記載のSQL文はあくまでViewの学習用で作成した物であり
Viewのデメリットを含んでいます。デメリットについては、デモ内で
説明しますので正しい理解の上で参考ください。
テーブル構成
顧客テーブル 商品テーブル 受注テーブル
顧客テーブル
CREATE TABLE `t_customers` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '連番
ID',
`last_name` varchar(20) NOT NULL COMMENT '姓',
`first_name` varchar(10) NOT NULL COMMENT '名前',
`last_name_kana` varchar(45) DEFAULT NULL COMMENT 'セイ',
`first_name_kana` varchar(45) DEFAULT NULL COMMENT 'ナマエ',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='顧客テーブル';
商品テーブル
CREATE TABLE `t_products` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '連番
ID',
`product_name` varchar(45) NOT NULL COMMENT '商品名',
`default_price` int(11) NOT NULL COMMENT '通常価格',
`sales_price` varchar(45) NOT NULL COMMENT '販売価格',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商品テーブル’;
受注テーブル
CREATE TABLE `t_orders` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '連番
ID',
`customer_id` int(11) NOT NULL COMMENT '顧客ID',
`sub_total` int(11) unsigned NOT NULL COMMENT '小計',
`tax` int(11) unsigned NOT NULL DEFAULT ‘0’ COMMENT ‘消費税’,
`order_date` timestamp NOT NULL COMMENT '受注日',
PRIMARY KEY (`id`),
KEY `idx_customer_id` (`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
顧客一覧を取得する
SELECT * FROM t_customers;
顧客ID毎の最終購入日 購入金額合計
を取得する
SELECT
customer_id,
MAX(order_date) last_order_date,
sum(sub_total + tax) total_price
FROM t_orders
GROUP BY
customer_id
ORDER BY order_date DESC;
顧客テーブルと受注テーブルを結合して顧客名
最終購入日 購入金額合計を取得する
SELECT
c.first_name,c.last_name,_tmp.last_order_date,_tmp.total_price
FROM t_customers c
LEFT JOIN (
SELECT
customer_id,
MAX(order_date) last_order_date,
SUM(sub_total + tax) total_price
FROM t_orders
GROUP BY customer_id
) _tmp ON c.id = _tmp.customer_id;
Viewを作成する
CREATE OR REPLACE VIEW v_customer_orders AS SELECT
customer_id,
MAX(order_date) last_order_date,
SUM(sub_total + tax) total_price
FROM t_orders
GROUP BY customer_id;
作成したViewから条件を指定して該当する
データを取得する
SELECT
customer_id,
last_order_date,
total_price
FROM v_customer_orders
WHERE customer_id = 1;
顧客テーブルと作成したViewを結合して顧客
氏名 最終購入日 購入金額合計 を取得する
SELECT
c.first_name,
c.last_name,
IFNULL(co.last_order_date,'-'),
IFNULL(co.total_price,'-')
FROM t_customers c
LEFT JOIN v_customer_orders co ON
c.id = co.customer_id;
Viewに項目を追加する
CREATE OR REPLACE VIEW v_customer_orders AS SELECT
customer_id,
MAX(order_date) last_order_date,
MIN(order_date) first_order_date,
COUNT(customer_id) order_count,
SUM(sub_total + tax) total_price
FROM t_orders
GROUP BY customer_id;
Viewに追加された項目も取得する
SELECT
c.first_name,
c.last_name,
IFNULL(co.order_count,0) order_count,
IFNULL(co.first_order_date,'-') first_order_date,
IFNULL(co.last_order_date,'-') last_order_date,
IFNULL(co.total_price,'-') total_price
FROM t_customers c
LEFT JOIN v_customer_orders co ON
c.id = co.customer_id;
Viewのデメリット
・実データを保持せず、Queryを流しているのと同じ為、遅いQueryは遅い。
なので
・集約関数( SUM、AVG、COUNT、MAX、MIN )との活用
・集合演算子( UNION、INTERSECT、EXCEPT(MINUS))との活用
には気をつける必要がある
Viewが遅い場合の回避策
・ViewにINDEXを貼る
・SQL Server
・マテリアライズドビューを利用する
・PostgreSQL 9.3で対応。9.4で自動更新に対応
・トリガー等を用いて中間テーブルを作成する
・MySQL
まとめ
Viewについて
・見ためがシンプルになる
・メンテナンスが楽になる
・プログラム改修が楽になる
・集約関数に気をつけよう(デモよ
り)
・銀の弾丸ではない
ご静聴
ありがとうございました

Viewを使って開発を楽にする話

Editor's Notes

  • #3  ----- 会議メモ (15/09/20 08:16) ----- クライアントから求められる様々な要求に応えていると、SQL文が長くなってしまうケースって現場ありありな話ですが、Viewを使えばとてもシンプルなSQL文で機能実装する事が可能になります。本日お話する内容は、Viewを使った実際の開発のサンプルをご紹介します。