Postgre SQL 9.3 新機能
-
Upload
yasuo-ohgaki -
Category
Documents
-
view
2.464 -
download
5
description
Transcript of Postgre SQL 9.3 新機能
PostgreSQL 9.3Yasuo Ohgaki / [email protected] / www.ohgaki.net
2
自己紹介
▪ 氏名:大垣靖男( Ohgaki Yasuo )
▪ メール: [email protected]
▪ 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.
3
PROVE for PHP
2013/07/08岡山 Ruby 会議 2013 (C) Electronic Service Initiative, Ltd.
www.provephp.com
PostgreSQL 9.x
2013/8/3中国 DB 勉強会 4
5
PostgreSQL 9.x
• 非同期レプリケーション• ホットスタンバイ• SQL 構文強化
2010 PostgreSQL 9.0
• 同期レプリケーション• UNLOGED テーブル• SQL/MED (外部データ連携)
2011 PostgreSQL 9.1
• カスケードレプリケーション• インデックスのみのスキャン• スケーラビリティの向上
2012 PostgreSQL 9.2
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 のパフォーマンス
https://sites.google.com/site/robertmhaas/presentations/Performance%20and%20Scalability%20Enhancements%20in%20PostgreSQL%209.2.odp?attredirects=0&d=1
2013/8/3中国 DB 勉強会
8
PostgreSQL 9.2 未満?
PostgreSQL 9.2 にアップグレードするだけで高速化!
アップグレードしないのは損!
2013/8/3中国 DB 勉強会
PostgreSQL 9.3
2013/8/3中国 DB 勉強会 9
10
2013 年秋 PostgreSQL 9.3
▪ PostgreSQL 9.3 がこの秋に正式リリース予定です。執筆時点では Beta2 がリリースされています。今回は現時点でリリースが確定している機能をご紹介します。
2013/8/3中国 DB 勉強会
11
機能追加
•データが更新されないビュー•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 勉強会
12
機能追加
•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 勉強会
13
機能追加
• ストリーミングレプリケーションがアーキテクチャ非依存に変更
アーキテクチャ非依存のストリーミング
• 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 勉強会
14
高速化
• データがフリーズされているとしてロードする(高速化)• 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 勉強会
15
その他の変更
• SysV 共有メモリから変更• http://www.postgresql.org/docs/9.3/static/kernel-resources.html#SYSV
IPC
• SQLite3 は MMAP に変更して数倍高速化されたが、 PostgreSQL の場合は変化なし
POSIX 共有メモリと MMAP の利用
2013/8/3中国 DB 勉強会
追加機能紹介ビューおよび JSON 関連
2013/8/3中国 DB 勉強会 16
17
マテリアライズドビュー▪ マテリアライズドビューとはテーブルのスナップショット
のようなビュー
▪ データ更新は明示的に指定
▪ 差分だけリフレッシュする機能が無く、リフレッシュには排他ロックが必要な事に注意
• CREATE MATERIALIZED VIEW ビュー名 AS 条件 ;
マテリアライズドビューの作成
• REFRESH MATERIALIZED VIEW ビュー名 ;
マテリアライズドビューの更新
2013/8/3中国 DB 勉強会
18
マテリアライズドビューの例yohgaki@127 ~=# CREATE TABLE my_table (id SERIAL PRIMARY KEY,txt text,date TIMESTAMP DEFAULT now());CREATE TABLEyohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');INSERT 0 1yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');INSERT 0 1yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');INSERT 0 1yohgaki@127 ~=# CREATE MATERIALIZED VIEW my_mate_view AS SELECT * FROM my_table;SELECT 3yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');INSERT 0 1yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');INSERT 0 1yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');INSERT 0 1
2013/8/3中国 DB 勉強会
19
マテリアライズドビューの例
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 勉強会
20
マテリアライズドビューの例
yohgaki@127 ~=# REFRESH MATERIALIZED VIEW my_mate_view;REFRESH MATERIALIZED VIEWyohgaki@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 勉強会
21
更新可能ビュー▪ 商用データベースでは更新可能なビューをサポート
▪ 特に MS SQL Server は古くから更新可能ビューをサポート
▪ PostgreSQL9.3 からビュー定義が簡単な場合、自動的にビューを更新可能▪ 9.3 以前は更新可能なビューを作成するには
INSERT 、 UPDATE 、 DELETE に対するルールまたはトリガーを定義
2013/8/3中国 DB 勉強会
22
更新可能ビュー▪ FROM 句に 1 つのテーブルまたは更新可能ビューが設定さ
れている
▪ WITH, DISTINCT, GROUP BY, HAVING, LIMIT, OFFSET がトップレベルに含まれない
▪ UNION 、 INTERSECT 、 EXCEPT がトップレベルに含まれない
▪ 全てのコラムが単純な参照であること(表現、リテラル、関数でない)
▪ ビューの SELECT リストにコラムの重複が無い
▪ security_barrier プロパティが設定されていない
2013/8/3中国 DB 勉強会
23
更新可能ビューの例
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 VIEWyohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');INSERT 0 1yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');INSERT 0 1yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');INSERT 0 1yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');INSERT 0 1yohgaki@127 ~=# INSERT INTO my_table (txt) VALUES ('abc');INSERT 0 1
2013/8/3中国 DB 勉強会
24
更新可能ビューの例
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 msyohgaki@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 勉強会
25
更新可能ビューの例
yohgaki@127 ~=# INSERT INTO my_view (txt) VALUES ('xyz');INSERT 0 1時間 : 20.490 msyohgaki@127 ~=# INSERT INTO my_view (txt) VALUES ('xyz');INSERT 0 1時間 : 9.702 msyohgaki@127 ~=# INSERT INTO my_view (txt) VALUES ('xyz');INSERT 0 1
2013/8/3中国 DB 勉強会
26
更新可能ビューの例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 勉強会
27
更新可能ビューの例yohgaki@127 ~=# DELETE FROM my_view WHERE id = 7;DELETE 1yohgaki@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 5yohgaki@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 勉強会
28
ビューが更新可能かどうか
システムカタログをクエリーして判別
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 勉強会
29
再帰ビュー
yohgaki@127 ~=# CREATE VIEW fib_up_to_50 ASWITH RECURSIVEfib AS ( SELECT 0 AS a, 1 AS b UNION ALL SELECT b, a + b FROM fib WHERE b <= 50)SELECT a FROM fib;CREATE VIEWyohgaki@127 ~=# SELECT * FROM fib_up_to_50; a ---- 0 1 1 2 3 5 8 13 21 34
2013/8/3中国 DB 勉強会
30
WITH RECURSIVE のみでも可能
yohgaki@127 ~=# WITH RECURSIVEfib 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 勉強会
31
実用的な例
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_quantityFROM included_partsGROUP BY sub_part
2013/8/3中国 DB 勉強会
32
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 勉強会
33
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 勉強会
34
JSON サポート - 演算子
• 配列要素またはオブジェクトフィールドを取得する。
->
• 配列要素の値またはオブジェクトフィールドの値をテキストとして取得する
->>
• 指定されたパスの JSON オブジェクトを取得する
#>
• 指定されたパスの JSON オブジェクトをテキストとして取得する。
#>>
2013/8/3中国 DB 勉強会
35
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 msyohgaki@127 ~=# SELECT '{"a":1,"b":2}'::json->>'b';?column? ---------- 2(1 行 )
2013/8/3中国 DB 勉強会
36
JSON 用演算子の利用例
yohgaki@127 ~=# SELECT '{"a":[1,2,3],"b":[4,5,6]}'::json#>'{a,2}'; ?column? ---------- 3yohgaki@127 ~=# SELECT '{"a":[1,2,3],"b":[4,5,6]}'::json#>>'{a,2}'; ?column? ---------- 3(1 行 )
2013/8/3中国 DB 勉強会
37
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 勉強会
38
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 勉強会
39
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 勉強会
40
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 勉強会
41
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 勉強会
42
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 勉強会
43
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 勉強会
44
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 TYPEyohgaki@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 勉強会
45
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 勉強会
46
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 勉強会
47
JSON 関数とテーブル▪ JSON 関数は JSON 型を持つテーブルと一緒に利用すると
様々なデータ操作を行えるyohgaki@127 ~=# CREATE TABLE my_json(id SERIAL PRIMARY KEY, j JSON);時間 : 132.419 msyohgaki@127 ~=# INSERT INTO my_json (j) VALUES ('{"f1":1,"f2":true,"f3":"Foo"}');INSERT 0 1yohgaki@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 勉強会
48
JSON サポートの注意点▪ JSON 型は TEXT 型とほぼ同じ
▪ JSON 型のクエリは基本的に遅い▪ レコードを特定して操作するのは普通だが、 JSON 型のデータ
をキーとして検索すると遅い
▪ 検索にはインデックス(関数インデックス)
▪ TEXT 型とほぼ同じ、つまり GIN を使った高速化などのテクニックが利用可能
▪ 注意点はあるが Web 開発者にとってはうれしい機能!
2013/8/3中国 DB 勉強会
49
まとめ▪ PostgreSQL9.3 の特徴
▪ パフォーマンスではなく機能強化▪ ビュー機能の強化▪ レプリケーション機能の強化▪ JSON サポートの強化
▪ JSON サポート▪ PostgreSQL9.2 の JSON サポートは保存できるだけ
▪ PostgreSQL9.3 からはデータ操作が可能
2013/8/3中国 DB 勉強会
50
PROVE for PHP
2013/07/08岡山 Ruby 会議 2013 (C) Electronic Service Initiative, Ltd.
www.provephp.com