Postgre SQL 9.3 新機能

3,185 views

Published on

第一回 中国地方DB勉強会の資料

Postgre SQL 9.3 新機能

  1. 1. PostgreSQL 9.3 Yasuo Ohgaki / yohgaki@ohgaki.net / www.ohgaki.net
  2. 2. 自己紹介 ▪ 氏名:大垣靖男(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
  3. 3. PROVE for PHP 2013/07/08岡山Ruby会議2013 (C) Electronic Service Initiative, Ltd. 3 www.provephp.com
  4. 4. PostgreSQL 9.x 2013/8/3中国DB勉強会 4
  5. 5. PostgreSQL 9.x 2013/8/3中国DB勉強会 5
  6. 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勉強会 6
  7. 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勉強会 7
  8. 8. PostgreSQL 9.2未満? PostgreSQL 9.2にアップグレードする だけで高速化! アップグレードしないのは損! 2013/8/3中国DB勉強会 8
  9. 9. PostgreSQL 9.3 2013/8/3中国DB勉強会 9
  10. 10. 2013年秋 PostgreSQL 9.3 ▪ PostgreSQL 9.3がこの秋に正式リリース予定です。執筆時 点ではBeta2がリリースされています。今回は現時点でリ リースが確定している機能をご紹介します。 2013/8/3中国DB勉強会 10
  11. 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勉強会 11
  12. 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勉強会 12
  13. 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勉強会 13
  14. 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勉強会 14
  15. 15. その他の変更 • SysV共有メモリから変更 • http://www.postgresql.org/docs/9.3/static/kernel- resources.html#SYSVIPC • SQLite3 はMMAPに変更して数倍高速化されたが、PostgreSQLの場 合は変化なし POSIX共有メモリとMMAPの利用 2013/8/3中国DB勉強会 15
  16. 16. 追加機能紹介 ビューおよびJSON関連 2013/8/3中国DB勉強会 16
  17. 17. マテリアライズドビュー ▪ マテリアライズドビューとはテーブルのスナップショット のようなビュー ▪ データ更新は明示的に指定 ▪ 差分だけリフレッシュする機能が無く、リフレッシュには 排他ロックが必要な事に注意 • CREATE MATERIALIZED VIEW ビュー名 AS 条件; マテリアライズドビューの作成 • REFRESH MATERIALIZED VIEW ビュー名; マテリアライズドビューの更新 2013/8/3中国DB勉強会 17
  18. 18. マテリアライズドビューの例 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
  19. 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勉強会 19
  20. 20. マテリアライズドビューの例 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
  21. 21. 更新可能ビュー ▪ 商用データベースでは更新可能なビューをサポート ▪ 特にMS SQL Serverは古くから更新可能ビューをサポート ▪ PostgreSQL9.3からビュー定義が簡単な場合、自動的に ビューを更新可能 ▪ 9.3以前は更新可能なビューを作成するにはINSERT、UPDATE、 DELETEに対するルールまたはトリガーを定義 2013/8/3中国DB勉強会 21
  22. 22. 更新可能ビュー ▪ FROM句に1つのテーブルまたは更新可能ビューが設定され ている ▪ WITH, DISTINCT, GROUP BY, HAVING, LIMIT, OFFSETが トップレベルに含まれない ▪ UNION、INTERSECT、EXCEPTがトップレベルに含まれ ない ▪ 全てのコラムが単純な参照であること(表現、リテラル、 関数でない) ▪ ビューのSELECTリストにコラムの重複が無い ▪ security_barrierプロパティが設定されていない 2013/8/3中国DB勉強会 22
  23. 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 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
  24. 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 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
  25. 25. 更新可能ビューの例 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
  26. 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勉強会 26
  27. 27. 更新可能ビューの例 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
  28. 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勉強会 28
  29. 29. 再帰ビュー 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
  30. 30. 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
  31. 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_quantity FROM included_parts GROUP BY sub_part 2013/8/3中国DB勉強会 31
  32. 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勉強会 32
  33. 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勉強会 33
  34. 34. JSONサポート - 演算子 • 配列要素またはオブジェクトフィールドを取得する。 -> • 配列要素の値またはオブジェクトフィールドの値をテキストとし て取得する ->> • 指定されたパスのJSONオブジェクトを取得する #> • 指定されたパスのJSONオブジェクトをテキストとして取得する。 #>> 2013/8/3中国DB勉強会 34
  35. 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 ms yohgaki@127 ~=# SELECT '{"a":1,"b":2}'::json->>'b'; ?column? ---------- 2 (1 行) 2013/8/3中国DB勉強会 35
  36. 36. 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
  37. 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勉強会 37
  38. 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勉強会 38
  39. 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勉強会 39
  40. 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勉強会 40
  41. 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勉強会 41
  42. 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勉強会 42
  43. 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勉強会 43
  44. 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 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
  45. 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勉強会 45
  46. 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勉強会 46
  47. 47. 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
  48. 48. JSONサポートの注意点 ▪ JSON型はTEXT型とほぼ同じ ▪ JSON型のクエリは基本的に遅い ▪ レコードを特定して操作するのは普通だが、JSON型のデータを キーとして検索すると遅い ▪ 検索にはインデックス(関数インデックス) ▪ TEXT型とほぼ同じ、つまりGINを使った高速化などのテク ニックが利用可能 ▪ 注意点はあるがWeb開発者にとってはうれしい機能! 2013/8/3中国DB勉強会 48
  49. 49. まとめ ▪ PostgreSQL9.3の特徴 ▪ パフォーマンスではなく機能強化 ▪ ビュー機能の強化 ▪ レプリケーション機能の強化 ▪ JSONサポートの強化 ▪ JSONサポート ▪ PostgreSQL9.2のJSONサポートは保存できるだけ ▪ PostgreSQL9.3からはデータ操作が可能 2013/8/3中国DB勉強会 49
  50. 50. PROVE for PHP 2013/07/08岡山Ruby会議2013 (C) Electronic Service Initiative, Ltd. 50 www.provephp.com

×