狠狠撸

狠狠撸Share a Scribd company logo
PostgreSQL 9.3
Yasuo Ohgaki / yohgaki@ohgaki.net / www.ohgaki.net
自己紹介
? 氏名:大垣靖男(Ohgaki Yasuo)
? メール:yohgaki@ohgaki.net
? SNS: yohgaki (Twitter/Facebook/Gmail/LinkedIn)
? 職業:
? エレクトロニック?サービス?イニシアチブ有限会社社長
? PHP技術者認定機構顧問?BOSS CON CTO?岡山大学大学
院講師
? Webアプリソースコード検査
(Ruby/PHP/Java/C#/ObjectiveC)など
? OSS開発者:PHP、Momonga-Linuxコミッター
2013/07/08岡山Ruby会議2013 (C) Electronic Service Initiative, Ltd. 2
PROVE for PHP
2013/07/08岡山Ruby会議2013 (C) Electronic Service Initiative, Ltd. 3
www.provephp.com
PostgreSQL 9.x
2013/8/3中国DB勉強会 4
PostgreSQL 9.x
2013/8/3中国DB勉強会 5
PostgreSQL 9.2のパフォーマンス
https://sites.google.com/site/robertmhaas/presentations/Performance%20and%20Scalability%20Enhancements%20in%20PostgreSQL%209.2.odp?attredirects=0&d=1
2013/8/3中国DB勉強会 6
PostgreSQL 9.2のパフォーマンス
https://sites.google.com/site/robertmhaas/presentations/Performance%20and%20Scalability%20Enhancements%20in%20PostgreSQL%209.2.odp?attredirects=0&d=1
2013/8/3中国DB勉強会 7
PostgreSQL 9.2未満?
PostgreSQL 9.2にアップグレードする
だけで高速化!
アップグレードしないのは損!
2013/8/3中国DB勉強会 8
PostgreSQL 9.3
2013/8/3中国DB勉強会 9
2013年秋 PostgreSQL 9.3
? PostgreSQL 9.3がこの秋に正式リリース予定です。執筆時
点ではBeta2がリリースされています。今回は現時点でリ
リースが確定している機能をご紹介します。
2013/8/3中国DB勉強会 10
機能追加
?データが更新されないビュー
?http://www.postgresql.org/docs/9.3/static/rules-materializedviews.html
?http://www.postgresql.org/docs/9.3/static/sql-creatematerializedview.html
マテリアライズドビュー
?ビューの定義と同時に更新ルールを定義
?http://www.postgresql.org/docs/9.3/static/sql-createview.html#SQL-CREATEVIEW-UPDATABLE-
VIEWS
更新可能ビュー
? 再帰的なビューを定義
?http://www.postgresql.org/docs/9.3/static/sql-createview.html
再帰ビュー
? 他のPostgreSQLサーバのデータ更新
?http://www.postgresql.org/docs/9.3/static/sql-createserver.html
?http://www.postgresql.org/docs/9.3/static/sql-createforeigndatawrapper.html
?http://www.postgresql.org/docs/9.3/static/fdwhandler.htmll
更新可能外部テーブル
2013/8/3中国DB勉強会 11
機能追加
?10の関数と4つ演算子
?http://www.postgresql.org/docs/9.3/static/datatype-json.html
?http://www.postgresql.org/docs/9.3/static/functions-json.html
JSON機能追加
?FROM句でSELECT文を利用可能
?http://www.postgresql.org/docs/9.3/static/sql-select.html
LATERAL JOIN
? CREATE、ALTER、DROPにトリガーを定義
?http://www.postgresql.org/docs/9.3/interactive/sql-createeventtrigger.html
?http://www.postgresql.org/docs/9.3/interactive/event-trigger-matrix.html
?http://www.postgresql.org/docs/9.3/interactive/plpgsql-trigger.html#PLPGSQL-EVENT-TRIGGER
イベントトリガー
?レプリケーションクラスタ管理の容易化
?http://www.databasesoup.com/2013/01/cascading-replication-and-cycles.html
ストリーミングによるリマスター
2013/8/3中国DB勉強会 12
機能追加
? ストリーミングレプリケーションがアーキテクチャ非依存に変更
アーキテクチャ非依存のストリーミング
? recovery.confの自動作成
pg_basebackupコマンドによるセットアップ
? postgresql.confから追加設定ファイルを読み込み
? http://www.postgresql.org/docs/9.3/static/config-setting.html#CONFIG-INCLUDES
include_dir
? 独自のバックグラウンドワーカをモジュールとしてロード
? http://www.postgresql.org/docs/9.3/static/bgworker.html
カスタムバックグラウンドワーカー
? PostgreSQLが利用可能か確認するコマンド
? http://www.postgresql.org/docs/9.3/static/app-pg-isready.htm
pg_isreadyコマンド
2013/8/3中国DB勉強会 13
高速化
? データがフリーズされているとしてロードする(高速化)
? http://www.postgresql.org/docs/9.3/static/sql-copy.html
COPY FREEZE
? 並列バックアップによるバックアップ高速化
? http://www.postgresql.org/docs/9.3/static/app-pgdump.html
パラレルpg_dump
? ファイルオーバーの高速化(1秒以内)
高速フェイルオーバー
2013/8/3中国DB勉強会 14
その他の変更
? SysV共有メモリから変更
? http://www.postgresql.org/docs/9.3/static/kernel-
resources.html#SYSVIPC
? SQLite3 はMMAPに変更して数倍高速化されたが、PostgreSQLの場
合は変化なし
POSIX共有メモリとMMAPの利用
2013/8/3中国DB勉強会 15
追加機能紹介
ビューおよびJSON関連
2013/8/3中国DB勉強会 16
マテリアライズドビュー
? マテリアライズドビューとはテーブルのスナップショット
のようなビュー
? データ更新は明示的に指定
? 差分だけリフレッシュする機能が無く、リフレッシュには
排他ロックが必要な事に注意
? CREATE MATERIALIZED VIEW ビュー名 AS 条件;
マテリアライズドビューの作成
? REFRESH MATERIALIZED VIEW ビュー名;
マテリアライズドビューの更新
2013/8/3中国DB勉強会 17
マテリアライズドビューの例
yohgaki@127 ~=# CREATE TABLE my_table (
id SERIAL PRIMARY KEY,
txt text,
date TIMESTAMP DEFAULT now()
);
CREATE TABLE
yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');
INSERT 0 1
yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');
INSERT 0 1
yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');
INSERT 0 1
yohgaki@127 ~=# CREATE MATERIALIZED VIEW my_mate_view AS SELECT * FROM my_table;
SELECT 3
yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');
INSERT 0 1
yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');
INSERT 0 1
yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');
INSERT 0 1
2013/8/3中国DB勉強会 18
マテリアライズドビューの例
yohgaki@127 ~=# SELECT * FROM my_mate_view;
id | txt | date
----+-----+----------------------------
1 | abc | 2013-07-25 07:39:32.099291
2 | abc | 2013-07-25 07:39:32.851492
3 | abc | 2013-07-25 07:39:35.835314
(3 行)
yohgaki@127 ~=# SELECT * FROM my_table;
id | txt | date
----+-----+----------------------------
1 | abc | 2013-07-25 07:39:32.099291
2 | abc | 2013-07-25 07:39:32.851492
3 | abc | 2013-07-25 07:39:35.835314
4 | abc | 2013-07-25 07:41:07.430558
5 | abc | 2013-07-25 07:41:08.278669
6 | abc | 2013-07-25 07:41:10.959413
(6 行)
2013/8/3中国DB勉強会 19
マテリアライズドビューの例
yohgaki@127 ~=# REFRESH MATERIALIZED VIEW my_mate_view;
REFRESH MATERIALIZED VIEW
yohgaki@127 ~=# SELECT * FROM my_mate_view;
id | txt | date
----+-----+----------------------------
1 | abc | 2013-07-25 07:39:32.099291
2 | abc | 2013-07-25 07:39:32.851492
3 | abc | 2013-07-25 07:39:35.835314
4 | abc | 2013-07-25 07:41:07.430558
5 | abc | 2013-07-25 07:41:08.278669
6 | abc | 2013-07-25 07:41:10.959413
(6 行)
2013/8/3中国DB勉強会 20
更新可能ビュー
? 商用データベースでは更新可能なビューをサポート
? 特にMS SQL Serverは古くから更新可能ビューをサポート
? PostgreSQL9.3からビュー定義が簡単な場合、自動的に
ビューを更新可能
? 9.3以前は更新可能なビューを作成するにはINSERT、UPDATE、
DELETEに対するルールまたはトリガーを定義
2013/8/3中国DB勉強会 21
更新可能ビュー
? FROM句に1つのテーブルまたは更新可能ビューが設定され
ている
? WITH, DISTINCT, GROUP BY, HAVING, LIMIT, OFFSETが
トップレベルに含まれない
? UNION、INTERSECT、EXCEPTがトップレベルに含まれ
ない
? 全てのコラムが単純な参照であること(表現、リテラル、
関数でない)
? ビューのSELECTリストにコラムの重複が無い
? security_barrierプロパティが設定されていない
2013/8/3中国DB勉強会 22
更新可能ビューの例
yohgaki@127 ~=# CREATE TABLE my_table (
yohgaki(# id SERIAL PRIMARY KEY,
yohgaki(# txt text,
yohgaki(# date TIMESTAMP DEFAULT now()
yohgaki(# );
CREATE TABLE
yohgaki@127 ~=# CREATE VIEW my_view AS SELECT * FROM my_table WHERE id > 2;
CREATE VIEW
yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');
INSERT 0 1
yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');
INSERT 0 1
yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');
INSERT 0 1
yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');
INSERT 0 1
yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');
INSERT 0 1
2013/8/3中国DB勉強会 23
更新可能ビューの例
yohgaki@127 ~=# SELECT * FROM my_table;
id | txt | date
----+-----+----------------------------
1 | abc | 2013-07-25 06:58:08.747109
2 | abc | 2013-07-25 06:58:09.811324
3 | abc | 2013-07-25 06:58:10.442833
4 | abc | 2013-07-25 06:58:11.026806
5 | abc | 2013-07-25 06:58:11.611632
(5 行)
時間: 0.351 ms
yohgaki@127 ~=# SELECT * FROM my_view;
id | txt | date
----+-----+----------------------------
3 | abc | 2013-07-25 06:58:10.442833
4 | abc | 2013-07-25 06:58:11.026806
5 | abc | 2013-07-25 06:58:11.611632
(3 行)
2013/8/3中国DB勉強会 24
更新可能ビューの例
yohgaki@127 ~=# INSERT INTO my_view (txt) VALUES ('xyz');
INSERT 0 1
時間: 20.490 ms
yohgaki@127 ~=# INSERT INTO my_view (txt) VALUES ('xyz');
INSERT 0 1
時間: 9.702 ms
yohgaki@127 ~=# INSERT INTO my_view (txt) VALUES ('xyz');
INSERT 0 1
2013/8/3中国DB勉強会 25
更新可能ビューの例
yohgaki@127 ~=# SELECT * FROM my_view;
id | txt | date
----+-----+----------------------------
3 | abc | 2013-07-25 06:58:10.442833
4 | abc | 2013-07-25 06:58:11.026806
5 | abc | 2013-07-25 06:58:11.611632
6 | xyz | 2013-07-25 06:58:44.644324
7 | xyz | 2013-07-25 06:58:45.620243
8 | xyz | 2013-07-25 06:58:46.188217
(6 行)
yohgaki@127 ~=# SELECT * FROM my_table;
id | txt | date
----+-----+----------------------------
1 | abc | 2013-07-25 06:58:08.747109
2 | abc | 2013-07-25 06:58:09.811324
3 | abc | 2013-07-25 06:58:10.442833
4 | abc | 2013-07-25 06:58:11.026806
5 | abc | 2013-07-25 06:58:11.611632
6 | xyz | 2013-07-25 06:58:44.644324
7 | xyz | 2013-07-25 06:58:45.620243
8 | xyz | 2013-07-25 06:58:46.188217
(8 行)
2013/8/3中国DB勉強会 26
更新可能ビューの例
yohgaki@127 ~=# DELETE FROM my_view WHERE id = 7;
DELETE 1
yohgaki@127 ~=# SELECT * FROM my_view;
id | txt | date
----+-----+----------------------------
3 | abc | 2013-07-25 06:58:10.442833
4 | abc | 2013-07-25 06:58:11.026806
5 | abc | 2013-07-25 06:58:11.611632
6 | xyz | 2013-07-25 06:58:44.644324
8 | xyz | 2013-07-25 06:58:46.188217
(5 行)
yohgaki@127 ~=# UPDATE my_view SET txt = 'ABC';
UPDATE 5
yohgaki@127 ~=# SELECT * FROM my_view;
id | txt | date
----+-----+----------------------------
3 | ABC | 2013-07-25 06:58:10.442833
4 | ABC | 2013-07-25 06:58:11.026806
5 | ABC | 2013-07-25 06:58:11.611632
6 | ABC | 2013-07-25 06:58:44.644324
8 | ABC | 2013-07-25 06:58:46.188217
(5 行)
2013/8/3中国DB勉強会 27
ビューが更新可能かどうか
システムカタログをクエリーして判別
yohgaki@127 ~=# SELECT table_name, is_insertable_into FROM
information_schema.tables WHERE table_name = 'my_view';
table_name | is_insertable_into
------------+--------------------
my_view | YES
2013/8/3中国DB勉強会 28
再帰ビュー
yohgaki@127 ~=# CREATE VIEW fib_up_to_50 AS
WITH RECURSIVE
fib AS (
SELECT 0 AS a, 1 AS b
UNION ALL
SELECT b, a + b FROM fib WHERE b <= 50
)
SELECT a FROM fib;
CREATE VIEW
yohgaki@127 ~=# SELECT * FROM fib_up_to_50;
a
----
0
1
1
2
3
5
8
13
21
34
2013/8/3中国DB勉強会 29
WITH RECURSIVEのみでも可能
yohgaki@127 ~=# WITH RECURSIVE
fib AS (
SELECT 0 AS a, 1 AS b
UNION ALL
SELECT b, a + b FROM fib WHERE b <= 50
)
SELECT a FROM fib;
a
----
0
1
1
2
3
5
8
13
21
34
2013/8/3中国DB勉強会 30
実用的な例
WITH RECURSIVE included_parts(sub_part, part, quantity) AS (
SELECT sub_part, part, quantity FROM parts WHERE part = 'our_product'
UNION ALL
SELECT p.sub_part, p.part, p.quantity
FROM included_parts pr, parts p
WHERE p.part = pr.sub_part
)
SELECT sub_part, SUM(quantity) as total_quantity
FROM included_parts
GROUP BY sub_part
2013/8/3中国DB勉強会 31
JSONサポート
? RFC 4627に準拠したJSONサポートはPostgreSQL 9.2から
追加
? http://www.postgresql.org/docs/9.3/static/datatype-json.html
? PostgreSQL 9.3ではJSON型データを操作する4つのオペ
レータと新たな10の関数が追加
2013/8/3中国DB勉強会 32
JSONサポート PostgreSQL 9.2
? JSON形式のデータを保存
? データ形式はバリデーションされる
JSON型
? 配列をJSONとして返す。PostgreSQLの多次元配列がJSON配列として返
される。pretty_boolが真の場合、1次元の要素の後に改行が追加される。
array_to_json(anyarray [, pretty_bool])
? 行をJSONとして返す。pretty_boolが真の場合、一次元の要素の後に改行
が追加される。
row_to_json(record [, pretty_bool])
2013/8/3中国DB勉強会 33
JSONサポート - 演算子
? 配列要素またはオブジェクトフィールドを取得する。
->
? 配列要素の値またはオブジェクトフィールドの値をテキストとし
て取得する
->>
? 指定されたパスのJSONオブジェクトを取得する
#>
? 指定されたパスのJSONオブジェクトをテキストとして取得する。
#>>
2013/8/3中国DB勉強会 34
JSON用演算子の利用例
yohgaki@127 ~=# SELECT '[1,2,3]'::json->2;
?column?
----------
3
(1 行)
yohgaki@127 ~=# SELECT '{"a":1,"b":2}'::json->'b';
?column?
----------
2
(1 行)
yohgaki@127 ~=# SELECT '[1,2,3]'::json->>2;
?column?
----------
3
時間: 0.304 ms
yohgaki@127 ~=# SELECT '{"a":1,"b":2}'::json->>'b';
?column?
----------
2
(1 行)
2013/8/3中国DB勉強会 35
JSON用演算子の利用例
yohgaki@127 ~=# SELECT '{"a":[1,2,3],"b":[4,5,6]}'::json#>'{a,2}';
?column?
----------
3
yohgaki@127 ~=# SELECT '{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}';
?column?
----------
3
(1 行)
2013/8/3中国DB勉強会 36
JSON関数
? JSON型を返す。組み込みデータ型でない場合、JSON型にキャストされる。
その他の値はJSONとして正しい値となるようにエスケープされる。
to_json(anyelement)
yohgaki@127 ~=# SELECT to_json('Fred said "Hi."'::text);
to_json
---------------------
"Fred said "Hi.""
(1 行)
2013/8/3中国DB勉強会 37
JSON関数
? JSONの配列要素数を返す。再帰的に要素数は数えない。
json_array_length(json)
yohgaki@127 ~=# SELECT json_array_length('[1,2,3,{"f1":1,"f2":[5,6]},4]');
json_array_length
-------------------
5
(1 行)
2013/8/3中国DB勉強会 38
JSON関数
? JSONオブジェクトのキー/値のペアのセットを返す。再
帰的な処理は行わない。
json_each(json)
yohgaki@127 ~=# SELECT * from json_each('{"a":"foo", "b":"bar"}');
key | value
-----+-------
a | "foo"
b | "bar"
(2 行)
2013/8/3中国DB勉強会 39
JSON関数
? JSONオブジェクトのキー/値のペアのセットを文字列と
して返す。再帰的な処理は行わない。
json_each_text(from_json json)
yohgaki@127 ~=# SELECT * from json_each_text('{"a":"foo", "b":"bar"}');
key | value
-----+-------
a | foo
b | bar
(2 行)
2013/8/3中国DB勉強会 40
JSON関数
? パス指定されたJSONオブジェクトを返す。
json_extract_path(from_json json,
VARIADIC path_elems text[])
yohgaki@127 ~=# SELECT
json_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4');
json_extract_path
----------------------
{"f5":99,"f6":"foo"}
(1 行)
2013/8/3中国DB勉強会 41
JSON関数
? パス指定されたJSONオブジェクトをテキストとして返す。
json_extract_path_text(from_json json,
VARIADIC path_elems text[])
yohgaki@127 ~=# SELECT
json_extract_path_text('{"f2":{"f3":1},"f4":{"f5":99,"f6":"foo"}}','f4', 'f6');
json_extract_path_text
------------------------
foo
(1 行)
2013/8/3中国DB勉強会 42
JSON関数
? JSONのキーをテキストとして返す。再帰的な処理は行わ
ない。
json_object_keys(json)
yohgaki@127 ~=# SELECT
json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}');
json_object_keys
------------------
f1
f2
(2 行)
2013/8/3中国DB勉強会 43
JSON関数
? JSONデータからレコードを生成する。フィールド名が一致しな
いとNULLとなり、データ型が一致しない場合、エラーとなる。
json_populate_record(base anyelement, from_json
json, [, use_json_as_text bool=false])
yohgaki@127 ~=# CREATE TYPE x AS (f1 int, f2 bool, f3 text);
CREATE TYPE
yohgaki@127 ~=# SELECT * FROM json_populate_record(null::x, '{"f1":3,"f2":true,"f3":"Some text"}');
f1 | f2 | f3
----+----+-----------
3 | t | Some text
(1 行)
yohgaki@127 ~=# SELECT * FROM json_populate_record(null::x, '{"f1":3,"f2":true,"f3":"Some text", "f4":"Extra"}');
f1 | f2 | f3
----+----+-----------
3 | t | Some text
(1 行)
yohgaki@127 ~=# SELECT * FROM json_populate_record(null::x, '{"f1":3,"foo":"Bar","f3":"Some text"}');
f1 | f2 | f3
----+----+-----------
3 | | Some text
(1 行)
yohgaki@127 ~=# SELECT * FROM json_populate_record(null::x, '{"f1":3,"f2":"Bar","f3":"Some text", "f4":"Extra"}');
ERROR: invalid input syntax for type boolean: "Bar"
2013/8/3中国DB勉強会 44
JSON関数
? JSONデータからレコードセットを生成する。フィールド名が一致し
ないとNULLとなり、データ型が一致しない場合、エラーとなる。
json_populate_recordset(base anyelement, from_json
json, [, use_json_as_text bool=false]
yohgaki@127 ~=# SELECT * FROM
json_populate_recordset(null::x,
'[{"f1":1,"f2":false, "f3":"Foo"},{"f1":3,"f2":true, "f3":"Bar"}]');
f1 | f2 | f3
----+----+-----
1 | f | Foo
3 | t | Bar
(2 行)
2013/8/3中国DB勉強会 45
JSON関数
? JSON配列の要素を展開する。再帰的な処理は行われない。
json_array_elements(json)
yohgaki@127 ~=# SELECT json_array_elements('[1,true, [2,false]]');
json_array_elements
---------------------
1
true
[2,false]
(3 行)
2013/8/3中国DB勉強会 46
JSON関数とテーブル
? JSON関数はJSON型を持つテーブルと一緒に利用すると
様々なデータ操作を行える
yohgaki@127 ~=# CREATE TABLE my_json(id SERIAL PRIMARY KEY, j JSON);
時間: 132.419 ms
yohgaki@127 ~=# INSERT INTO my_json (j) VALUES ('{"f1":1,"f2":true,"f3":"Foo"}');
INSERT 0 1
yohgaki@127 ~=# INSERT INTO my_json (j) VALUES ('{"f1":2,"f2":false,"f3":"bar"}');
INSERT 0 1
# json_each()にクエリ結果を渡す
yohgaki@127 ~=# SELECT * FROM json_each((SELECT j FROM my_json WHERE id=1));
key | value
-----+-------
f1 | 1
f2 | true
f3 | "Foo"
(3 行)
# クエリでJSON型を取得し、json_extract_path()関数と"->"オペレータで同じ値を取得する
yohgaki@127 ~=# SELECT json_extract_path(j, 'f1') AS f1a, j->'f1' AS f1b FROM my_json WHERE id = 3;
f1a | f1b
---------------------+---------------------
{"f11":11,"f12":12} | {"f11":11,"f12":12}
(1 行)
2013/8/3中国DB勉強会 47
JSONサポートの注意点
? JSON型はTEXT型とほぼ同じ
? JSON型のクエリは基本的に遅い
? レコードを特定して操作するのは普通だが、JSON型のデータを
キーとして検索すると遅い
? 検索にはインデックス(関数インデックス)
? TEXT型とほぼ同じ、つまりGINを使った高速化などのテク
ニックが利用可能
? 注意点はあるがWeb開発者にとってはうれしい機能!
2013/8/3中国DB勉強会 48
まとめ
? PostgreSQL9.3の特徴
? パフォーマンスではなく機能強化
? ビュー機能の強化
? レプリケーション機能の強化
? JSONサポートの強化
? JSONサポート
? PostgreSQL9.2のJSONサポートは保存できるだけ
? PostgreSQL9.3からはデータ操作が可能
2013/8/3中国DB勉強会 49
PROVE for PHP
2013/07/08岡山Ruby会議2013 (C) Electronic Service Initiative, Ltd. 50
www.provephp.com

More Related Content

Postgre SQL 9.3 新機能