SlideShare a Scribd company logo
1 of 161
Download to read offline
オープンソースカンファレンス
2015 Hokkaido(2015-06-13)
PostgreSQL で
非構造化データを使う
XML, hstore,
JSON, JSONB
ぬこ@横浜 (@nuko_yokohama)
2
自己紹介
SELECT '{
" 名前 ":" ぬこ@横浜 ",
" 住所 ":" 横浜市 ",
"Twitter":"@nuko_yokohama",
" 所属 ":{" 会社 ":" 某通信系ソフトウェア会社 ",
" 部署 ":" クラウドな感じ(仕事はクラウドじゃない) ",
" 勤務地 ":" ミナトミライ・スゴイトオイビル "},
" 仕事 ":"PostgreSQL あれこれ ",
" 趣味 ":[" 猫 "," スパ "," 原付旅 ","PostgreSQL"," ラーメン "],
" メモ ":["PostgreSQL は 7.4 の頃からの腐れ縁 ",
" ときどき PostgreSQL イベントで喋ってます ","PostgreSQL チョットデキル "],
" 作ったもの ":[" 漢数字型 (ksj)"," ゆるい文字型 (ntext)", "new4j_fdw",
"hit_and_blow BGW"]}'::jsonb;
3
自己紹介 ( こんなの作ってた )
SELECT data, data + ' 拾 ' FROM ksj_sample;
data | ?column?
------------+----------------
五百壱拾六 | 五百弐拾六
零 | 壱拾
参万壱百壱 | 参万壱百壱拾壱
(3 rows)
SELECT data, data * ' 拾 ' FROM ksj_sample;
data | ?column?
------------+--------------
五百壱拾六 | 五千壱百六拾
零 | 零
参万壱百壱 | 参拾壱千壱拾
(3 rows)
SELECT sum(data) FROM ksj_sample;
sum
----------------
参万六百壱拾七
(1 row)
SELECT * FROM ksj_sample ORDER BY data;
data
------------
零
五百壱拾六
参万壱百壱
(3 rows)
ksj (漢数字型)
漢数字で四則演算や
比較演算できる、誰得データ型
4
自己紹介 ( こんなの作ってた )
SELECT * FROM foo WHERE data = ' エバンゲリオン ';
id | data
----+------------
3 | エヴァンゲリヲン
(1 row)
SELECT * FROM foo WHERE data = ' センヌリティウス ';
id | data
----+------
(0 rows)
SELECT * FROM foo WHERE data /= ' センヌリティウス ';
id | data
----+------------------
4 | セリヌンティウス
(1 row)
ntext( ゆるい文字型 )
日本語正規化
ゆるい演算子 (/=)
類似度計算で typo を許容
5
自己紹介 ( こんなの作ってた )
CREATE FOREIGN TABLE bar3 (
my_name text,
my_gender text,
follower_name text,
follower_gender text)
SERVER foo
OPTIONS (query '{
"query":"START n=node(*)
MATCH p=fm<-[]-n<-[]-fm
RETURN n.name as my_name, n.gender as my_gender,
fm.name as follower_name, fm.gender as follower_gender" }');
SELECT my_name, my_gender, follower_name, follower_gender FROM bar3;
my_name | my_gender | follower_name | follower_gender
---------+-----------+---------------+-----------------
Akagi | Famale | Hiryu | Famale
Nagato | Male | Mutsu | Male
Mutsu | Male | Nagato | Male
Hiryu | Famale | Soryu | Famale
Hiryu | Famale | Akagi | Famale
Soryu | Famale | Hiryu | Famale
(6 rows)
new4j_fdw
グラフデータベース Neo4j を
わざわざ PostgreSQL 経由で
SQL 検索する誰得 FDW
neo4j_fdw
6
自己紹介 ( こんなの作ってた )
postgres=# LISTEN HB_CL;
LISTEN
postgres=# NOTIFY HB_SV,'xxxx';;
NOTIFY
Asynchronous notification "hb_cl" with payload "Invalid data.(xxxx)"
received from server process with PID 29520.
postgres=# NOTIFY HB_SV,'0123';;
NOTIFY
Asynchronous notification "hb_cl" with payload "2 Hit / 1 Blow."
received from server process with PID 29520.
postgres=# NOTIFY HB_SV,'0813';;
NOTIFY
Asynchronous notification "hb_cl" with payload "4 Hit! Conguratulatoins!, next new game."
received from server process with PID 29520.
postgres=#
hb_worker
psql などから数当てができる
Background Worker Process
7
自己紹介
PostgreSQL を
無駄に使うのが好き
8
アジェンダ
PostgreSQL と非構造化データ
XML
hstore
JSON/JSONB
PostgreSQL JSONB と MongoDB
JSONB 多めです
9
PostgreSQL と
非構造化データ
10
と、非構造化データの
お話をする前に
PostgreSQL の概要と歴史に
ついて簡単におさらいします
11
PostgreSQL の概要
MySQL と並ぶ OSS RDBMS
ライセンスは BSD ライクなもの
高度なクエリにも対応
性能面でも商用 DBMS とも遜色なし
9.0 以降はレプリケーションも対応
多種多様なデータ型サポート
非常に高い拡張性
活発な開発コミュニティ
12
PostgreSQL の歴史
POSTGRES
プロジェクト
の時代
Postgres95
の時代
※SQL サポート
PostgresSQL
の時代
※6.0 から開始
6.0 ~
発展途上の時代
GEQO
マルチバイト文字セット
MVCC
7.0 ~
やっと実用的に
WAL
TOAST
VACUUM 改善
8.0 ~
商用レベルへ
Windows 対応
PITR
自動 VACUUM
HOT
9.0 ~
エンタープライズ化
レプリケーション
外部表
メニーコア性能向上
マテリアライズドビュー
JSON 対応
PostgreSQLPostgreSQL のの
進化はこれからも続く…進化はこれからも続く…
1986 年
1995 年
1997 年
1997 年
2000 年
2005 年
2010 年
意外と古い?
13
PostgreSQL 9.4
そして
PostgreSQL 9.5
現在の最新版
現在、開発中
14
PostgreSQL 9.4
JSONB データ型
ALTER SYSTEM コマンド
マテリアライズド・ビューの改善
ロジカル・デコーディング
バックグラウンドワーカプロセスの動的操作
WAL バッファへの並列挿入
etc... 200 項目近くの改善 / 修正
最新版は 9.4.4
( 昨晩アナウンス )
15
PostgreSQL 9.5( 開発中 )
IMPORT FOREIGN SCHEMA
Row-Level Security Policies
BRIN Indexes(Block Range Index)
Foreign Table Inheritance
JSONB-modifying operators and functions
UPSERT(INSERT ... ON CONFLICT DO NOTHING/UPDATE)
Parallel VACUUMing
etc...
今後、変更される
可能性はあり
Release Notes も先日公開されました!
http://www.postgresql.org/docs/devel/static/release-9-5.html
16
非構造化データ?
17
構造化の観点から見た分類
あり
なし
完全
不完全
構造化データ構造化定義
半構造化データ
非構造化データ
構造の定義を持たない
構造の定義が完全ではない
完全に定義された構造を持つ
18
構造化の観点から見た分類
種別 内容 例
構造化データ 何らかの定義(スキーマ定義等)に
より、構造を事前に決定しておく
データ。
CREATE TABLE 文で
定義されたテーブル
半構造化データ 事前の定義はあるが、定義内の一部
の構造が存在しなくても良いデー
タ。
XML スキーマで定義さ
れた XML 文書
非構造化データ 事前の構造定義を持たないデータ。 任意の JSON 文書
通常、 RDBMS では上記の種別の
データのうち、構造化データを扱う。
19
PostgreSQL と非構造データ型
PostgreSQL で通常扱うのは、
「構造化データ」
さらに、それに加えて PostgreSQL では
「半構造化データ」「非構造化データ」
(以降、両方とも「非構造化データ」と
記述)を扱うしくみも用意されている。
20
PostgreSQL と非構造データ型
PostgreSQL で使用可能な、
非構造化データ型は以下の 4 種類
型名 対応バージョン 位置づけ 備考
XML 8.2 ~ 本体機能 libxml2 依存
hstore 8.3 ~ contrib
JSON 9.2 ~ 本体機能
JSONB 9.4 ~ 本体機能
21
XML 型
XML を格納するデータ型
本体機能 (configure で指定 )
格納時に XML パースを行なう
型自体に比較演算機能はない
xpath によるアクセスが可能
SQL 関数による XML 型構築
libxml2 ライブラリに依存
22
XML 型の処理イメージ
XML 文字列
XML パーサ
XML 型
(文字列)
XML 文字列
関数の結果
(そのまま出力)
格納時
取り出し時
xpath 関数
XML パーサ関数処理
xpath 処理
パーサではチェック
のみを行う
PostgreSQL
ストレージ
23
XML 型でできること
XML 文字列のパースと格納
xpath による結果の取り出し
SQL 関数による XML 型の構築
24
XML 型の使用例
XML 型カラムを持つテーブル
other=# d xml_t
Table "public.xml_t"
Column | Type | Modifiers
--------+---------+----------------------------------------------------
id | integer | not null default nextval('xml_t_id_seq'::regclass)
data | xml |
other=# SELECT data FROM xml_t;
<rdb_t><email>Laverna@junius.io</email><created_at>1987-08-
21T18:42:02.269Z</created_at><country>
Paraguay</country><id>0</id><full_name>Carolyne Kohler</full_name></rdb_t>
<rdb_t><email>Nakia_Rolfson@cecelia.ca</email><created_at>1989-03-
16T14:37:36.825Z</created_at><c
ountry>France</country><id>1</id><full_name>Paul Weber DVM</full_name></rdb_t>
<rdb_t><email>Elbert@norma.co.uk</email><created_at>1980-02-
19T04:16:52.113Z</created_at><country
>Uzbekistan</country><id>2</id><full_name>Florence Murphy</full_name></rdb_t>
(3 rows)
25
XML 型の使用例
xpath 関数による XML 文書からの抽出
other=# SELECT
(xpath('/rdb_t/email/text()', data)::text[])[1] as email,
(xpath('/rdb_t/full_name/text()', data)::text[])[1] as fullname
FROM xml_t;
email | fullname
--------------------------+-----------------
Laverna@junius.io | Carolyne Kohler
Nakia_Rolfson@cecelia.ca | Paul Weber DVM
Elbert@norma.co.uk | Florence Murphy
(3 rows)
XML や xpath 関数は強力だけど、書くのは少々面倒・・・
(例) xpath 関数は XML 配列を返却するので、テキストを取り出す場合に、 TEXT
配列にキャストして最初の要素を取り出すなどの操作が必要。
(例)名前空間 url と prefix の組を配列化して xpath 関数に渡す必要がある。
26
hstore 型
Key-Value store データ型
contrib モジュール
ネストはできない。
部分更新インタフェースあり
※ 作者は JSONB と同じ Oleg 氏
27
hstore 型の処理イメージ
hstore 文字列
hstore パーサ
hstore 型
(バイナリ)
hstore 文字列
関数の結果
文字列化
格納時
取り出し時
hstore 関数
関数処理 バイナリを直接解釈して
関数実行
パーサは動作しない
PostgreSQL
ストレージシリアライズ
28
hstore 型でできること
hstore 文字列のパースと格納
キーによる値の取り出し
キーと値のセットで追加 / 更新
指定キーのキー&値を削除
レコードからの生成
JSON への変換
GIN インデックス対応
29
hstore 型の使用例
hstore 型カラムを持つテーブル
other=# dx
List of installed extensions
Name | Version | Schema | Description
---------+---------+------------
+--------------------------------------------------
hstore | 1.3 | public | data type for storing sets of (key, value)
pairs
plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language
(2 rows)
other=# d hstore_t
Table "public.hstore_t"
Column | Type | Modifiers
--------+---------+-------------------------------------------------------
id | integer | not null default nextval('hstore_t_id_seq'::regclass)
data | hstore |
30
hstore 型の使用例
hstore 型カラムの検索
other=# SELECT data FROM hstore_t;
data
------------------------------------------------------------------------------
--------------------
--------------------------------------------
"id"=>"0", "email"=>"Laverna@junius.io", "country"=>"Paraguay",
"full_name"=>"Carolyne Kohler", "
created_at"=>"1987-08-21T18:42:02.269Z"
"id"=>"1", "email"=>"Nakia_Rolfson@cecelia.ca", "country"=>"France",
"full_name"=>"Paul Weber DVM
", "created_at"=>"1989-03-16T14:37:36.825Z"
"id"=>"2", "email"=>"Elbert@norma.co.uk", "country"=>"Uzbekistan",
"full_name"=>"Florence Murphy"
, "created_at"=>"1980-02-19T04:16:52.113Z"
(3 rows)
31
hstore 型の使用例
hstore 型カラムから特定のキーのみ抽出
other=# SELECT data->'email' as email, data->'full_name' as full_name FROM
hstore_t;
email | full_name
--------------------------+-----------------
Laverna@junius.io | Carolyne Kohler
Nakia_Rolfson@cecelia.ca | Paul Weber DVM
Elbert@norma.co.uk | Florence Murphy
(3 rows)
条件式を使う例
other=# SELECT data->'id' as id, data->'email' as email FROM hstore_t WHERE
data->'id' = '1';
id | email
----+--------------------------
1 | Nakia_Rolfson@cecelia.ca
(1 row)
XML 型 /xpath 関数を使うよりシンプルに書ける
32
hstore に関する補足
hstore については、 JPUG の「第 20 回
しくみ + アプリケーション勉強会 (2011
年 6 月 4 日 ) 」でも解説しているので、
そちらも参考にしてください ( 多少情報
は古いかもしれませんが…)。
http://www.postgresql.jp/wg/shikumi/sikumi_20/
http://www.postgresql.jp/wg/shikumi/study20_materials/hstore_int
roduction/view
33
JSON/JSONB
概説
34
JSON とは
JavaScript Object Notation
XML よりも軽量
構造化されたデータを
文字列で表現可能
35
PostgreSQL における
JSON への取り組み
9.2 から順調に進化。 9.5 でも…?
●JSON 型の導入。
●2 つの JSON 型構築関数。
●JSON 内の値を
使った条件検索は
できなかった。
●JSON 型関数・演算子の
大幅な強化。
●JSON データ型への
パスによるアクセス。
●JSON 内の値を使った
条件検索が可能に。
●JSONB 型の導入。
●検索の高速化
●独自演算子の追加
●GIN インデックス対応
9.2
9.3
9.4
36
JSON 型でできること
JSON 文字列のパース
キーによる値の取り出し
パスによる値の取り出し
PostgreSQL 配列や行との変換
etc ・・・
37
JSON 文字列のパース
PostgreSQL へのデータ格納時
に格納される JSON が正しい
書式かチェックする。
正しくない書式の場合
PostgreSQL がエラーにする。
38
JSON 文字列のパース例
正しい JSON 文字列
jsonb=# SELECT '{"key1":"value1", "key2":[100, 20, 5]}'::json;
json
----------------------------------------
{"key1":"value1", "key2":[100, 20, 5]}
(1 row)
誤った JSON 文字列
jsonb=# SELECT '{"key1":"value1", "key2":[100, 20, ]}'::json;
ERROR: invalid input syntax for type json
LINE 1: SELECT '{"key1":"value1", "key2":[100, 20, ]}'::json;
^
DETAIL: Expected JSON value, but found "]".
CONTEXT: JSON data, line 1: {"key1":"value1", "key2":[100, 20, ]...
※ パースは JSON/JSONB 型に変換されるときに行われる。
カンマの後に
値がない
39
キーによる値の取り出し
JSON 型に対してキーを指定し
て対応する値を取得する。
”->”, ”->>” 演算子など
40
キーによる値の取り出し
JSON 型全体を取得
jsonb=# pset null (null)Null display (null) is "(null)".
jsonb=# SELECT data FROM test ORDER BY id LIMIT 3;
data
---------------------------------------------------------------------------
-----
-------------------------------------------------------------
{"Id": 0, "Email": "Laverna@junius.io", "Country": "Paraguay", "Full
Name": "Ca
rolyne Kohler", "Created At": "1987-08-21T18:42:02.269Z"}
{"Id": 1, "Country": "France", "Full Name": "Paul Weber DVM", "Created
At": "19
89-03-16T14:37:36.825Z"}
{"Id": 2, "Email": "Elbert@norma.co.uk", "Country": "Uzbekistan", "Full
Name":
"Florence Murphy", "Created At": "1980-02-19T04:16:52.113Z"}
(3 rows)
41
キーによる値の取り出し
キーから JSON オブジェクトを取得
jsonb=# SELECT data->'Email' as email , data->'Full Name' as fullname FROM
test ORDER BY id LIMIT 3;
email | fullname
----------------------+-------------------
"Laverna@junius.io" | "Carolyne Kohler"
(null) | "Paul Weber DVM"
"Elbert@norma.co.uk" | "Florence Murphy"
(3 rows)
キーから文字列を取得
jsonb=# SELECT data->>'Email' as email , data->>'Full Name' as fullname
FROM test ORDER BY id LIMIT 3;
email | fullname
--------------------+-----------------
Laverna@junius.io | Carolyne Kohler
(null) | Paul Weber DVM
Elbert@norma.co.uk | Florence Murphy
(3 rows)
42
パスによる値の取り出し
JSON 型に対してパスを指定し
て対応する値を取得する。
“#>”, “#>>” 演算子
43
パスによる値の取り出し
person, name, first のパスで取得
jsonb=# SELECT '{"person":{"name":
{"first":"Tom","last":"Lane"},"age":59}}'::json #>> '{person, name,
first}';
?column?
----------
Tom
(1 row)
person
name
first last
age
Tom Lane
59
(root)
44
パスによる値の取り出し
Contributes の 2 番目 (0 相対 ) を取得
jsonb=# SELECT '{"Name":
{"First":"Oleg","Last":"Bartunov"},"Country":"Russia","Contributes":
["hstore","JSON","JSONB","GIN"]}'::json #>> '{Contributes,2}';
?column?
----------
JSONB
(1 row)
Contributes
name
first last
Oleg
hstore
(root)
JSON JSONB GIN
[0] [1] [2] [3]
Bartunov
45
式インデックスとの組合せ
キーやパスによって取り出した
値は式インデックスとしても
使用可能
⇒JSON 型を条件列として
インデックス検索も可能!
46
式インデックスとの組合せ
式インデックスの設定
jsonb=# SELECT data FROM json_t LIMIT 1;
data
---------------------------------------------------------------------------
-----
--------------------------------------------------------------------------
{ "Email": "Laverna@junius.io", "Created At": "1987-08-
21T18:42:02.269Z",
"Country": "Paraguay", "Id": 0, "Full Name": "Carolyne Kohler"}
(1 row)
jsonb=# CREATE INDEX json_id_idx ON json_t USING btree ((data->>'Id'));
CREATE INDEX
jsonb=# d json_t
Unlogged table "public.json_t"
Column | Type | Modifiers
--------+---------+-----------------------------------------------------
id | integer | not null default nextval('json_t_id_seq'::regclass)
data | json |
Indexes:
"json_id_idx" btree ((data ->> 'Id'::text))
47
式インデックスとの組合せ
式インデックスを利用した検索
jsonb=# EXPLAIN ANALYZE SELECT data FROM json_t WHERE data->>'Id' = '1000';
QUERY PLAN
---------------------------------------------------------------------------
-----
-------------------------------------
Bitmap Heap Scan on json_t (cost=4.68..130.11 rows=50 width=32) (actual
time=0
.078..0.078 rows=1 loops=1)
Recheck Cond: ((data ->> 'Id'::text) = '1000'::text)
Heap Blocks: exact=1
-> Bitmap Index Scan on json_id_idx (cost=0.00..4.66 rows=50 width=0)
(actual time=0.072..0.072 rows=1 loops=1)
Index Cond: ((data ->> 'Id'::text) = '1000'::text)
Planning time: 0.248 ms
Execution time: 0.106 ms
(7 rows)
48
その他の JSON 関数
PostgreSQL 配列と JSON 配列との変換
行から JSON への変換
JSON から PostgreSQL 行への展開
キー集合の取得
49
PostgreSQL 配列と JSON 配列との変換
jsonb=# SELECT array_to_json(ARRAY[1, 3.14, -1.2e3]);
array_to_json
----------------
[1,3.14,-1200]
(1 row)
jsonb=# TABLE bar;
id | n_datas | t_datas
----+------------------+------------------------
1 | {1.32,9.76,5.55} | {bdho,fjoal}
2 | {6.43,0.48} | {vbwdahoi,3dsai,cfjia}
3 | {} | {}
(3 rows)
jsonb=# SELECT array_to_json(bar.t_datas) FROM bar;
array_to_json
------------------------------
["bdho","fjoal"]
["vbwdahoi","3dsai","cfjia"]
[]
(3 rows)
PostgreSQL 配列を
JSON 配列に変換
テーブル内の特定の列を
JSON 化した例
50
行から JSON への変換
jsonb=# TABLE foo;
id | n_data | t_data
----+--------+----------
1 | 8.93 | 366fd4cf
2 | 5.23 | 3f0a243b
3 | (null) | (null)
(3 rows)
jsonb=# SELECT row_to_json(foo.*) FROM foo;
row_to_json
--------------------------------------------
{"id":1,"n_data":8.93,"t_data":"366fd4cf"}
{"id":2,"n_data":5.23,"t_data":"3f0a243b"}
{"id":3,"n_data":null,"t_data":null}
(3 rows)
カラム値が null の場合は
JSON の null に変換
テーブル全体を
JSON 化した例
51
JSON から PostgreSQL 行への展開
jsonb=# select * from json_each_text('{"id": 2, "age": 59, "name": {"last":
"Lane", "first": "Tom"}}');
key | value
------+----------------------------------
id | 2
age | 59
name | {"last": "Lane", "first": "Tom"}
(3 rows)
※ 内側のキー ("first", "last") と値は展開しない。
※ key, value という固定の列名として返却される。
※ key も value も TEXT 型として返却される。
52
キー集合の取得
jsonb=# TABLE test;
{"id": 1, "name": {"first": "Oleg"}, "distribute": ["GIN", "hstore",
"json", "jsonb"]}
{"id": 2, "age": 59, "name": {"last": "Lane", "first": "Tom"}}
{"id": 3, "name": {"nickname": "nuko"}, "distribute": ["ksj", "neo4jfdw"]}
jsonb=# SELECT DISTINCT jsonb_object_keys(data) FROM test;
distribute
age
id
name
以下のような JSONB を含む全レコードからキーを取得する。
jsonb_object_keys 関数の結果
※ 内側のキー ("first", "last") は取得できない点に注意!
※ 自分で Outer キーを指定して取得した JSONB に対して
  jsonb_object_keys を発行することは可能。
53
JSON と JSONB
54
JSON 型
格納形式は文字列
JSONB 型
格納形式は規定のバイナリ形式
データ型の導入
専用演算子の追加
55
JSON と JSONB の格納状態例
00001fb0 95 7b 22 61 61 61 22 20 3a 20 22 41 41 41 41 22 |.{"aaa" : "AAAA"|
00001fc0 2c 20 22 62 62 62 31 22 20 3a 20 7b 22 63 63 63 |, "bbb1" : {"ccc|
00001fd0 63 22 3a 20 22 43 43 43 43 31 22 7d 2c 20 22 62 |c": "CCCC1"}, "b|
00001fe0 62 62 32 22 20 3a 7b 22 63 63 63 63 22 20 3a 20 |bb2" :{"cccc" : |
00001ff0 22 43 43 43 43 32 22 7d 20 7d 00 00 00 00 00 00 |"CCCC2"} }......|
00001fa0 b5 03 00 00 20 03 00 00 80 04 00 00 00 04 00 00 |.... ...........|
00001fb0 00 04 00 00 00 16 00 00 50 18 00 00 50 61 61 61 |........P...Paaa|
00001fc0 62 62 62 31 62 62 62 32 41 41 41 41 00 01 00 00 |bbb1bbb2AAAA....|
00001fd0 20 04 00 00 80 05 00 00 00 63 63 63 63 43 43 43 | ........ccccCCC|
00001fe0 43 31 00 00 00 01 00 00 20 04 00 00 80 05 00 00 |C1...... .......|
00001ff0 00 63 63 63 63 43 43 43 43 32 00 00 00 00 00 00 |.ccccCCCC2......|
{"aaa" : "AAAA", "bbb1" : {"cccc": "CCCC1"}, "bbb2" :{"cccc" : "CCCC2"} }
入力 JSON 文字列
JSON 型の格納状態
JSONB 型の格納状態
入力文字列そのまま
バイナリ化された
データが格納される
PostgreSQL 9.4 で確認
56
バイナリ形式で
格納すると
何が嬉しいのか?
57
JSONB は格納効率を
優先はしていない
格納サイズに関しては
むしろ JSON より大きくなる
ケースもある。
58
JSONB の格納性能も
JSON と比較すると遅い。
・格納容量が大きい
・シリアライズ化処理
(性能検証結果は後述)
59
JSONB は検索効率を優先
JSON 関数を使ってキーによる
検索を行ったときに
JSON と比較して非常に高速
(性能検証結果は後述)
60
JSONB データ型
JSON 自体にはデータ型の概念がある。
PostgreSQL の JSONB 型もデータ型に一部対応している。
JSON 型 対応する PostgreSQL 型 備考
文字型 text エンコーディングの問題は注意。
なお、キーは文字型扱い。
数値型 numeric 浮動小数点型の NaN や Infinity の表記は
許容されない。
時刻型 (未対応) PostgreSQL では文字列扱い。
真偽値 boolean 小文字の true/false のみ許容。
(on/off とかもダメ )
null - 小文字 null のみ許容。
SQL NULL とは別概念。
61
JSONB は入力した
JSON 文字列は保持されない。
JSON は入力文字列を
そのまま保持する。
62
JSONB 入力結果が保持されない例
(数値型)
jsonb=# INSERT INTO jsonb_t VALUES
(1, '{"key":1, "value":100}'),
(2, '{"key":2, "value":100.0}'),
(3, '{"key":3, "value":1.00e2}'),
(4, '{"key":4, "value":1.000e2}')
;
INSERT 0 4
jsonb=# SELECT * FROM jsonb_t ;
id | data
----+----------------------------
1 | {"key": 1, "value": 100}
2 | {"key": 2, "value": 100.0}
3 | {"key": 3, "value": 100}
4 | {"key": 4, "value": 100.0}
(4 rows)
小数なしの
numeric として同値
小数点ありの
numeric として同値
指数表記でなくなる
63
JSON だと単に文字列として
格納されているだけなので、
入力形式そのままで出力される
jsonb=# INSERT INTO json_t VALUES
jsonb-# (1, '{"key":1, "value":100}'),
jsonb-# (2, '{"key":2, "value":100.0}'),
jsonb-# (3, '{"key":3, "value":1.00e2}'),
jsonb-# (4, '{"key":4, "value":1.000e2}')
jsonb-# ;
INSERT 0 4
jsonb=# SELECT * FROM json_t;
id | data
----+----------------------------
1 | {"key":1, "value":100}
2 | {"key":2, "value":100.0}
3 | {"key":3, "value":1.00e2}
4 | {"key":4, "value":1.000e2}
(4 rows)
64
JSONB 入力結果が保持されない例
(重複キー、キー名の順序)
jsonb=# SELECT
'{"key_z":99, "key_q": 20, "key_q" :25, "key_a" : 3}'::json,
'{"key_z":99, "key_q": 20, "key_q" :25, "key_a" : 3}'::jsonb;
-[ RECORD 1 ]----------------------------------------------
json | {"key_z":99, "key_q": 20, "key_q" :25, "key_a" : 3}
jsonb | {"key_a": 3, "key_q": 25, "key_z": 99}
jsonb=# SELECT
'{"key_x":[ 1, 400, 8888, 2, 99, 25, 3]}'::json,
'{"key_x":[ 1, 400, 8888, 2, 99, 25, 3]}'::jsonb ;
-[ RECORD 1 ]----------------------------------
json | {"key_x":[ 1, 400, 8888, 2, 99, 25, 3]}
jsonb | {"key_x": [1, 400, 8888, 2, 99, 25, 3]}
同一階層で重複したキーがある場合、後に記述したもののみ有効となる。
また、キー名でソートされている。
配列の場合、順序は保証される。 ”最初の key_q”:20 の
組み合わせはなくなる。
65
JSONB 入力結果が保持されない例
(空白の扱い)
jsonb=# SELECT
'{"key_z" : 99, "key q": 20, "key_a" : "aa aa"}'::json,
'{"key_z" : 99, "key q": 20, "key_a" : "aa aa"}'::jsonb;
-[ RECORD 1 ]--------------------------------------------------
json | {"key_z" : 99, "key q": 20, "key_a" : "aa aa"}
jsonb | {"key q": 20, "key_a": "aa aa", "key_z": 99}
キーまたは値でない JSON 文字列中の空白は、
JSONB では無視される。
また、 JSONB の検索結果として出力される JSON 文字列では
キーと値のセパレータである“ :” の後に 1 つ空白文字を入れる
という規則で文字列を生成している。
66
JSONB 専用演算子 (9.4)
演算子 意味
<@ 左辺の JSON が右辺のキー&値の組を含むかを
評価する。
@> 右辺の JSON が左辺のキー&値の組を含むかを
評価する。
? 左辺の JSON が右辺の(一つの)キーまたは要
素を含むかどうかを評価する。
|? 左辺の JSON が右辺のキーまたは要素を 1 つで
も含むかどうかを評価する。( ANY 評価)
&? 左辺の JSON が右辺のキーまたは要素を全て含
むかどうかを評価する。( ALL 評価)
67
JSONB 専用演算子 (9.5 追加 )
演算子 意味
|| 指定したキーが存在しなければ、キー&値の組
み合わせを追加し、存在すれば指定したキー&
値の組み合わせを置換する。
- 指定したキーと合致するキー&値の組み合わせ
を削除する。。
- 指定した番号の配列要素を削除する。
#- 指定したパスに合致するキー&値の組み合わ
せ、または配列要素を削除する。
文書の部分更新が可能に!
68
<@ 演算子と GIN
GIN インデックスとの
組み合わせで、お手軽な
インデックスの作成が可能
69
GIN インデックス
汎用転置インデックス
配列型での利用
全文検索等でも利用
※ これも JSONB と同じ開発チームで開発している。
http://www.sai.msu.su/~megera/wiki/Gin
70
<@ と GIN インデックス
JSONB カラム自体に GIN インデックスを設定
jsonb=# SELECT data FROM jsonb_t LIMIT 1;
data
------------------------------------------------------------------------------
--
----------------------------------------------------------
{"Id": 0, "Email": "Laverna@junius.io", "Country": "Paraguay", "Full Name":
"Ca
rolyne Kohler", "Created At": "1987-08-21T18:42:02.269Z"}
(1 row)
jsonb=# CREATE INDEX jsonb_idx ON jsonb_t USING gin (data jsonb_ops);
CREATE INDEX
jsonb=# d jsonb_t
Unlogged table "public.jsonb_t"
Column | Type | Modifiers
--------+---------+------------------------------------------------------
id | integer | not null default nextval('jsonb_t_id_seq'::regclass)
data | jsonb |
Indexes:
"jsonb_idx" gin (data)
JSONB 型用の
GIN インデックス
メソッドの指定
実は指定しなくても
後述の演算子は OK
71
この状態で @> 演算子(右辺にはキーと値の組み合わせ)
を使うと GIN インデックスによる効率的な検索が可能になる
JSONB カラムに <@ 演算子で条件を記述
jsonb=# EXPLAIN SELECT data->'Full Name' as fullname, data->'Country' as
country FROM jsonb_t WHERE data @> '{"Country" : "Monaco"}';
QUERY PLAN
--------------------------------------------------------------------------
Bitmap Heap Scan on jsonb_t (cost=20.08..54.18 rows=10 width=160)
Recheck Cond: (data @> '{"Country": "Monaco"}'::jsonb)
-> Bitmap Index Scan on jsonb_idx (cost=0.00..20.07 rows=10 width=0)
Index Cond: (data @> '{"Country": "Monaco"}'::jsonb)
Planning time: 0.074 ms
(5 rows)
<@ と GIN インデックス
72
JSONB カラムに <@ 演算子で条件を記述(検索結果)
jsonb=# SELECT data->'Full Name' as fullname, data->'Country' as country FROM
jsonb_t WHERE data @> '{"Country" : "Monaco"}';
fullname | country
--------------------------+----------
"Romaine Hickle" | "Monaco"
"Mr. Joana Huel" | "Monaco"
"Jeff Wilkinson" | "Monaco"
(以下略)
<@ と GIN インデックス
"Country” が "Monaco” の行だけ選択されている。
73
今までの JSON 型でも
"->“,“->>“ 演算子と
関数インデクスの組み合わせで
btree インデクスによる
インデクス検索は出来たが
@> + GIN の組み合わせは
キーが不定でも有効!
74
しかも、 PostgreSQL 9.4 で
は GIN インデックスのサイズ
縮小 / 性能改善も行われている
のでさらに効果的!
(参考: GIN インデックスの改善も
JSONB 型と同じメンバが実施している)
75
JSONB 型の実装
76
JSON 型と JSONB 型の処理
JSON 型と JSONB 型の
データ格納
データ取得
JSON 関数処理
の処理イメージを次ページ以降に示す。
77
JSON 型の処理イメージ
JSON 文字列
JSON ツリーJSON パーサ
JSON 型
(文字列)
JSON 文字列
関数の結果
(そのまま出力)
格納時
取り出し時
JSON 関数
JSON パーサ関数処理
JSON ツリー
パーサで生成した
JSON ツリーは
捨てられる
PostgreSQL
ストレージ
再度パースが
必要
78
JSONB 型の処理イメージ
JSON 文字列
JSON ツリーJSON パーサ
JSONB 型
(バイナリ)
JSON 文字列
関数の結果
文字列化
格納時
取り出し時
JSONB 関数
関数処理 バイナリを直接解釈して
関数実行
パーサは動作しない
PostgreSQL
ストレージシリアライズ
79
JSON ツリー
parseState=0
pstate
res
res
type=jbvObject val.object.nPairs=3
key
type=jbvString
pair[0]
val
type=jbvString
len=3 val
AAA
len=2 val
aa
key
type=jbvString
val
type=jbvString
pair[1]
key
type=jbvString
pair[2]
len=2 val
bb
・・・
上記の JSON 文字列をパースすると
以下のようなツリー構造が生成される
※ PostgreSQL 9.4-beta2 の場合
{"aa":"AAA","bb":"BBB","cc":"CCC"}
80
格納サイズ
さっき説明した JSON と JSONB の
処理内容から格納サイズを予想すると
以下のようになる。
格納サイズは JSON のほうが小さい?
( JSONB はツリー構造情報も保持)
81
以下のような JSON データ
{ "Email": "Laverna@junius.io", "Created At": "1987-08-
21T18:42:02.269Z", "Country": "Paraguay","Id":"0",
"Full Name": "Carolyne Kohler"}
測定内容
TEXT/JSON/JSONB カラムのみをもつテーブルを作成
上記 1 万件を 10 回 COPY した後の
テーブルサイズを pg_relation_size() で測定
82
格納サイズ
TEXT 型と JSON 型のサイズは同じ
JSONB は JSON 型と比較すると 7 %増加
PostgreSQL 9.4 で確認
TEXT 型 JSON 型 JSONB 型
0
2,000,000
4,000,000
6,000,000
8,000,000
10,000,000
12,000,000
14,000,000
16,000,000
18,000,000
20,000,000
18,366,464 18,366,464
19,587,072
10 万件ロード時のテーブルサイズ
83
インデックスサイズ
JSON 型のキーに対する
btree 関数インデックス
Vs
JSONB の GIN インデックス
さっきの JSON 型データの 5 種のキーに
対する btree インデックスの総サイズと
JSONB 型の GIN インデックスサイズを比較してみる。
84
各キーから値を取得する btree インデックス群を設定
インデックスサイズ
JSONB 列自体に GIN インデックスを設定
CREATE INDEX jsonb_id_idx ON jsonb_t
USING btree ((data->>'Id'));
CREATE INDEX jsonb_fullname_idx ON jsonb_t
USING btree ((data->>'Full Name'));
CREATE INDEX jsonb_email_idx ON jsonb_t
USING btree ((data->>'Email'));
CREATE INDEX jsonb_created_idx ON jsonb_t
USING btree ((data->>'Created At'));
CREATE INDEX jsonb_country_idx ON jsonb_t
USING btree ((data->>'Country'));
CREATE INDEX jsonb_data_idx ON jsonb_t USING gin (data jsonb_ops);
85
インデックスサイズ
全てのキーに btree インデックスを
設定するより GIN インデックスのほうが
インデックスサイズは大幅に小さくなる。
PostgreSQL 9.4 で確認
JSONB+btree JSONB+GIN
0
5,000,000
10,000,000
15,000,000
20,000,000
25,000,000
18,366,464
19,587,072
18,055,168
6,897,664
btee 式インデックスサイズと GINインデックスサイズ
pg_relation_size()
pg_indexes_size()
86
性能比較
さっき説明した JSON と JSONB の
処理内容から処理性能を予想すると
以下のようになる。
格納処理は JSON のほうが高速
単なる SELECT は JSON のほうが高速?
JSON 関数を使った場合は JSONB が高速
87
測定環境
PC:Let's note SX2(SSD)
OS:CentOS 6.3( メモリ 4GB)
PostgreSQL パラメータ
shared_buffers=128MB
checkpoint_segments=30
88
以下のような JSON データ
{ "Email": "Laverna@junius.io", "Created At": "1987-08-
21T18:42:02.269Z", "Country": "Paraguay", "Id": 0,
"Full Name": "Carolyne Kohler"}
測定内容
JSON/JSONB カラムをもつテーブルを UNLOGGED で作成
上記 1 万件を 10 回 COPY したときの平均性能
SELECT(10 万件 ) の平均性能
SELECT(10 万件 ) + JSON 演算子を使ったときの平均性能
btree vs GIN インデックス検索性能
89
COPY 処理時間
TEXT と JSON の差分が 10000 件分の JSON パース時間?
JSON と JSONB の差分が 10000 件文のシリアライズ時間?
GIN インデックスありの場合はかなり遅くなる。
PostgreSQL 9.4 で測定
TEXT JSON JSONB JSONB + GIN
0.00
50.00
100.00
150.00
200.00
250.00
300.00
23.67 31.00
74.68
269.80
COPY 平均処理時間 (10000 件:単位 ms)
90
JSON 関数なし JSON 関数あり
0
20
40
60
80
100
120
140
160
180
200
20.27
173.16
17.79
50.01
全件 SELECT 時間( 10 万件:単位 ms )
JSON 型
JSONB 型
SELECT 処理時間
単なる SELECT はほとんど差はない?
JSON 関数を使用した場合の性能差は明確。
PostgreSQL 9.4 で確認
91
btree vs GIN
EXPLAIN ANALYZE SELECT * FROM jsonb_t WHERE data->>'Country' = 'Monaco';
Bitmap Heap Scan on jsonb_t (cost=12.29..1240.26 rows=500 width=161) (actual
time=0.180..0.692 rows=310 loops=1)
Recheck Cond: ((data ->> 'Country'::text) = 'Monaco'::text)
Heap Blocks: exact=280
-> Bitmap Index Scan on jsonb_country_idx (cost=0.00..12.17 rows=500 width=0)
(actual time=0.112..0.112 rows=310 loops=1)
Index Cond: ((data ->> 'Country'::text) = 'Monaco'::text)
Planning time: 0.607 ms
Execution time: 0.767 ms
(7 rows)
EXPLAIN ANALYZE SELECT * FROM jsonb_t WHERE data @> '{"Country":"Monaco"}';
Bitmap Heap Scan on jsonb_t (cost=28.77..362.50 rows=100 width=161) (actual
time=1.709..2.502 rows=310 loops=1)
Recheck Cond: (data @> '{"Country": "Monaco"}'::jsonb)
Heap Blocks: exact=280
-> Bitmap Index Scan on jsonb_data_idx (cost=0.00..28.75 rows=100 width=0) (actual
time=1.630..1.630 rows=310 loops=1)
Index Cond: (data @> '{"Country": "Monaco"}'::jsonb)
Planning time: 0.086 ms
Execution time: 2.566 ms
(7 rows)
GIN インデックス使用時
btree 式インデックス使用時
GIN より btree 式インデックスのほうが若干速い
92
測定結果まとめ
格納: JSON が高速
SELECT :ほぼ同じ?
JSON 関数: JSONB が高速
GIN より btree 式インデックスが高速
93
格納効率優先なら JSON
検索効率優先なら JSONB
入力形式を保持するなら JSON
⇒ だいたいの場合、 JSONB で OK?
結局、 JSON と JSONB は
どう使い分けるのか?
94
XML, hstore, JSON/JSONB 比較
データ型 表現能力 格納サイズ 参照性能 更新性能
XML ◎ △ △ △
hstore △ ○ ◎ ◎
JSON ○ ○ ○ ◎
JSONB ○ ○ ◎ ○
XML は表現能力は高いが扱いにくい
hstore はシンプルだが速い
JSONB は良いとこ取り?
⇒ 用途で使い分け可能
95
pgbench で
各データタイプの
性能の傾向を確認
96
測定環境とモデル
Let's note SX4
VMWare + CentOS 7.0
PostgreSQL 9.5-devel
Scale Factor = 10
( accounts:100 万件)
カスタムクエリ機能を使用
ホントは
AWS EC2 の
いい感じの
インスタンスを
使いたかっけど
間に合わなかった
※ 各型に対応したカスタムクエリについては付録 1 を参照
97
ロード時間と
インデックス
作成時間
98
XML のロードとインデックス作成は遅い
JSON と hstore はやや速い
XML
hstore
JSON
JSONB
0.000 5000.000 10000.000 15000.000 20000.000 25000.000 30000.000
ロード時間およびインデックス作成時間
インデックス作成時間 (ms)
ロード時間 (ms)
ロード時間とインデックス作成時間
99
このモデルだとカラム数が少ないから
JSONB はやや冗長になるのかも
XML
hstore
JSON
JSONB
0 50000000 100000000 150000000 200000000 250000000
テーブルサイズ / インデックスサイズ
インデックスサイズ
テーブルサイズ
テーブルサイズとインデックスサイズ
100
全件更新の性能も XML は非常に悪い
hstore はかなり速い
JSONB-9.5 部分更新の効果も見える
XML
hstore
JSON
JSONB
JSONB-9.5
0 10000 20000 30000 40000 50000 60000 70000 80000
76042
5292
12508
12241
8829
100 万件更新時間 (ms)
accounts(100 万件)全件更新時間
101
pgbench 走行
トランザクション内容
・ UPDATE 3 回
・ SELECT 1 回
・ INSERT 1 回
同時接続数 =2
走行時間 =300 秒
102
XML は非常に遅い
hstore は速い
JSON/JSONB はこのモデルだとあまり差はない。
XML
hstore
JSON
JSONB
JSONB-9.5
通常レコード
0 200 400 600 800 1000 1200 1400 1600 1800 2000
467.436
1360.219
1066.437
1149.694
1103.781
1708.898
pgbench スループット (tps)
pgbench 走行 スループット
103
参照も XML は遅い
hstore は速い
このモデルだと思ったより JSON/JSONB の差がない?
UPDATE accounts
SELECT accounts
UPDATE tellers
UPDATE branches
INSERT history
END
0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2
pgbench レイテンシ (ms)
XML
hstore
JSON
JSONB
JSONB-9.5
通常レコード
pgbench 走行 レイテンシ
104
JSON 型の
想定用途
105
様々なログの収集
( fluentd との組み合わせ等)
JSON 化
ログ
ログ
ログ
JSONB カラムに格納
GIN/btree インデックス設定
ログ検索
アプリケーション
syslog 等
ログ
既存の表JSONB 表
106
微妙なテーブル設計の救済?
CREATE TABLE foo {
id integer primary key,
name text,
・・・
memo1 text,
memo2 text,
memo3 text,
・・・
memo100 text
}
CREATE TABLE foo {
id integer primary key,
name text,
・・・
memo jsonb
}
可変の個数
設定されるような
予備カラム群
JSONB 型に
まとめてしまう
※ きちんと設計をしていれば不要だろうけど・・・
107
MongoDB 等の
NoSQL ドキュメント
DB の代替?
or
108
PostgreSQL JSONB
と
MongoDB との比較
と、いうことで
109
ドキュメント指向 DB として
比較した
MongoDB と
PostgreSQL との違い
110
データ管理単位
CRUD 操作
高度な検索
性能
レプリケーション
シャーディング
111
データ管理単位
PostgreSQL MongoDB
データベースクラスタ ( --dbpath 指定フォルダ)
データベース データベース
スキーマ (対応なし)
テーブル コレクション
レコード 文書
他の NoSQL 系に比べると、
RDBMS に比較的近い印象あり。
112
CRUD 操作
操作 PostgreSQL MongoDB
挿入 ○ ○
読み込み ○ ○
更新(全体) ○ ○
更新(部分) ✗( ~ 9.4) ○
UPSERT ✗( ~ 9.4) ○
削除 ○ ○
部分更新の有無がポイント
⇒ 逆に言えば更新がなければ差異はない
113
挿入
PostgreSQL の場合
MongoDB の場合
INSERT INTO テーブル名 VALUES ( JSON 文字列 )
db. コレクション名 .insert( JSON 文字列 )
114
読み込み
PostgreSQL の場合
MongoDB の場合
SELECT JSONB 列 FROM テーブル名 [WHERE 条件式 ]
db. コレクション名 .find([ 条件式 ])
->>' キー名 ' 演算子 値
@> ' キー名 : 値 '
115
更新(全体)
PostgreSQL の場合
MongoDB の場合
UPDATE テーブル名 SET ( JSON 文字列 )
db. コレクション名 .update( 条件式 ,JSON 文字列 )
116
更新(部分)
PostgreSQL の場合 (9.5 以降 )
UPDATE テーブル名 SET 値 = 値 || '( 追加するキーと値 )'
UPDATE テーブル名 SET 値 = 値 || '( 追加するキーと値 )'
UPDATE テーブル名 SET 値 = 値 - '( 削除するキー名 )'
キー追加
キー更新
キー削除
117
更新(部分)
MongoDB の場合
db. コレクション名 .update( 条件式 , {$set:{ キー : 値 }})
db. コレクション名 .update( 条件式 , {$set:{ キー : 値 }})
db. コレクション名 .update( 条件式 , {$unset:{ キー : 値 }}
キー追加
キー更新
キー削除
118
削除
PostgreSQL の場合
MongoDB の場合
DELETE テーブル名 [ 条件式 ]
あるいは
TRUNCATE TABLE テーブル名
db. コレクション名 .remove( 条件式 )
119
高度な検索
操作 PostgreSQL MongoDB
ソート ○ ○
重複排除 ○ ○
グルーピング ○ ○
集約演算 ○ ○
PostgreSQL の場合は SQL で上記を実現
MongoDB は MapReduce や
Aggregation-Framework で実現
120
レプリケーション
機能 PostgreSQL MongoDB
レプリケーション
方式
本体機能
マスタースレーブ
本体機能
マスタースレーブ
同期方式 同期 / 非同期 非同期
フェールオーバ機構 他クラスタ製品
・ pgpool-II
・ Pacemaker
本体機能
121
シャーディング
機能 PostgreSQL MongoDB
シャーディング
方式
本体機能にはない。
他製品でカバー。
(pgpool-II,pg_shard 等 )
今後は、外部表継承による
シャーディング相当が可能に
なるかも!? (9.5 だとまだ
JSONB への適用は難しい )
本体機能
クライアントドライバ
レプリケーション / シャーディングに関しては、
最初からそれを前提として開発されている
MongoDB のほうが扱いやすいのかも?
122
性能
YCSB ベンチマークを用いて
PostgreSQL JSONB と
MongoDB の性能を比較してみた
用途が異なるものを同じベンチマークで
測定する意味はあるのか、というツッコミは
あるかと思いますが、参考までに測定しました。
※ JSONB 対応 YCSB については付録 2 を参照
123
YCSB 測定
AWS EC2(m3.2xlarge on-demand)
CPU 数 8 、メモリ 30GB
PostgreSQL 9.4.1 (yum)
PostgreSQL の環境設定は checkpoint_segments=30
に変更したくらい。
MongoDB 3.0.2 (yum)
MongoDB は特に設定なし。
124
YCSB 測定
測定内容
ロード (load)⇒10 万件
更新と参照 (workload-a )
参照のみ( workload-c )
⇒ それぞれ 10 万回実行
125
YCSB 測定
ロード処理
0 5 10 15 20 25
0
2000
4000
6000
8000
10000
12000
14000
16000
YCSB load Throughput
PostgreSQL 9.4
MongoDB 3.0
number of concurrency
Throughput(ops/sec)
126
YCSB 測定
更新と参照
0 5 10 15 20 25
0
5000
10000
15000
20000
25000
YCSB load Workload-a Throughput
PostgreSQL 9.4
MongoDB 3.0
number of concurrency
Throughput(ops/sec)
10000(opt/sec)
程度になるはず?
127
YCSB 測定
参照のみ
0 5 10 15 20 25
0
10000
20000
30000
40000
50000
60000
YCSB workload-c Throughput
PostgreSQL 9.4
MongoDB 3.0
number of concurrency
Throughput(ops/sec)
128
YCSB 測定
まとめ
PostgreSQL は CPU 数があれば同時実行
数が多い場合にスループット向上。
MongoDB は CPU 数が多いマシンで動か
しても同時実行性能は上がらない。
⇒ その代わりシャードで書き込み分散?
129
MongoDB との比較
(まとめ)
130
PostgreSQL と NoSQL
DBMS 得意 不得意
PostgreSQL スケールアップ
SQL との連携 ( 結
合など )
トランザクション
スケールアウト
集計処理
MongoDB スケールアウト
書き込み並列化
集計処理?
スケールアップ
トランザクション
結合
それぞれ向き不向きがある
131
サーバ構成 / スペック次第?
コア数が多いサーバが用意できるなら
PostgreSQL を MongoDB の代わりに
使うという解もあり?
ほどほどのスペックのマシンを多数用意
できるなら MongoDB ?
132
PostgreSQL(+JSONB) の強み
既存の PostgreSQL 環境に
新たに JSONB 型を追加することで
SQL レベルで統一して扱えるのは強み。
PostgreSQL + MongoDB 構成を
PostgreSQL のみの構成にできるかも?
133
まとめ
134
PostgreSQL は非構造化データを
扱う手段がいくつかある。
XML/hstore/JSON/JSONB の
どれを使うかは要件次第
要件によっては、 JSON 文書格納先として
MongoDB 等の NoSQL ではなく、
PostgreSQL を使うのもありうる。
135
ご清聴
ありがとう
ございました
136
FAQ
137
Q. JSONB って日本語扱える?
A. キーにも値にも日本語は使えます。
ただし、サーバエンコーディングが
UTF-8 環境で使うのが無難そう。
日本語キーのパスを使って日本語を取得する例
jsonb=# SELECT '{" 種別 ":" ラーメン ", " 値段 " : 650, " スープ ":" 豚骨醤油 ", "
トッピング ":[" チャーシュー "," ほうれん草 "," 海苔 "," 葱 "]}'::jsonb #> '{ トッピ
ング , 2}';
?column?
----------
" 海苔 "
(1 row)
138
Q. JSONB ってトランザクションに対応
しているの?
A. してます。 JSONB も PostgreSQL 上
では他のデータ型と一緒の扱いです。
139
Q. PostgreSQL の
クライアントライブラリでは JSONB を
オブジェクトとして扱えるの?
A. すいません、きちんと調べてません。
少なくとも libpq としては特別な扱いは
してないみたいです。
140
Q. 結局、どういうときに
JSONB 型を使えばいいの?
A. 開発時にスキーマが決定できない情報
を管理する場合。
( XML や hstore も検討してみる)
あるいは、外部データとして JSON を
使っていて、それを PostgreSQL で管理
したい場合とか・・・?
141
Q. JSON データ管理なら
MongoDB とかじゃダメなの?
A. それも一つの選択肢です。
スケールアウト重視なら MongoDB 。
スタートアップ開発にも向いている。
トランザクションなど堅牢性の重視や
SQL アクセスしたいなら PostgreSQL 。
142
参考情報
●“PostgreSQL 9.4 Documentation”
http://www.postgresql.org/docs/9.4/static/index.html
●“Schema-less PostgreSQL”
http://www.sraoss.co.jp/event_seminar/2014/20140911_pg94_schemales
s.pdf
●SRA OSS. “PostgreSQL 9.4 評価検証報告”
http://www.sraoss.co.jp/event_seminar/2014/20140911_pg94report.pdf
●第 20 回しくみ+アプリケーション勉強会
"PostgreSQL の KVS hstore の紹介”
http://www.postgresql.jp/wg/shikumi/study20_materials/hstore_introduct
ion/view
●EDB 社ブログ “ Open Enterprise: The PostgreSQL Open Source Database
Blog from EnterpriseDB”
http://blogs.enterprisedb.com/2014/09/24/postgres-outperforms-mongodb
-and-ushers-in-new-developer-reality/
●”7 つのデータベース 7 つの世界”
ISBN 978-274-06907-6
143
付録
付録 1 pgbench モデル用クエリ
付録 2 YCSB JSONB 用クエリ
144
付録 1
pgbench モデル用
カスタムクエリ
145
各データ型を使って
pgbench_accounts
pgbench_branches
pgbench_tellers
pgbench_history
を 1 カラムで表現する
146
pgbench モデルのテーブル
bench=# d pgbench_accounts;
Table "public.pgbench_accounts"
Column | Type | Modifiers
----------+---------------+-----------
aid | integer | not null
bid | integer |
abalance | integer |
filler | character(84) |
Indexes:
"pgbench_accounts_pkey" PRIMARY KEY, btree (aid)
通常の pgbench モデル
XML モデル
bench_xml=# d accounts
Table "public.accounts"
Column | Type | Modifiers
--------+------+-----------
data | xml |
Indexes:
"xml_aid_idx" btree
(((xpath('/accounts/aid/text()'::text, data)::text[])[1]::integer))
147
pgbench モデルのテーブル
bench_hstore=# d accounts
Table "public.accounts"
Column | Type | Modifiers
--------+--------+-----------
data | hstore |
Indexes:
"hstore_aid_idx" btree (((data -> 'aid'::text)::integer))
hstore モデル
JSONB モデル
bench_json=# d accounts
Table "public.accounts"
Column | Type | Modifiers
--------+------+-----------
data | json |
Indexes:
"json_aid_idx" btree (((data ->> 'aid'::text)::integer))
JSON モデル
( JSON モデルとだいたいおなじ)
今回は GIN インデックスパターンは
使いません
148
pgbench モデルのクエリ
BEGIN;
UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
INSERT INTO pgbench_history (tid, bid, aid, delta, mtime)
VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
END;
通常の pgbench モデル(抜粋)
149
pgbench モデルのクエリ
UPDATE accounts SET data =
xmlelement(name accounts, null,
xmlelement(name aid, null,
((xpath('/accounts/aid/text()', data))::text[])[1]),
xmlelement(name bid, null,
((xpath('/accounts/bid/text()', data))::text[])[1]),
xmlelement(name abalance, null,
(((xpath('/accounts/abalance/text()', data))::text[])[1])::int + :delta ),
xmlelement(name filler, null,
((xpath('/accounts/filler/text()', data))::text[])[1]))
WHERE (xpath('/accounts/aid/text()', data)::text[])[1]::int = :aid;
SELECT ((xpath('/accounts/abalance/text()', data))::text[])[1]::int FROM accounts
WHERE ((xpath('/accounts/aid/text()', data))::text[])[1]::int = :aid;
INSERT INTO history (data) VALUES (
xmlelement(name history, null,
xmlelement(name tid, null, :tid),
xmlelement(name bid, null, :bid),
xmlelement(name aid, null, :aid),
xmlelement(name delta, null, :delta),
xmlelement(name mtime, null, CURRENT_TIMESTAMP),
xmlelement(name filler, null, ' ')
));
XML の pgbench モデル(抜粋)
150
pgbench モデルのクエリ
UPDATE accounts SET data =
data || hstore('abalance', ((data->'abalance')::int + :delta)::text )
WHERE (data->'aid')::int = :aid;
SELECT data->'abalance' FROM accounts WHERE (data->'aid')::int = :aid;
INSERT INTO history (data) VALUES (
hstore(
ARRAY['tid','bid','aid','delta','mtime', 'filler'],
ARRAY[ ( :tid )::text, ( :bid )::text, ( :aid )::text, ( :delta )::text,
CURRENT_TIMESTAMP::text, ' '])
);
hstore の pgbench モデル(抜粋)
151
pgbench モデルのクエリ
UPDATE accounts SET data =
json_build_object(
'aid', (data->>'aid')::int,
'bid', (data->>'bid')::int,
'abalance', (data->>'abalance')::int + :delta ,
'filler', data->>'filler')
WHERE (data->>'aid')::int = :aid;
SELECT data->>'abalance' FROM accounts WHERE (data->>'aid')::int = :aid;
INSERT INTO history (data) VALUES (
json_build_object(
'tid', :tid,
'bid', :bid,
'aid', :aid,
'delta', :delta,
'mtime', CURRENT_TIMESTAMP,
'filler', ' '));
JSON の pgbench モデル(抜粋)
152
pgbench モデルのクエリ
UPDATE accounts SET data =
json_build_object(
'aid', (data->>'aid')::int,
'bid', (data->>'bid')::int,
'abalance', (data->>'abalance')::int + :delta ,
'filler', data->>'filler')::jsonb
WHERE (data->>'aid')::int = :aid;
SELECT data->>'abalance' FROM accounts WHERE (data->>'aid')::int = :aid;
INSERT INTO history (data) VALUES (
json_build_object('tid', :tid,
'bid', :bid,
'aid', :aid,
'delta', :delta,
'mtime', CURRENT_TIMESTAMP,
'filler', ' ')::jsonb);
JSONB の pgbench モデル(抜粋)
153
pgbench モデルのクエリ
UPDATE accounts SET data = data ||
jsonb_build_object('abalance', (data->>'abalance')::int + :delta)
WHERE (data->>'aid')::int = :aid;
SELECT data->>'abalance' FROM accounts WHERE (data->>'aid')::int = :aid;
INSERT INTO history (data) VALUES (
jsonb_build_object(
'tid', :tid,
' bid', :bid, 'aid', :aid,
'delta', :delta,
'mtime', CURRENT_TIMESTAMP,
'filler', ' '));
JSONB(9.5) の pgbench モデル(抜粋)
PostgreSQL 9.5 では hstore 型と似たような
部分更新の演算子 ( || ) が追加された!
(あと jsonb_build_object が追加されたっぽい)
154
付録 2
YCSB JSONB
モデル用クエリ
155
YCSB とは
Yahoo! Cloud Service
Benchmark の略
いろんな NoSQL 系に
対応したベンチマーク
https://github.com/brianfrankcooper/YCSB
156
YCSB JSONB 対応版
改造方針
YCSB JSONB 版はないので
JDBC 版の SQL を JSONB を
使うモデルに合わせて修正
157
YCSB JSONB 対応版
JDBC 版テーブル定義
CREATE TABLE usertable (ycsb_key text, field1 text, field2 text,
field3 text, field4 text, field5 text, field6 text, field7 text,
field8 text, field9 text, field10 text);
CREATE INDEX ycsb_key_idx ON usertable (ycsb_key);
JSONB 版テーブル定義
CREATE TABLE usertable(data jsonb);
CREATE INDEX ycsb_pk_idx ON usertable USING btree ((data-
>'YCSB_KEY'));
158
YCSB JSONB 対応版
JDBC 版挿入 SQL
INSERT INTO usertable
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
JSONB 版挿入 SQL
INSERT INTO usertable VALUES(json_build_object('YCSB_KEY', ?,
'FIELD1', ?, 'FIELD2', ?, 'FIELD3', ?, 'FIELD4', ?, 'FIELD5', ?,
'FIELD6', ?, 'FIELD7', ?, 'FIELD8', ?, 'FIELD9', ?,
'FIILD10', ?)::jsonb)
9.5-devel だと
jsonb_build_object() が
あるので、 JSONB への
キャストは不要
159
YCSB JSONB 対応版
JDBC 版更新 SQL
UPDATE usertable SET FIELD1 = ?
WHERE YCSB_KEY = ?
JSONB 版更新 SQL
UPDATE usertable SET data = json_build_object('YCSB_KEY', data-
>>'YCSB_KEY', 'FIELD1', ?, 'FIELD2', data->>'FIELD2', 'FIELD3',
data->>'FIELD03', 'FIELD4', data->>'FIELD4', 'FIELD5', data-
>>'FIELD5', 'FIELD6', data->>'FIELD6', 'FIELD7', data->>'FIELD7',
'FIELD8', data->>'FIELD8', 'FIELD9', data->>'FIELD9', 'FIELD10',
data->>'FIELD10')::jsonb
WHERE data->>'YCSB_KEY' = ?
見ただけで
うんざりしますよね。
160
YCSB JSONB 対応版
JDBC 版更新 SQL
UPDATE usertable SET FIELD1 = ?
WHERE YCSB_KEY = ?
PostgreSQL 9.5 JSONB 版更新 SQL
UPDATE usertable SET data = data || jsonb_build_object('FIELD1', ?)
WHERE data->>'YCSB_KEY' = ?
まだ試してないけど
9.4 版と比べると
非常にスッキリ書けるはず
参考
9.5-devel だと
jsonb_build_object() が
あるので、 JSONB への
キャストは不要になる
161
YCSB JSONB 対応版
JDBC 版参照 SQL
SELECT * FROM usertable
WHERE YCSB_KEY = ?
JSONB 版参照 SQL
SELECT * FROM usertable
WHERE data->>'YCSB_KEY' = ?

More Related Content

What's hot

Postgre sql9.3 newlockmode_and_etc
Postgre sql9.3 newlockmode_and_etcPostgre sql9.3 newlockmode_and_etc
Postgre sql9.3 newlockmode_and_etckasaharatt
 
MySQLメインの人がPostgreSQLのベンチマークをしてみた話
MySQLメインの人がPostgreSQLのベンチマークをしてみた話MySQLメインの人がPostgreSQLのベンチマークをしてみた話
MySQLメインの人がPostgreSQLのベンチマークをしてみた話hiroi10
 
PostgreSQLではじめるOSS開発@OSC 2014 Hiroshima
PostgreSQLではじめるOSS開発@OSC 2014 HiroshimaPostgreSQLではじめるOSS開発@OSC 2014 Hiroshima
PostgreSQLではじめるOSS開発@OSC 2014 HiroshimaShigeru Hanada
 
OSC沖縄2014_JPUG資料
OSC沖縄2014_JPUG資料OSC沖縄2014_JPUG資料
OSC沖縄2014_JPUG資料kasaharatt
 
「今そこにある危機」を捉える ~ pg_stat_statements revisited
「今そこにある危機」を捉える ~ pg_stat_statements revisited「今そこにある危機」を捉える ~ pg_stat_statements revisited
「今そこにある危機」を捉える ~ pg_stat_statements revisitedUptime Technologies LLC (JP)
 
PostgreSQLアーキテクチャ入門(PostgreSQL Conference 2012)
PostgreSQLアーキテクチャ入門(PostgreSQL Conference 2012)PostgreSQLアーキテクチャ入門(PostgreSQL Conference 2012)
PostgreSQLアーキテクチャ入門(PostgreSQL Conference 2012)Uptime Technologies LLC (JP)
 
OSS-DB Gold技術解説セミナー@db tech showcase 東京 2014
OSS-DB Gold技術解説セミナー@db tech showcase 東京 2014OSS-DB Gold技術解説セミナー@db tech showcase 東京 2014
OSS-DB Gold技術解説セミナー@db tech showcase 東京 2014Shigeru Hanada
 
Hackers Champloo 2016 postgresql-9.6
Hackers Champloo 2016 postgresql-9.6Hackers Champloo 2016 postgresql-9.6
Hackers Champloo 2016 postgresql-9.6Toshi Harada
 
新しくなったPg monzでpostgre sqlのクラスタを監視しよう
新しくなったPg monzでpostgre sqlのクラスタを監視しよう新しくなったPg monzでpostgre sqlのクラスタを監視しよう
新しくなったPg monzでpostgre sqlのクラスタを監視しようYoshinori Nakanishi
 
PostgreSQL 9.2 新機能 - 新潟オープンソースセミナー2012
PostgreSQL 9.2 新機能 - 新潟オープンソースセミナー2012PostgreSQL 9.2 新機能 - 新潟オープンソースセミナー2012
PostgreSQL 9.2 新機能 - 新潟オープンソースセミナー2012Shigeru Hanada
 
JPUG 沖縄支部セミナー資料(2013-04-27)
JPUG 沖縄支部セミナー資料(2013-04-27)JPUG 沖縄支部セミナー資料(2013-04-27)
JPUG 沖縄支部セミナー資料(2013-04-27)Chika SATO
 
Jpug study-pq 20170121
Jpug study-pq 20170121Jpug study-pq 20170121
Jpug study-pq 20170121Kosuke Kida
 
PostgreSQL 9.6 新機能紹介
PostgreSQL 9.6 新機能紹介PostgreSQL 9.6 新機能紹介
PostgreSQL 9.6 新機能紹介Masahiko Sawada
 
5ステップで始めるPostgreSQLレプリケーション@hbstudy#13
5ステップで始めるPostgreSQLレプリケーション@hbstudy#135ステップで始めるPostgreSQLレプリケーション@hbstudy#13
5ステップで始めるPostgreSQLレプリケーション@hbstudy#13Uptime Technologies LLC (JP)
 
PostgreSQL 9.2 新機能 - OSC 2012 Kansai@Kyoto
PostgreSQL 9.2 新機能 - OSC 2012 Kansai@KyotoPostgreSQL 9.2 新機能 - OSC 2012 Kansai@Kyoto
PostgreSQL 9.2 新機能 - OSC 2012 Kansai@KyotoShigeru Hanada
 

What's hot (20)

PostgreSQLアーキテクチャ入門
PostgreSQLアーキテクチャ入門PostgreSQLアーキテクチャ入門
PostgreSQLアーキテクチャ入門
 
Postgre sql9.3 newlockmode_and_etc
Postgre sql9.3 newlockmode_and_etcPostgre sql9.3 newlockmode_and_etc
Postgre sql9.3 newlockmode_and_etc
 
MySQLメインの人がPostgreSQLのベンチマークをしてみた話
MySQLメインの人がPostgreSQLのベンチマークをしてみた話MySQLメインの人がPostgreSQLのベンチマークをしてみた話
MySQLメインの人がPostgreSQLのベンチマークをしてみた話
 
PostgreSQLバックアップの基本
PostgreSQLバックアップの基本PostgreSQLバックアップの基本
PostgreSQLバックアップの基本
 
PostgreSQLではじめるOSS開発@OSC 2014 Hiroshima
PostgreSQLではじめるOSS開発@OSC 2014 HiroshimaPostgreSQLではじめるOSS開発@OSC 2014 Hiroshima
PostgreSQLではじめるOSS開発@OSC 2014 Hiroshima
 
PostgreSQL安定運用のコツ2009 @hbstudy#5
PostgreSQL安定運用のコツ2009 @hbstudy#5PostgreSQL安定運用のコツ2009 @hbstudy#5
PostgreSQL安定運用のコツ2009 @hbstudy#5
 
OSC沖縄2014_JPUG資料
OSC沖縄2014_JPUG資料OSC沖縄2014_JPUG資料
OSC沖縄2014_JPUG資料
 
「今そこにある危機」を捉える ~ pg_stat_statements revisited
「今そこにある危機」を捉える ~ pg_stat_statements revisited「今そこにある危機」を捉える ~ pg_stat_statements revisited
「今そこにある危機」を捉える ~ pg_stat_statements revisited
 
PostgreSQLアーキテクチャ入門(PostgreSQL Conference 2012)
PostgreSQLアーキテクチャ入門(PostgreSQL Conference 2012)PostgreSQLアーキテクチャ入門(PostgreSQL Conference 2012)
PostgreSQLアーキテクチャ入門(PostgreSQL Conference 2012)
 
OSS-DB Gold技術解説セミナー@db tech showcase 東京 2014
OSS-DB Gold技術解説セミナー@db tech showcase 東京 2014OSS-DB Gold技術解説セミナー@db tech showcase 東京 2014
OSS-DB Gold技術解説セミナー@db tech showcase 東京 2014
 
Hackers Champloo 2016 postgresql-9.6
Hackers Champloo 2016 postgresql-9.6Hackers Champloo 2016 postgresql-9.6
Hackers Champloo 2016 postgresql-9.6
 
新しくなったPg monzでpostgre sqlのクラスタを監視しよう
新しくなったPg monzでpostgre sqlのクラスタを監視しよう新しくなったPg monzでpostgre sqlのクラスタを監視しよう
新しくなったPg monzでpostgre sqlのクラスタを監視しよう
 
PostgreSQL 9.2 新機能 - 新潟オープンソースセミナー2012
PostgreSQL 9.2 新機能 - 新潟オープンソースセミナー2012PostgreSQL 9.2 新機能 - 新潟オープンソースセミナー2012
PostgreSQL 9.2 新機能 - 新潟オープンソースセミナー2012
 
いまさら聞けないPostgreSQL運用管理
いまさら聞けないPostgreSQL運用管理いまさら聞けないPostgreSQL運用管理
いまさら聞けないPostgreSQL運用管理
 
JPUG 沖縄支部セミナー資料(2013-04-27)
JPUG 沖縄支部セミナー資料(2013-04-27)JPUG 沖縄支部セミナー資料(2013-04-27)
JPUG 沖縄支部セミナー資料(2013-04-27)
 
Jpug study-pq 20170121
Jpug study-pq 20170121Jpug study-pq 20170121
Jpug study-pq 20170121
 
PostgreSQL 9.6 新機能紹介
PostgreSQL 9.6 新機能紹介PostgreSQL 9.6 新機能紹介
PostgreSQL 9.6 新機能紹介
 
5ステップで始めるPostgreSQLレプリケーション@hbstudy#13
5ステップで始めるPostgreSQLレプリケーション@hbstudy#135ステップで始めるPostgreSQLレプリケーション@hbstudy#13
5ステップで始めるPostgreSQLレプリケーション@hbstudy#13
 
Vacuum徹底解説
Vacuum徹底解説Vacuum徹底解説
Vacuum徹底解説
 
PostgreSQL 9.2 新機能 - OSC 2012 Kansai@Kyoto
PostgreSQL 9.2 新機能 - OSC 2012 Kansai@KyotoPostgreSQL 9.2 新機能 - OSC 2012 Kansai@Kyoto
PostgreSQL 9.2 新機能 - OSC 2012 Kansai@Kyoto
 

Viewers also liked

Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアルkwatch
 
レシピブログのサービス設計と今後の展望
レシピブログのサービス設計と今後の展望レシピブログのサービス設計と今後の展望
レシピブログのサービス設計と今後の展望Masaki Nakagawa
 
Lagom で学ぶ Reactive Microservices Architecture @ 第3回Reactive System Meetup i...
Lagom で学ぶ Reactive Microservices Architecture @ 第3回Reactive System Meetup i...Lagom で学ぶ Reactive Microservices Architecture @ 第3回Reactive System Meetup i...
Lagom で学ぶ Reactive Microservices Architecture @ 第3回Reactive System Meetup i...TIS Inc.
 
今すぐ使えるクラウドとPostgreSQL
今すぐ使えるクラウドとPostgreSQL今すぐ使えるクラウドとPostgreSQL
今すぐ使えるクラウドとPostgreSQLSoudai Sone
 
HAWQをCDHで動かしてみた
HAWQをCDHで動かしてみたHAWQをCDHで動かしてみた
HAWQをCDHで動かしてみたadachij2002
 
Ivsctonightandday2016winter moringsession awsreinvent2016recap
Ivsctonightandday2016winter moringsession awsreinvent2016recapIvsctonightandday2016winter moringsession awsreinvent2016recap
Ivsctonightandday2016winter moringsession awsreinvent2016recapTadashi Okazaki
 
初心者がAWSでWebサービスを始めるまで 〜たった3ステップでWebページは公開できる〜
初心者がAWSでWebサービスを始めるまで 〜たった3ステップでWebページは公開できる〜初心者がAWSでWebサービスを始めるまで 〜たった3ステップでWebページは公開できる〜
初心者がAWSでWebサービスを始めるまで 〜たった3ステップでWebページは公開できる〜Takeshi Wakamatsu
 
【自社プロダクト開発エンジニア募集中】エーピーコミュニケーションズ 先進開発グループ
【自社プロダクト開発エンジニア募集中】エーピーコミュニケーションズ 先進開発グループ【自社プロダクト開発エンジニア募集中】エーピーコミュニケーションズ 先進開発グループ
【自社プロダクト開発エンジニア募集中】エーピーコミュニケーションズ 先進開発グループAPCommunications-recruit
 
[D31] PostgreSQLでスケールアウト構成を構築しよう by Yugo Nagata
[D31] PostgreSQLでスケールアウト構成を構築しよう by Yugo Nagata[D31] PostgreSQLでスケールアウト構成を構築しよう by Yugo Nagata
[D31] PostgreSQLでスケールアウト構成を構築しよう by Yugo NagataInsight Technology, Inc.
 
最上級の簡易性を備えたオープンソースDBクラウド基盤 Composeのご紹介
最上級の簡易性を備えたオープンソースDBクラウド基盤 Composeのご紹介最上級の簡易性を備えたオープンソースDBクラウド基盤 Composeのご紹介
最上級の簡易性を備えたオープンソースDBクラウド基盤 Composeのご紹介IBM Analytics Japan
 
PL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database AnalyticsPL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database AnalyticsKohei KaiGai
 
仕事で使うちょっとしたコードをOSSとして開発メンテしていく - Django Redshift Backend の開発 - PyCon JP 2016
仕事で使うちょっとしたコードをOSSとして開発メンテしていく- Django Redshift Backend の開発 - PyCon JP 2016仕事で使うちょっとしたコードをOSSとして開発メンテしていく- Django Redshift Backend の開発 - PyCon JP 2016
仕事で使うちょっとしたコードをOSSとして開発メンテしていく - Django Redshift Backend の開発 - PyCon JP 2016Takayuki Shimizukawa
 
サーバーワークス re:invent_2016~新サービス・アップデート紹介~
サーバーワークス re:invent_2016~新サービス・アップデート紹介~サーバーワークス re:invent_2016~新サービス・アップデート紹介~
サーバーワークス re:invent_2016~新サービス・アップデート紹介~Serverworks Co.,Ltd.
 
35歳でDBAになった私がデータベースを壊して学んだこと
35歳でDBAになった私がデータベースを壊して学んだこと35歳でDBAになった私がデータベースを壊して学んだこと
35歳でDBAになった私がデータベースを壊して学んだことShinnosuke Akita
 
20160927_守るべきは、大量の情報資産を管理するデータベース! ~ユーザ事例から見るデータベースのセキュリティ対策~ by 株式会社インサイトテクノ...
20160927_守るべきは、大量の情報資産を管理するデータベース! ~ユーザ事例から見るデータベースのセキュリティ対策~ by 株式会社インサイトテクノ...20160927_守るべきは、大量の情報資産を管理するデータベース! ~ユーザ事例から見るデータベースのセキュリティ対策~ by 株式会社インサイトテクノ...
20160927_守るべきは、大量の情報資産を管理するデータベース! ~ユーザ事例から見るデータベースのセキュリティ対策~ by 株式会社インサイトテクノ...Insight Technology, Inc.
 
20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫
20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫
20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫Insight Technology, Inc.
 
地方エンジニアがPostgreSQLを通じて成長した話
地方エンジニアがPostgreSQLを通じて成長した話地方エンジニアがPostgreSQLを通じて成長した話
地方エンジニアがPostgreSQLを通じて成長した話Soudai Sone
 
[data analytics showcase] B16: Live Demo! データ分析基盤を支えるデータレプリケーション技術とデータワークロード分...
[data analytics showcase] B16: Live Demo! データ分析基盤を支えるデータレプリケーション技術とデータワークロード分...[data analytics showcase] B16: Live Demo! データ分析基盤を支えるデータレプリケーション技術とデータワークロード分...
[data analytics showcase] B16: Live Demo! データ分析基盤を支えるデータレプリケーション技術とデータワークロード分...Insight Technology, Inc.
 
[CB16] 80時間でWebを一周:クロムミウムオートメーションによるスケーラブルなフィンガープリント by Isaac Dawson
[CB16] 80時間でWebを一周:クロムミウムオートメーションによるスケーラブルなフィンガープリント by Isaac Dawson[CB16] 80時間でWebを一周:クロムミウムオートメーションによるスケーラブルなフィンガープリント by Isaac Dawson
[CB16] 80時間でWebを一周:クロムミウムオートメーションによるスケーラブルなフィンガープリント by Isaac DawsonCODE BLUE
 
リローダブルClojureアプリケーション
リローダブルClojureアプリケーションリローダブルClojureアプリケーション
リローダブルClojureアプリケーションKenji Nakamura
 

Viewers also liked (20)

Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアル
 
レシピブログのサービス設計と今後の展望
レシピブログのサービス設計と今後の展望レシピブログのサービス設計と今後の展望
レシピブログのサービス設計と今後の展望
 
Lagom で学ぶ Reactive Microservices Architecture @ 第3回Reactive System Meetup i...
Lagom で学ぶ Reactive Microservices Architecture @ 第3回Reactive System Meetup i...Lagom で学ぶ Reactive Microservices Architecture @ 第3回Reactive System Meetup i...
Lagom で学ぶ Reactive Microservices Architecture @ 第3回Reactive System Meetup i...
 
今すぐ使えるクラウドとPostgreSQL
今すぐ使えるクラウドとPostgreSQL今すぐ使えるクラウドとPostgreSQL
今すぐ使えるクラウドとPostgreSQL
 
HAWQをCDHで動かしてみた
HAWQをCDHで動かしてみたHAWQをCDHで動かしてみた
HAWQをCDHで動かしてみた
 
Ivsctonightandday2016winter moringsession awsreinvent2016recap
Ivsctonightandday2016winter moringsession awsreinvent2016recapIvsctonightandday2016winter moringsession awsreinvent2016recap
Ivsctonightandday2016winter moringsession awsreinvent2016recap
 
初心者がAWSでWebサービスを始めるまで 〜たった3ステップでWebページは公開できる〜
初心者がAWSでWebサービスを始めるまで 〜たった3ステップでWebページは公開できる〜初心者がAWSでWebサービスを始めるまで 〜たった3ステップでWebページは公開できる〜
初心者がAWSでWebサービスを始めるまで 〜たった3ステップでWebページは公開できる〜
 
【自社プロダクト開発エンジニア募集中】エーピーコミュニケーションズ 先進開発グループ
【自社プロダクト開発エンジニア募集中】エーピーコミュニケーションズ 先進開発グループ【自社プロダクト開発エンジニア募集中】エーピーコミュニケーションズ 先進開発グループ
【自社プロダクト開発エンジニア募集中】エーピーコミュニケーションズ 先進開発グループ
 
[D31] PostgreSQLでスケールアウト構成を構築しよう by Yugo Nagata
[D31] PostgreSQLでスケールアウト構成を構築しよう by Yugo Nagata[D31] PostgreSQLでスケールアウト構成を構築しよう by Yugo Nagata
[D31] PostgreSQLでスケールアウト構成を構築しよう by Yugo Nagata
 
最上級の簡易性を備えたオープンソースDBクラウド基盤 Composeのご紹介
最上級の簡易性を備えたオープンソースDBクラウド基盤 Composeのご紹介最上級の簡易性を備えたオープンソースDBクラウド基盤 Composeのご紹介
最上級の簡易性を備えたオープンソースDBクラウド基盤 Composeのご紹介
 
PL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database AnalyticsPL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
 
仕事で使うちょっとしたコードをOSSとして開発メンテしていく - Django Redshift Backend の開発 - PyCon JP 2016
仕事で使うちょっとしたコードをOSSとして開発メンテしていく- Django Redshift Backend の開発 - PyCon JP 2016仕事で使うちょっとしたコードをOSSとして開発メンテしていく- Django Redshift Backend の開発 - PyCon JP 2016
仕事で使うちょっとしたコードをOSSとして開発メンテしていく - Django Redshift Backend の開発 - PyCon JP 2016
 
サーバーワークス re:invent_2016~新サービス・アップデート紹介~
サーバーワークス re:invent_2016~新サービス・アップデート紹介~サーバーワークス re:invent_2016~新サービス・アップデート紹介~
サーバーワークス re:invent_2016~新サービス・アップデート紹介~
 
35歳でDBAになった私がデータベースを壊して学んだこと
35歳でDBAになった私がデータベースを壊して学んだこと35歳でDBAになった私がデータベースを壊して学んだこと
35歳でDBAになった私がデータベースを壊して学んだこと
 
20160927_守るべきは、大量の情報資産を管理するデータベース! ~ユーザ事例から見るデータベースのセキュリティ対策~ by 株式会社インサイトテクノ...
20160927_守るべきは、大量の情報資産を管理するデータベース! ~ユーザ事例から見るデータベースのセキュリティ対策~ by 株式会社インサイトテクノ...20160927_守るべきは、大量の情報資産を管理するデータベース! ~ユーザ事例から見るデータベースのセキュリティ対策~ by 株式会社インサイトテクノ...
20160927_守るべきは、大量の情報資産を管理するデータベース! ~ユーザ事例から見るデータベースのセキュリティ対策~ by 株式会社インサイトテクノ...
 
20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫
20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫
20160929_InnoDBの全文検索を使ってみた by 株式会社インサイトテクノロジー 中村範夫
 
地方エンジニアがPostgreSQLを通じて成長した話
地方エンジニアがPostgreSQLを通じて成長した話地方エンジニアがPostgreSQLを通じて成長した話
地方エンジニアがPostgreSQLを通じて成長した話
 
[data analytics showcase] B16: Live Demo! データ分析基盤を支えるデータレプリケーション技術とデータワークロード分...
[data analytics showcase] B16: Live Demo! データ分析基盤を支えるデータレプリケーション技術とデータワークロード分...[data analytics showcase] B16: Live Demo! データ分析基盤を支えるデータレプリケーション技術とデータワークロード分...
[data analytics showcase] B16: Live Demo! データ分析基盤を支えるデータレプリケーション技術とデータワークロード分...
 
[CB16] 80時間でWebを一周:クロムミウムオートメーションによるスケーラブルなフィンガープリント by Isaac Dawson
[CB16] 80時間でWebを一周:クロムミウムオートメーションによるスケーラブルなフィンガープリント by Isaac Dawson[CB16] 80時間でWebを一周:クロムミウムオートメーションによるスケーラブルなフィンガープリント by Isaac Dawson
[CB16] 80時間でWebを一周:クロムミウムオートメーションによるスケーラブルなフィンガープリント by Isaac Dawson
 
リローダブルClojureアプリケーション
リローダブルClojureアプリケーションリローダブルClojureアプリケーション
リローダブルClojureアプリケーション
 

Similar to Osc2015 hokkaido postgresql-semi-stuructured-datatype

20171103 pg con-jp-lt-plpgsql
20171103 pg con-jp-lt-plpgsql20171103 pg con-jp-lt-plpgsql
20171103 pg con-jp-lt-plpgsqlToshi Harada
 
MyNA JPUG study 20160220-postgresql-json-datatype
MyNA JPUG study 20160220-postgresql-json-datatypeMyNA JPUG study 20160220-postgresql-json-datatype
MyNA JPUG study 20160220-postgresql-json-datatypeToshi Harada
 
PGCon.jp 2014 jsonb-datatype-20141205
PGCon.jp 2014 jsonb-datatype-20141205PGCon.jp 2014 jsonb-datatype-20141205
PGCon.jp 2014 jsonb-datatype-20141205Toshi Harada
 
Osc shimane-2016-do-postgres-dream-of-graph-database
Osc shimane-2016-do-postgres-dream-of-graph-databaseOsc shimane-2016-do-postgres-dream-of-graph-database
Osc shimane-2016-do-postgres-dream-of-graph-databaseToshi Harada
 
PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選Tomoya Kawanishi
 
BPStudy32 CouchDB 再入門
BPStudy32 CouchDB 再入門BPStudy32 CouchDB 再入門
BPStudy32 CouchDB 再入門Yohei Sasaki
 
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-uedayou
 
20150530 pgunconf-pgbench-semi-structured-benchmark
20150530 pgunconf-pgbench-semi-structured-benchmark20150530 pgunconf-pgbench-semi-structured-benchmark
20150530 pgunconf-pgbench-semi-structured-benchmarkToshi Harada
 
⑲jQueryをおぼえよう!その5
⑲jQueryをおぼえよう!その5⑲jQueryをおぼえよう!その5
⑲jQueryをおぼえよう!その5Nishida Kansuke
 
Chugokudb study-20150131
Chugokudb study-20150131Chugokudb study-20150131
Chugokudb study-20150131Toshi Harada
 
Jpug study-jsonb-datatype-20141011
Jpug study-jsonb-datatype-20141011Jpug study-jsonb-datatype-20141011
Jpug study-jsonb-datatype-20141011Toshi Harada
 
20171106 ntt-tx-postgre sql-10
20171106 ntt-tx-postgre sql-1020171106 ntt-tx-postgre sql-10
20171106 ntt-tx-postgre sql-10Toshi Harada
 
AWS Black Belt Online Seminar 2016 Amazon Kinesis
AWS Black Belt Online Seminar 2016 Amazon KinesisAWS Black Belt Online Seminar 2016 Amazon Kinesis
AWS Black Belt Online Seminar 2016 Amazon KinesisAmazon Web Services Japan
 
JSON Value into Power Automate
JSON Value into Power AutomateJSON Value into Power Automate
JSON Value into Power AutomateTomoyuki Obi
 
JSONB型でpostgresをNoSQLっぽく使う
JSONB型でpostgresをNoSQLっぽく使うJSONB型でpostgresをNoSQLっぽく使う
JSONB型でpostgresをNoSQLっぽく使うYuki Takeichi
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platformToru Yamaguchi
 
Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Shinsuke Sugaya
 
20171028 osc-nagaoka-postgre sql-10
20171028 osc-nagaoka-postgre sql-1020171028 osc-nagaoka-postgre sql-10
20171028 osc-nagaoka-postgre sql-10Toshi Harada
 

Similar to Osc2015 hokkaido postgresql-semi-stuructured-datatype (20)

20171103 pg con-jp-lt-plpgsql
20171103 pg con-jp-lt-plpgsql20171103 pg con-jp-lt-plpgsql
20171103 pg con-jp-lt-plpgsql
 
MyNA JPUG study 20160220-postgresql-json-datatype
MyNA JPUG study 20160220-postgresql-json-datatypeMyNA JPUG study 20160220-postgresql-json-datatype
MyNA JPUG study 20160220-postgresql-json-datatype
 
PGCon.jp 2014 jsonb-datatype-20141205
PGCon.jp 2014 jsonb-datatype-20141205PGCon.jp 2014 jsonb-datatype-20141205
PGCon.jp 2014 jsonb-datatype-20141205
 
Osc shimane-2016-do-postgres-dream-of-graph-database
Osc shimane-2016-do-postgres-dream-of-graph-databaseOsc shimane-2016-do-postgres-dream-of-graph-database
Osc shimane-2016-do-postgres-dream-of-graph-database
 
PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選
 
BPStudy32 CouchDB 再入門
BPStudy32 CouchDB 再入門BPStudy32 CouchDB 再入門
BPStudy32 CouchDB 再入門
 
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-
 
20150530 pgunconf-pgbench-semi-structured-benchmark
20150530 pgunconf-pgbench-semi-structured-benchmark20150530 pgunconf-pgbench-semi-structured-benchmark
20150530 pgunconf-pgbench-semi-structured-benchmark
 
⑲jQueryをおぼえよう!その5
⑲jQueryをおぼえよう!その5⑲jQueryをおぼえよう!その5
⑲jQueryをおぼえよう!その5
 
Chugokudb study-20150131
Chugokudb study-20150131Chugokudb study-20150131
Chugokudb study-20150131
 
Jpug study-jsonb-datatype-20141011
Jpug study-jsonb-datatype-20141011Jpug study-jsonb-datatype-20141011
Jpug study-jsonb-datatype-20141011
 
20171106 ntt-tx-postgre sql-10
20171106 ntt-tx-postgre sql-1020171106 ntt-tx-postgre sql-10
20171106 ntt-tx-postgre sql-10
 
AWS Black Belt Online Seminar 2016 Amazon Kinesis
AWS Black Belt Online Seminar 2016 Amazon KinesisAWS Black Belt Online Seminar 2016 Amazon Kinesis
AWS Black Belt Online Seminar 2016 Amazon Kinesis
 
Tokyo r 25_lt_isobe
Tokyo r 25_lt_isobeTokyo r 25_lt_isobe
Tokyo r 25_lt_isobe
 
JSON Value into Power Automate
JSON Value into Power AutomateJSON Value into Power Automate
JSON Value into Power Automate
 
JSONB型でpostgresをNoSQLっぽく使う
JSONB型でpostgresをNoSQLっぽく使うJSONB型でpostgresをNoSQLっぽく使う
JSONB型でpostgresをNoSQLっぽく使う
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platform
 
Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方
 
20171028 osc-nagaoka-postgre sql-10
20171028 osc-nagaoka-postgre sql-1020171028 osc-nagaoka-postgre sql-10
20171028 osc-nagaoka-postgre sql-10
 
Heroku Postgres
Heroku PostgresHeroku Postgres
Heroku Postgres
 

More from Toshi Harada

無駄にNeo4jを使っている日々
無駄にNeo4jを使っている日々無駄にNeo4jを使っている日々
無駄にNeo4jを使っている日々Toshi Harada
 
Pgunconf14 pg13-psql
Pgunconf14 pg13-psqlPgunconf14 pg13-psql
Pgunconf14 pg13-psqlToshi Harada
 
20190518 27th-chugoku db-lt-pg12
20190518 27th-chugoku db-lt-pg1220190518 27th-chugoku db-lt-pg12
20190518 27th-chugoku db-lt-pg12Toshi Harada
 
20190202-pgunconf-Access-Privilege-Inquiry-Functions
20190202-pgunconf-Access-Privilege-Inquiry-Functions20190202-pgunconf-Access-Privilege-Inquiry-Functions
20190202-pgunconf-Access-Privilege-Inquiry-FunctionsToshi Harada
 
20190119 aws-study-pg-extension
20190119 aws-study-pg-extension20190119 aws-study-pg-extension
20190119 aws-study-pg-extensionToshi Harada
 
20181122 pg con-jp-lt-logrep
20181122 pg con-jp-lt-logrep20181122 pg con-jp-lt-logrep
20181122 pg con-jp-lt-logrepToshi Harada
 
20181110 fok2018-pg-extension
20181110 fok2018-pg-extension20181110 fok2018-pg-extension
20181110 fok2018-pg-extensionToshi Harada
 
20170819 ocd-l tthon-pgdev
20170819 ocd-l tthon-pgdev20170819 ocd-l tthon-pgdev
20170819 ocd-l tthon-pgdevToshi Harada
 
Ntt tx-study-postgre sql-10
Ntt tx-study-postgre sql-10Ntt tx-study-postgre sql-10
Ntt tx-study-postgre sql-10Toshi Harada
 
Jpug study-postgre sql-10-pub
Jpug study-postgre sql-10-pubJpug study-postgre sql-10-pub
Jpug study-postgre sql-10-pubToshi Harada
 
Chugoku db 20th-postgresql-10-pub
Chugoku db 20th-postgresql-10-pubChugoku db 20th-postgresql-10-pub
Chugoku db 20th-postgresql-10-pubToshi Harada
 
Pgconf asia-201612203-pg reversi-ja
Pgconf asia-201612203-pg reversi-jaPgconf asia-201612203-pg reversi-ja
Pgconf asia-201612203-pg reversi-jaToshi Harada
 
Pgconf asia-201612203-pg reversi
Pgconf asia-201612203-pg reversiPgconf asia-201612203-pg reversi
Pgconf asia-201612203-pg reversiToshi Harada
 
Kof2016 postgresql-9.6
Kof2016 postgresql-9.6Kof2016 postgresql-9.6
Kof2016 postgresql-9.6Toshi Harada
 
Chugoku db 17th-lt-kly
Chugoku db 17th-lt-klyChugoku db 17th-lt-kly
Chugoku db 17th-lt-klyToshi Harada
 
Chugoku db 17th-postgresql-9.6
Chugoku db 17th-postgresql-9.6Chugoku db 17th-postgresql-9.6
Chugoku db 17th-postgresql-9.6Toshi Harada
 
Dblt#2 do-postgres-dream-of-graph-database
Dblt#2 do-postgres-dream-of-graph-databaseDblt#2 do-postgres-dream-of-graph-database
Dblt#2 do-postgres-dream-of-graph-databaseToshi Harada
 
Do postgres-dream-of-graph-database
Do postgres-dream-of-graph-databaseDo postgres-dream-of-graph-database
Do postgres-dream-of-graph-databaseToshi Harada
 
Pgunconf 20121212-postgeres fdw
Pgunconf 20121212-postgeres fdwPgunconf 20121212-postgeres fdw
Pgunconf 20121212-postgeres fdwToshi Harada
 

More from Toshi Harada (20)

無駄にNeo4jを使っている日々
無駄にNeo4jを使っている日々無駄にNeo4jを使っている日々
無駄にNeo4jを使っている日々
 
Pgunconf16 toast
Pgunconf16 toastPgunconf16 toast
Pgunconf16 toast
 
Pgunconf14 pg13-psql
Pgunconf14 pg13-psqlPgunconf14 pg13-psql
Pgunconf14 pg13-psql
 
20190518 27th-chugoku db-lt-pg12
20190518 27th-chugoku db-lt-pg1220190518 27th-chugoku db-lt-pg12
20190518 27th-chugoku db-lt-pg12
 
20190202-pgunconf-Access-Privilege-Inquiry-Functions
20190202-pgunconf-Access-Privilege-Inquiry-Functions20190202-pgunconf-Access-Privilege-Inquiry-Functions
20190202-pgunconf-Access-Privilege-Inquiry-Functions
 
20190119 aws-study-pg-extension
20190119 aws-study-pg-extension20190119 aws-study-pg-extension
20190119 aws-study-pg-extension
 
20181122 pg con-jp-lt-logrep
20181122 pg con-jp-lt-logrep20181122 pg con-jp-lt-logrep
20181122 pg con-jp-lt-logrep
 
20181110 fok2018-pg-extension
20181110 fok2018-pg-extension20181110 fok2018-pg-extension
20181110 fok2018-pg-extension
 
20170819 ocd-l tthon-pgdev
20170819 ocd-l tthon-pgdev20170819 ocd-l tthon-pgdev
20170819 ocd-l tthon-pgdev
 
Ntt tx-study-postgre sql-10
Ntt tx-study-postgre sql-10Ntt tx-study-postgre sql-10
Ntt tx-study-postgre sql-10
 
Jpug study-postgre sql-10-pub
Jpug study-postgre sql-10-pubJpug study-postgre sql-10-pub
Jpug study-postgre sql-10-pub
 
Chugoku db 20th-postgresql-10-pub
Chugoku db 20th-postgresql-10-pubChugoku db 20th-postgresql-10-pub
Chugoku db 20th-postgresql-10-pub
 
Pgconf asia-201612203-pg reversi-ja
Pgconf asia-201612203-pg reversi-jaPgconf asia-201612203-pg reversi-ja
Pgconf asia-201612203-pg reversi-ja
 
Pgconf asia-201612203-pg reversi
Pgconf asia-201612203-pg reversiPgconf asia-201612203-pg reversi
Pgconf asia-201612203-pg reversi
 
Kof2016 postgresql-9.6
Kof2016 postgresql-9.6Kof2016 postgresql-9.6
Kof2016 postgresql-9.6
 
Chugoku db 17th-lt-kly
Chugoku db 17th-lt-klyChugoku db 17th-lt-kly
Chugoku db 17th-lt-kly
 
Chugoku db 17th-postgresql-9.6
Chugoku db 17th-postgresql-9.6Chugoku db 17th-postgresql-9.6
Chugoku db 17th-postgresql-9.6
 
Dblt#2 do-postgres-dream-of-graph-database
Dblt#2 do-postgres-dream-of-graph-databaseDblt#2 do-postgres-dream-of-graph-database
Dblt#2 do-postgres-dream-of-graph-database
 
Do postgres-dream-of-graph-database
Do postgres-dream-of-graph-databaseDo postgres-dream-of-graph-database
Do postgres-dream-of-graph-database
 
Pgunconf 20121212-postgeres fdw
Pgunconf 20121212-postgeres fdwPgunconf 20121212-postgeres fdw
Pgunconf 20121212-postgeres fdw
 

Recently uploaded

クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NTT DATA Technology & Innovation
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 

Recently uploaded (8)

クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 

Osc2015 hokkaido postgresql-semi-stuructured-datatype

  • 2. 2 自己紹介 SELECT '{ " 名前 ":" ぬこ@横浜 ", " 住所 ":" 横浜市 ", "Twitter":"@nuko_yokohama", " 所属 ":{" 会社 ":" 某通信系ソフトウェア会社 ", " 部署 ":" クラウドな感じ(仕事はクラウドじゃない) ", " 勤務地 ":" ミナトミライ・スゴイトオイビル "}, " 仕事 ":"PostgreSQL あれこれ ", " 趣味 ":[" 猫 "," スパ "," 原付旅 ","PostgreSQL"," ラーメン "], " メモ ":["PostgreSQL は 7.4 の頃からの腐れ縁 ", " ときどき PostgreSQL イベントで喋ってます ","PostgreSQL チョットデキル "], " 作ったもの ":[" 漢数字型 (ksj)"," ゆるい文字型 (ntext)", "new4j_fdw", "hit_and_blow BGW"]}'::jsonb;
  • 3. 3 自己紹介 ( こんなの作ってた ) SELECT data, data + ' 拾 ' FROM ksj_sample; data | ?column? ------------+---------------- 五百壱拾六 | 五百弐拾六 零 | 壱拾 参万壱百壱 | 参万壱百壱拾壱 (3 rows) SELECT data, data * ' 拾 ' FROM ksj_sample; data | ?column? ------------+-------------- 五百壱拾六 | 五千壱百六拾 零 | 零 参万壱百壱 | 参拾壱千壱拾 (3 rows) SELECT sum(data) FROM ksj_sample; sum ---------------- 参万六百壱拾七 (1 row) SELECT * FROM ksj_sample ORDER BY data; data ------------ 零 五百壱拾六 参万壱百壱 (3 rows) ksj (漢数字型) 漢数字で四則演算や 比較演算できる、誰得データ型
  • 4. 4 自己紹介 ( こんなの作ってた ) SELECT * FROM foo WHERE data = ' エバンゲリオン '; id | data ----+------------ 3 | エヴァンゲリヲン (1 row) SELECT * FROM foo WHERE data = ' センヌリティウス '; id | data ----+------ (0 rows) SELECT * FROM foo WHERE data /= ' センヌリティウス '; id | data ----+------------------ 4 | セリヌンティウス (1 row) ntext( ゆるい文字型 ) 日本語正規化 ゆるい演算子 (/=) 類似度計算で typo を許容
  • 5. 5 自己紹介 ( こんなの作ってた ) CREATE FOREIGN TABLE bar3 ( my_name text, my_gender text, follower_name text, follower_gender text) SERVER foo OPTIONS (query '{ "query":"START n=node(*) MATCH p=fm<-[]-n<-[]-fm RETURN n.name as my_name, n.gender as my_gender, fm.name as follower_name, fm.gender as follower_gender" }'); SELECT my_name, my_gender, follower_name, follower_gender FROM bar3; my_name | my_gender | follower_name | follower_gender ---------+-----------+---------------+----------------- Akagi | Famale | Hiryu | Famale Nagato | Male | Mutsu | Male Mutsu | Male | Nagato | Male Hiryu | Famale | Soryu | Famale Hiryu | Famale | Akagi | Famale Soryu | Famale | Hiryu | Famale (6 rows) new4j_fdw グラフデータベース Neo4j を わざわざ PostgreSQL 経由で SQL 検索する誰得 FDW neo4j_fdw
  • 6. 6 自己紹介 ( こんなの作ってた ) postgres=# LISTEN HB_CL; LISTEN postgres=# NOTIFY HB_SV,'xxxx';; NOTIFY Asynchronous notification "hb_cl" with payload "Invalid data.(xxxx)" received from server process with PID 29520. postgres=# NOTIFY HB_SV,'0123';; NOTIFY Asynchronous notification "hb_cl" with payload "2 Hit / 1 Blow." received from server process with PID 29520. postgres=# NOTIFY HB_SV,'0813';; NOTIFY Asynchronous notification "hb_cl" with payload "4 Hit! Conguratulatoins!, next new game." received from server process with PID 29520. postgres=# hb_worker psql などから数当てができる Background Worker Process
  • 11. 11 PostgreSQL の概要 MySQL と並ぶ OSS RDBMS ライセンスは BSD ライクなもの 高度なクエリにも対応 性能面でも商用 DBMS とも遜色なし 9.0 以降はレプリケーションも対応 多種多様なデータ型サポート 非常に高い拡張性 活発な開発コミュニティ
  • 12. 12 PostgreSQL の歴史 POSTGRES プロジェクト の時代 Postgres95 の時代 ※SQL サポート PostgresSQL の時代 ※6.0 から開始 6.0 ~ 発展途上の時代 GEQO マルチバイト文字セット MVCC 7.0 ~ やっと実用的に WAL TOAST VACUUM 改善 8.0 ~ 商用レベルへ Windows 対応 PITR 自動 VACUUM HOT 9.0 ~ エンタープライズ化 レプリケーション 外部表 メニーコア性能向上 マテリアライズドビュー JSON 対応 PostgreSQLPostgreSQL のの 進化はこれからも続く…進化はこれからも続く… 1986 年 1995 年 1997 年 1997 年 2000 年 2005 年 2010 年 意外と古い?
  • 14. 14 PostgreSQL 9.4 JSONB データ型 ALTER SYSTEM コマンド マテリアライズド・ビューの改善 ロジカル・デコーディング バックグラウンドワーカプロセスの動的操作 WAL バッファへの並列挿入 etc... 200 項目近くの改善 / 修正 最新版は 9.4.4 ( 昨晩アナウンス )
  • 15. 15 PostgreSQL 9.5( 開発中 ) IMPORT FOREIGN SCHEMA Row-Level Security Policies BRIN Indexes(Block Range Index) Foreign Table Inheritance JSONB-modifying operators and functions UPSERT(INSERT ... ON CONFLICT DO NOTHING/UPDATE) Parallel VACUUMing etc... 今後、変更される 可能性はあり Release Notes も先日公開されました! http://www.postgresql.org/docs/devel/static/release-9-5.html
  • 18. 18 構造化の観点から見た分類 種別 内容 例 構造化データ 何らかの定義(スキーマ定義等)に より、構造を事前に決定しておく データ。 CREATE TABLE 文で 定義されたテーブル 半構造化データ 事前の定義はあるが、定義内の一部 の構造が存在しなくても良いデー タ。 XML スキーマで定義さ れた XML 文書 非構造化データ 事前の構造定義を持たないデータ。 任意の JSON 文書 通常、 RDBMS では上記の種別の データのうち、構造化データを扱う。
  • 19. 19 PostgreSQL と非構造データ型 PostgreSQL で通常扱うのは、 「構造化データ」 さらに、それに加えて PostgreSQL では 「半構造化データ」「非構造化データ」 (以降、両方とも「非構造化データ」と 記述)を扱うしくみも用意されている。
  • 20. 20 PostgreSQL と非構造データ型 PostgreSQL で使用可能な、 非構造化データ型は以下の 4 種類 型名 対応バージョン 位置づけ 備考 XML 8.2 ~ 本体機能 libxml2 依存 hstore 8.3 ~ contrib JSON 9.2 ~ 本体機能 JSONB 9.4 ~ 本体機能
  • 21. 21 XML 型 XML を格納するデータ型 本体機能 (configure で指定 ) 格納時に XML パースを行なう 型自体に比較演算機能はない xpath によるアクセスが可能 SQL 関数による XML 型構築 libxml2 ライブラリに依存
  • 22. 22 XML 型の処理イメージ XML 文字列 XML パーサ XML 型 (文字列) XML 文字列 関数の結果 (そのまま出力) 格納時 取り出し時 xpath 関数 XML パーサ関数処理 xpath 処理 パーサではチェック のみを行う PostgreSQL ストレージ
  • 23. 23 XML 型でできること XML 文字列のパースと格納 xpath による結果の取り出し SQL 関数による XML 型の構築
  • 24. 24 XML 型の使用例 XML 型カラムを持つテーブル other=# d xml_t Table "public.xml_t" Column | Type | Modifiers --------+---------+---------------------------------------------------- id | integer | not null default nextval('xml_t_id_seq'::regclass) data | xml | other=# SELECT data FROM xml_t; <rdb_t><email>Laverna@junius.io</email><created_at>1987-08- 21T18:42:02.269Z</created_at><country> Paraguay</country><id>0</id><full_name>Carolyne Kohler</full_name></rdb_t> <rdb_t><email>Nakia_Rolfson@cecelia.ca</email><created_at>1989-03- 16T14:37:36.825Z</created_at><c ountry>France</country><id>1</id><full_name>Paul Weber DVM</full_name></rdb_t> <rdb_t><email>Elbert@norma.co.uk</email><created_at>1980-02- 19T04:16:52.113Z</created_at><country >Uzbekistan</country><id>2</id><full_name>Florence Murphy</full_name></rdb_t> (3 rows)
  • 25. 25 XML 型の使用例 xpath 関数による XML 文書からの抽出 other=# SELECT (xpath('/rdb_t/email/text()', data)::text[])[1] as email, (xpath('/rdb_t/full_name/text()', data)::text[])[1] as fullname FROM xml_t; email | fullname --------------------------+----------------- Laverna@junius.io | Carolyne Kohler Nakia_Rolfson@cecelia.ca | Paul Weber DVM Elbert@norma.co.uk | Florence Murphy (3 rows) XML や xpath 関数は強力だけど、書くのは少々面倒・・・ (例) xpath 関数は XML 配列を返却するので、テキストを取り出す場合に、 TEXT 配列にキャストして最初の要素を取り出すなどの操作が必要。 (例)名前空間 url と prefix の組を配列化して xpath 関数に渡す必要がある。
  • 26. 26 hstore 型 Key-Value store データ型 contrib モジュール ネストはできない。 部分更新インタフェースあり ※ 作者は JSONB と同じ Oleg 氏
  • 27. 27 hstore 型の処理イメージ hstore 文字列 hstore パーサ hstore 型 (バイナリ) hstore 文字列 関数の結果 文字列化 格納時 取り出し時 hstore 関数 関数処理 バイナリを直接解釈して 関数実行 パーサは動作しない PostgreSQL ストレージシリアライズ
  • 28. 28 hstore 型でできること hstore 文字列のパースと格納 キーによる値の取り出し キーと値のセットで追加 / 更新 指定キーのキー&値を削除 レコードからの生成 JSON への変換 GIN インデックス対応
  • 29. 29 hstore 型の使用例 hstore 型カラムを持つテーブル other=# dx List of installed extensions Name | Version | Schema | Description ---------+---------+------------ +-------------------------------------------------- hstore | 1.3 | public | data type for storing sets of (key, value) pairs plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language (2 rows) other=# d hstore_t Table "public.hstore_t" Column | Type | Modifiers --------+---------+------------------------------------------------------- id | integer | not null default nextval('hstore_t_id_seq'::regclass) data | hstore |
  • 30. 30 hstore 型の使用例 hstore 型カラムの検索 other=# SELECT data FROM hstore_t; data ------------------------------------------------------------------------------ -------------------- -------------------------------------------- "id"=>"0", "email"=>"Laverna@junius.io", "country"=>"Paraguay", "full_name"=>"Carolyne Kohler", " created_at"=>"1987-08-21T18:42:02.269Z" "id"=>"1", "email"=>"Nakia_Rolfson@cecelia.ca", "country"=>"France", "full_name"=>"Paul Weber DVM ", "created_at"=>"1989-03-16T14:37:36.825Z" "id"=>"2", "email"=>"Elbert@norma.co.uk", "country"=>"Uzbekistan", "full_name"=>"Florence Murphy" , "created_at"=>"1980-02-19T04:16:52.113Z" (3 rows)
  • 31. 31 hstore 型の使用例 hstore 型カラムから特定のキーのみ抽出 other=# SELECT data->'email' as email, data->'full_name' as full_name FROM hstore_t; email | full_name --------------------------+----------------- Laverna@junius.io | Carolyne Kohler Nakia_Rolfson@cecelia.ca | Paul Weber DVM Elbert@norma.co.uk | Florence Murphy (3 rows) 条件式を使う例 other=# SELECT data->'id' as id, data->'email' as email FROM hstore_t WHERE data->'id' = '1'; id | email ----+-------------------------- 1 | Nakia_Rolfson@cecelia.ca (1 row) XML 型 /xpath 関数を使うよりシンプルに書ける
  • 32. 32 hstore に関する補足 hstore については、 JPUG の「第 20 回 しくみ + アプリケーション勉強会 (2011 年 6 月 4 日 ) 」でも解説しているので、 そちらも参考にしてください ( 多少情報 は古いかもしれませんが…)。 http://www.postgresql.jp/wg/shikumi/sikumi_20/ http://www.postgresql.jp/wg/shikumi/study20_materials/hstore_int roduction/view
  • 34. 34 JSON とは JavaScript Object Notation XML よりも軽量 構造化されたデータを 文字列で表現可能
  • 35. 35 PostgreSQL における JSON への取り組み 9.2 から順調に進化。 9.5 でも…? ●JSON 型の導入。 ●2 つの JSON 型構築関数。 ●JSON 内の値を 使った条件検索は できなかった。 ●JSON 型関数・演算子の 大幅な強化。 ●JSON データ型への パスによるアクセス。 ●JSON 内の値を使った 条件検索が可能に。 ●JSONB 型の導入。 ●検索の高速化 ●独自演算子の追加 ●GIN インデックス対応 9.2 9.3 9.4
  • 37. 37 JSON 文字列のパース PostgreSQL へのデータ格納時 に格納される JSON が正しい 書式かチェックする。 正しくない書式の場合 PostgreSQL がエラーにする。
  • 38. 38 JSON 文字列のパース例 正しい JSON 文字列 jsonb=# SELECT '{"key1":"value1", "key2":[100, 20, 5]}'::json; json ---------------------------------------- {"key1":"value1", "key2":[100, 20, 5]} (1 row) 誤った JSON 文字列 jsonb=# SELECT '{"key1":"value1", "key2":[100, 20, ]}'::json; ERROR: invalid input syntax for type json LINE 1: SELECT '{"key1":"value1", "key2":[100, 20, ]}'::json; ^ DETAIL: Expected JSON value, but found "]". CONTEXT: JSON data, line 1: {"key1":"value1", "key2":[100, 20, ]... ※ パースは JSON/JSONB 型に変換されるときに行われる。 カンマの後に 値がない
  • 40. 40 キーによる値の取り出し JSON 型全体を取得 jsonb=# pset null (null)Null display (null) is "(null)". jsonb=# SELECT data FROM test ORDER BY id LIMIT 3; data --------------------------------------------------------------------------- ----- ------------------------------------------------------------- {"Id": 0, "Email": "Laverna@junius.io", "Country": "Paraguay", "Full Name": "Ca rolyne Kohler", "Created At": "1987-08-21T18:42:02.269Z"} {"Id": 1, "Country": "France", "Full Name": "Paul Weber DVM", "Created At": "19 89-03-16T14:37:36.825Z"} {"Id": 2, "Email": "Elbert@norma.co.uk", "Country": "Uzbekistan", "Full Name": "Florence Murphy", "Created At": "1980-02-19T04:16:52.113Z"} (3 rows)
  • 41. 41 キーによる値の取り出し キーから JSON オブジェクトを取得 jsonb=# SELECT data->'Email' as email , data->'Full Name' as fullname FROM test ORDER BY id LIMIT 3; email | fullname ----------------------+------------------- "Laverna@junius.io" | "Carolyne Kohler" (null) | "Paul Weber DVM" "Elbert@norma.co.uk" | "Florence Murphy" (3 rows) キーから文字列を取得 jsonb=# SELECT data->>'Email' as email , data->>'Full Name' as fullname FROM test ORDER BY id LIMIT 3; email | fullname --------------------+----------------- Laverna@junius.io | Carolyne Kohler (null) | Paul Weber DVM Elbert@norma.co.uk | Florence Murphy (3 rows)
  • 43. 43 パスによる値の取り出し person, name, first のパスで取得 jsonb=# SELECT '{"person":{"name": {"first":"Tom","last":"Lane"},"age":59}}'::json #>> '{person, name, first}'; ?column? ---------- Tom (1 row) person name first last age Tom Lane 59 (root)
  • 44. 44 パスによる値の取り出し Contributes の 2 番目 (0 相対 ) を取得 jsonb=# SELECT '{"Name": {"First":"Oleg","Last":"Bartunov"},"Country":"Russia","Contributes": ["hstore","JSON","JSONB","GIN"]}'::json #>> '{Contributes,2}'; ?column? ---------- JSONB (1 row) Contributes name first last Oleg hstore (root) JSON JSONB GIN [0] [1] [2] [3] Bartunov
  • 46. 46 式インデックスとの組合せ 式インデックスの設定 jsonb=# SELECT data FROM json_t LIMIT 1; data --------------------------------------------------------------------------- ----- -------------------------------------------------------------------------- { "Email": "Laverna@junius.io", "Created At": "1987-08- 21T18:42:02.269Z", "Country": "Paraguay", "Id": 0, "Full Name": "Carolyne Kohler"} (1 row) jsonb=# CREATE INDEX json_id_idx ON json_t USING btree ((data->>'Id')); CREATE INDEX jsonb=# d json_t Unlogged table "public.json_t" Column | Type | Modifiers --------+---------+----------------------------------------------------- id | integer | not null default nextval('json_t_id_seq'::regclass) data | json | Indexes: "json_id_idx" btree ((data ->> 'Id'::text))
  • 47. 47 式インデックスとの組合せ 式インデックスを利用した検索 jsonb=# EXPLAIN ANALYZE SELECT data FROM json_t WHERE data->>'Id' = '1000'; QUERY PLAN --------------------------------------------------------------------------- ----- ------------------------------------- Bitmap Heap Scan on json_t (cost=4.68..130.11 rows=50 width=32) (actual time=0 .078..0.078 rows=1 loops=1) Recheck Cond: ((data ->> 'Id'::text) = '1000'::text) Heap Blocks: exact=1 -> Bitmap Index Scan on json_id_idx (cost=0.00..4.66 rows=50 width=0) (actual time=0.072..0.072 rows=1 loops=1) Index Cond: ((data ->> 'Id'::text) = '1000'::text) Planning time: 0.248 ms Execution time: 0.106 ms (7 rows)
  • 48. 48 その他の JSON 関数 PostgreSQL 配列と JSON 配列との変換 行から JSON への変換 JSON から PostgreSQL 行への展開 キー集合の取得
  • 49. 49 PostgreSQL 配列と JSON 配列との変換 jsonb=# SELECT array_to_json(ARRAY[1, 3.14, -1.2e3]); array_to_json ---------------- [1,3.14,-1200] (1 row) jsonb=# TABLE bar; id | n_datas | t_datas ----+------------------+------------------------ 1 | {1.32,9.76,5.55} | {bdho,fjoal} 2 | {6.43,0.48} | {vbwdahoi,3dsai,cfjia} 3 | {} | {} (3 rows) jsonb=# SELECT array_to_json(bar.t_datas) FROM bar; array_to_json ------------------------------ ["bdho","fjoal"] ["vbwdahoi","3dsai","cfjia"] [] (3 rows) PostgreSQL 配列を JSON 配列に変換 テーブル内の特定の列を JSON 化した例
  • 50. 50 行から JSON への変換 jsonb=# TABLE foo; id | n_data | t_data ----+--------+---------- 1 | 8.93 | 366fd4cf 2 | 5.23 | 3f0a243b 3 | (null) | (null) (3 rows) jsonb=# SELECT row_to_json(foo.*) FROM foo; row_to_json -------------------------------------------- {"id":1,"n_data":8.93,"t_data":"366fd4cf"} {"id":2,"n_data":5.23,"t_data":"3f0a243b"} {"id":3,"n_data":null,"t_data":null} (3 rows) カラム値が null の場合は JSON の null に変換 テーブル全体を JSON 化した例
  • 51. 51 JSON から PostgreSQL 行への展開 jsonb=# select * from json_each_text('{"id": 2, "age": 59, "name": {"last": "Lane", "first": "Tom"}}'); key | value ------+---------------------------------- id | 2 age | 59 name | {"last": "Lane", "first": "Tom"} (3 rows) ※ 内側のキー ("first", "last") と値は展開しない。 ※ key, value という固定の列名として返却される。 ※ key も value も TEXT 型として返却される。
  • 52. 52 キー集合の取得 jsonb=# TABLE test; {"id": 1, "name": {"first": "Oleg"}, "distribute": ["GIN", "hstore", "json", "jsonb"]} {"id": 2, "age": 59, "name": {"last": "Lane", "first": "Tom"}} {"id": 3, "name": {"nickname": "nuko"}, "distribute": ["ksj", "neo4jfdw"]} jsonb=# SELECT DISTINCT jsonb_object_keys(data) FROM test; distribute age id name 以下のような JSONB を含む全レコードからキーを取得する。 jsonb_object_keys 関数の結果 ※ 内側のキー ("first", "last") は取得できない点に注意! ※ 自分で Outer キーを指定して取得した JSONB に対して   jsonb_object_keys を発行することは可能。
  • 55. 55 JSON と JSONB の格納状態例 00001fb0 95 7b 22 61 61 61 22 20 3a 20 22 41 41 41 41 22 |.{"aaa" : "AAAA"| 00001fc0 2c 20 22 62 62 62 31 22 20 3a 20 7b 22 63 63 63 |, "bbb1" : {"ccc| 00001fd0 63 22 3a 20 22 43 43 43 43 31 22 7d 2c 20 22 62 |c": "CCCC1"}, "b| 00001fe0 62 62 32 22 20 3a 7b 22 63 63 63 63 22 20 3a 20 |bb2" :{"cccc" : | 00001ff0 22 43 43 43 43 32 22 7d 20 7d 00 00 00 00 00 00 |"CCCC2"} }......| 00001fa0 b5 03 00 00 20 03 00 00 80 04 00 00 00 04 00 00 |.... ...........| 00001fb0 00 04 00 00 00 16 00 00 50 18 00 00 50 61 61 61 |........P...Paaa| 00001fc0 62 62 62 31 62 62 62 32 41 41 41 41 00 01 00 00 |bbb1bbb2AAAA....| 00001fd0 20 04 00 00 80 05 00 00 00 63 63 63 63 43 43 43 | ........ccccCCC| 00001fe0 43 31 00 00 00 01 00 00 20 04 00 00 80 05 00 00 |C1...... .......| 00001ff0 00 63 63 63 63 43 43 43 43 32 00 00 00 00 00 00 |.ccccCCCC2......| {"aaa" : "AAAA", "bbb1" : {"cccc": "CCCC1"}, "bbb2" :{"cccc" : "CCCC2"} } 入力 JSON 文字列 JSON 型の格納状態 JSONB 型の格納状態 入力文字列そのまま バイナリ化された データが格納される PostgreSQL 9.4 で確認
  • 60. 60 JSONB データ型 JSON 自体にはデータ型の概念がある。 PostgreSQL の JSONB 型もデータ型に一部対応している。 JSON 型 対応する PostgreSQL 型 備考 文字型 text エンコーディングの問題は注意。 なお、キーは文字型扱い。 数値型 numeric 浮動小数点型の NaN や Infinity の表記は 許容されない。 時刻型 (未対応) PostgreSQL では文字列扱い。 真偽値 boolean 小文字の true/false のみ許容。 (on/off とかもダメ ) null - 小文字 null のみ許容。 SQL NULL とは別概念。
  • 61. 61 JSONB は入力した JSON 文字列は保持されない。 JSON は入力文字列を そのまま保持する。
  • 62. 62 JSONB 入力結果が保持されない例 (数値型) jsonb=# INSERT INTO jsonb_t VALUES (1, '{"key":1, "value":100}'), (2, '{"key":2, "value":100.0}'), (3, '{"key":3, "value":1.00e2}'), (4, '{"key":4, "value":1.000e2}') ; INSERT 0 4 jsonb=# SELECT * FROM jsonb_t ; id | data ----+---------------------------- 1 | {"key": 1, "value": 100} 2 | {"key": 2, "value": 100.0} 3 | {"key": 3, "value": 100} 4 | {"key": 4, "value": 100.0} (4 rows) 小数なしの numeric として同値 小数点ありの numeric として同値 指数表記でなくなる
  • 63. 63 JSON だと単に文字列として 格納されているだけなので、 入力形式そのままで出力される jsonb=# INSERT INTO json_t VALUES jsonb-# (1, '{"key":1, "value":100}'), jsonb-# (2, '{"key":2, "value":100.0}'), jsonb-# (3, '{"key":3, "value":1.00e2}'), jsonb-# (4, '{"key":4, "value":1.000e2}') jsonb-# ; INSERT 0 4 jsonb=# SELECT * FROM json_t; id | data ----+---------------------------- 1 | {"key":1, "value":100} 2 | {"key":2, "value":100.0} 3 | {"key":3, "value":1.00e2} 4 | {"key":4, "value":1.000e2} (4 rows)
  • 64. 64 JSONB 入力結果が保持されない例 (重複キー、キー名の順序) jsonb=# SELECT '{"key_z":99, "key_q": 20, "key_q" :25, "key_a" : 3}'::json, '{"key_z":99, "key_q": 20, "key_q" :25, "key_a" : 3}'::jsonb; -[ RECORD 1 ]---------------------------------------------- json | {"key_z":99, "key_q": 20, "key_q" :25, "key_a" : 3} jsonb | {"key_a": 3, "key_q": 25, "key_z": 99} jsonb=# SELECT '{"key_x":[ 1, 400, 8888, 2, 99, 25, 3]}'::json, '{"key_x":[ 1, 400, 8888, 2, 99, 25, 3]}'::jsonb ; -[ RECORD 1 ]---------------------------------- json | {"key_x":[ 1, 400, 8888, 2, 99, 25, 3]} jsonb | {"key_x": [1, 400, 8888, 2, 99, 25, 3]} 同一階層で重複したキーがある場合、後に記述したもののみ有効となる。 また、キー名でソートされている。 配列の場合、順序は保証される。 ”最初の key_q”:20 の 組み合わせはなくなる。
  • 65. 65 JSONB 入力結果が保持されない例 (空白の扱い) jsonb=# SELECT '{"key_z" : 99, "key q": 20, "key_a" : "aa aa"}'::json, '{"key_z" : 99, "key q": 20, "key_a" : "aa aa"}'::jsonb; -[ RECORD 1 ]-------------------------------------------------- json | {"key_z" : 99, "key q": 20, "key_a" : "aa aa"} jsonb | {"key q": 20, "key_a": "aa aa", "key_z": 99} キーまたは値でない JSON 文字列中の空白は、 JSONB では無視される。 また、 JSONB の検索結果として出力される JSON 文字列では キーと値のセパレータである“ :” の後に 1 つ空白文字を入れる という規則で文字列を生成している。
  • 66. 66 JSONB 専用演算子 (9.4) 演算子 意味 <@ 左辺の JSON が右辺のキー&値の組を含むかを 評価する。 @> 右辺の JSON が左辺のキー&値の組を含むかを 評価する。 ? 左辺の JSON が右辺の(一つの)キーまたは要 素を含むかどうかを評価する。 |? 左辺の JSON が右辺のキーまたは要素を 1 つで も含むかどうかを評価する。( ANY 評価) &? 左辺の JSON が右辺のキーまたは要素を全て含 むかどうかを評価する。( ALL 評価)
  • 67. 67 JSONB 専用演算子 (9.5 追加 ) 演算子 意味 || 指定したキーが存在しなければ、キー&値の組 み合わせを追加し、存在すれば指定したキー& 値の組み合わせを置換する。 - 指定したキーと合致するキー&値の組み合わせ を削除する。。 - 指定した番号の配列要素を削除する。 #- 指定したパスに合致するキー&値の組み合わ せ、または配列要素を削除する。 文書の部分更新が可能に!
  • 68. 68 <@ 演算子と GIN GIN インデックスとの 組み合わせで、お手軽な インデックスの作成が可能
  • 69. 69 GIN インデックス 汎用転置インデックス 配列型での利用 全文検索等でも利用 ※ これも JSONB と同じ開発チームで開発している。 http://www.sai.msu.su/~megera/wiki/Gin
  • 70. 70 <@ と GIN インデックス JSONB カラム自体に GIN インデックスを設定 jsonb=# SELECT data FROM jsonb_t LIMIT 1; data ------------------------------------------------------------------------------ -- ---------------------------------------------------------- {"Id": 0, "Email": "Laverna@junius.io", "Country": "Paraguay", "Full Name": "Ca rolyne Kohler", "Created At": "1987-08-21T18:42:02.269Z"} (1 row) jsonb=# CREATE INDEX jsonb_idx ON jsonb_t USING gin (data jsonb_ops); CREATE INDEX jsonb=# d jsonb_t Unlogged table "public.jsonb_t" Column | Type | Modifiers --------+---------+------------------------------------------------------ id | integer | not null default nextval('jsonb_t_id_seq'::regclass) data | jsonb | Indexes: "jsonb_idx" gin (data) JSONB 型用の GIN インデックス メソッドの指定 実は指定しなくても 後述の演算子は OK
  • 71. 71 この状態で @> 演算子(右辺にはキーと値の組み合わせ) を使うと GIN インデックスによる効率的な検索が可能になる JSONB カラムに <@ 演算子で条件を記述 jsonb=# EXPLAIN SELECT data->'Full Name' as fullname, data->'Country' as country FROM jsonb_t WHERE data @> '{"Country" : "Monaco"}'; QUERY PLAN -------------------------------------------------------------------------- Bitmap Heap Scan on jsonb_t (cost=20.08..54.18 rows=10 width=160) Recheck Cond: (data @> '{"Country": "Monaco"}'::jsonb) -> Bitmap Index Scan on jsonb_idx (cost=0.00..20.07 rows=10 width=0) Index Cond: (data @> '{"Country": "Monaco"}'::jsonb) Planning time: 0.074 ms (5 rows) <@ と GIN インデックス
  • 72. 72 JSONB カラムに <@ 演算子で条件を記述(検索結果) jsonb=# SELECT data->'Full Name' as fullname, data->'Country' as country FROM jsonb_t WHERE data @> '{"Country" : "Monaco"}'; fullname | country --------------------------+---------- "Romaine Hickle" | "Monaco" "Mr. Joana Huel" | "Monaco" "Jeff Wilkinson" | "Monaco" (以下略) <@ と GIN インデックス "Country” が "Monaco” の行だけ選択されている。
  • 73. 73 今までの JSON 型でも "->“,“->>“ 演算子と 関数インデクスの組み合わせで btree インデクスによる インデクス検索は出来たが @> + GIN の組み合わせは キーが不定でも有効!
  • 74. 74 しかも、 PostgreSQL 9.4 で は GIN インデックスのサイズ 縮小 / 性能改善も行われている のでさらに効果的! (参考: GIN インデックスの改善も JSONB 型と同じメンバが実施している)
  • 76. 76 JSON 型と JSONB 型の処理 JSON 型と JSONB 型の データ格納 データ取得 JSON 関数処理 の処理イメージを次ページ以降に示す。
  • 77. 77 JSON 型の処理イメージ JSON 文字列 JSON ツリーJSON パーサ JSON 型 (文字列) JSON 文字列 関数の結果 (そのまま出力) 格納時 取り出し時 JSON 関数 JSON パーサ関数処理 JSON ツリー パーサで生成した JSON ツリーは 捨てられる PostgreSQL ストレージ 再度パースが 必要
  • 78. 78 JSONB 型の処理イメージ JSON 文字列 JSON ツリーJSON パーサ JSONB 型 (バイナリ) JSON 文字列 関数の結果 文字列化 格納時 取り出し時 JSONB 関数 関数処理 バイナリを直接解釈して 関数実行 パーサは動作しない PostgreSQL ストレージシリアライズ
  • 79. 79 JSON ツリー parseState=0 pstate res res type=jbvObject val.object.nPairs=3 key type=jbvString pair[0] val type=jbvString len=3 val AAA len=2 val aa key type=jbvString val type=jbvString pair[1] key type=jbvString pair[2] len=2 val bb ・・・ 上記の JSON 文字列をパースすると 以下のようなツリー構造が生成される ※ PostgreSQL 9.4-beta2 の場合 {"aa":"AAA","bb":"BBB","cc":"CCC"}
  • 80. 80 格納サイズ さっき説明した JSON と JSONB の 処理内容から格納サイズを予想すると 以下のようになる。 格納サイズは JSON のほうが小さい? ( JSONB はツリー構造情報も保持)
  • 81. 81 以下のような JSON データ { "Email": "Laverna@junius.io", "Created At": "1987-08- 21T18:42:02.269Z", "Country": "Paraguay","Id":"0", "Full Name": "Carolyne Kohler"} 測定内容 TEXT/JSON/JSONB カラムのみをもつテーブルを作成 上記 1 万件を 10 回 COPY した後の テーブルサイズを pg_relation_size() で測定
  • 82. 82 格納サイズ TEXT 型と JSON 型のサイズは同じ JSONB は JSON 型と比較すると 7 %増加 PostgreSQL 9.4 で確認 TEXT 型 JSON 型 JSONB 型 0 2,000,000 4,000,000 6,000,000 8,000,000 10,000,000 12,000,000 14,000,000 16,000,000 18,000,000 20,000,000 18,366,464 18,366,464 19,587,072 10 万件ロード時のテーブルサイズ
  • 83. 83 インデックスサイズ JSON 型のキーに対する btree 関数インデックス Vs JSONB の GIN インデックス さっきの JSON 型データの 5 種のキーに 対する btree インデックスの総サイズと JSONB 型の GIN インデックスサイズを比較してみる。
  • 84. 84 各キーから値を取得する btree インデックス群を設定 インデックスサイズ JSONB 列自体に GIN インデックスを設定 CREATE INDEX jsonb_id_idx ON jsonb_t USING btree ((data->>'Id')); CREATE INDEX jsonb_fullname_idx ON jsonb_t USING btree ((data->>'Full Name')); CREATE INDEX jsonb_email_idx ON jsonb_t USING btree ((data->>'Email')); CREATE INDEX jsonb_created_idx ON jsonb_t USING btree ((data->>'Created At')); CREATE INDEX jsonb_country_idx ON jsonb_t USING btree ((data->>'Country')); CREATE INDEX jsonb_data_idx ON jsonb_t USING gin (data jsonb_ops);
  • 85. 85 インデックスサイズ 全てのキーに btree インデックスを 設定するより GIN インデックスのほうが インデックスサイズは大幅に小さくなる。 PostgreSQL 9.4 で確認 JSONB+btree JSONB+GIN 0 5,000,000 10,000,000 15,000,000 20,000,000 25,000,000 18,366,464 19,587,072 18,055,168 6,897,664 btee 式インデックスサイズと GINインデックスサイズ pg_relation_size() pg_indexes_size()
  • 86. 86 性能比較 さっき説明した JSON と JSONB の 処理内容から処理性能を予想すると 以下のようになる。 格納処理は JSON のほうが高速 単なる SELECT は JSON のほうが高速? JSON 関数を使った場合は JSONB が高速
  • 87. 87 測定環境 PC:Let's note SX2(SSD) OS:CentOS 6.3( メモリ 4GB) PostgreSQL パラメータ shared_buffers=128MB checkpoint_segments=30
  • 88. 88 以下のような JSON データ { "Email": "Laverna@junius.io", "Created At": "1987-08- 21T18:42:02.269Z", "Country": "Paraguay", "Id": 0, "Full Name": "Carolyne Kohler"} 測定内容 JSON/JSONB カラムをもつテーブルを UNLOGGED で作成 上記 1 万件を 10 回 COPY したときの平均性能 SELECT(10 万件 ) の平均性能 SELECT(10 万件 ) + JSON 演算子を使ったときの平均性能 btree vs GIN インデックス検索性能
  • 89. 89 COPY 処理時間 TEXT と JSON の差分が 10000 件分の JSON パース時間? JSON と JSONB の差分が 10000 件文のシリアライズ時間? GIN インデックスありの場合はかなり遅くなる。 PostgreSQL 9.4 で測定 TEXT JSON JSONB JSONB + GIN 0.00 50.00 100.00 150.00 200.00 250.00 300.00 23.67 31.00 74.68 269.80 COPY 平均処理時間 (10000 件:単位 ms)
  • 90. 90 JSON 関数なし JSON 関数あり 0 20 40 60 80 100 120 140 160 180 200 20.27 173.16 17.79 50.01 全件 SELECT 時間( 10 万件:単位 ms ) JSON 型 JSONB 型 SELECT 処理時間 単なる SELECT はほとんど差はない? JSON 関数を使用した場合の性能差は明確。 PostgreSQL 9.4 で確認
  • 91. 91 btree vs GIN EXPLAIN ANALYZE SELECT * FROM jsonb_t WHERE data->>'Country' = 'Monaco'; Bitmap Heap Scan on jsonb_t (cost=12.29..1240.26 rows=500 width=161) (actual time=0.180..0.692 rows=310 loops=1) Recheck Cond: ((data ->> 'Country'::text) = 'Monaco'::text) Heap Blocks: exact=280 -> Bitmap Index Scan on jsonb_country_idx (cost=0.00..12.17 rows=500 width=0) (actual time=0.112..0.112 rows=310 loops=1) Index Cond: ((data ->> 'Country'::text) = 'Monaco'::text) Planning time: 0.607 ms Execution time: 0.767 ms (7 rows) EXPLAIN ANALYZE SELECT * FROM jsonb_t WHERE data @> '{"Country":"Monaco"}'; Bitmap Heap Scan on jsonb_t (cost=28.77..362.50 rows=100 width=161) (actual time=1.709..2.502 rows=310 loops=1) Recheck Cond: (data @> '{"Country": "Monaco"}'::jsonb) Heap Blocks: exact=280 -> Bitmap Index Scan on jsonb_data_idx (cost=0.00..28.75 rows=100 width=0) (actual time=1.630..1.630 rows=310 loops=1) Index Cond: (data @> '{"Country": "Monaco"}'::jsonb) Planning time: 0.086 ms Execution time: 2.566 ms (7 rows) GIN インデックス使用時 btree 式インデックス使用時 GIN より btree 式インデックスのほうが若干速い
  • 92. 92 測定結果まとめ 格納: JSON が高速 SELECT :ほぼ同じ? JSON 関数: JSONB が高速 GIN より btree 式インデックスが高速
  • 93. 93 格納効率優先なら JSON 検索効率優先なら JSONB 入力形式を保持するなら JSON ⇒ だいたいの場合、 JSONB で OK? 結局、 JSON と JSONB は どう使い分けるのか?
  • 94. 94 XML, hstore, JSON/JSONB 比較 データ型 表現能力 格納サイズ 参照性能 更新性能 XML ◎ △ △ △ hstore △ ○ ◎ ◎ JSON ○ ○ ○ ◎ JSONB ○ ○ ◎ ○ XML は表現能力は高いが扱いにくい hstore はシンプルだが速い JSONB は良いとこ取り? ⇒ 用途で使い分け可能
  • 96. 96 測定環境とモデル Let's note SX4 VMWare + CentOS 7.0 PostgreSQL 9.5-devel Scale Factor = 10 ( accounts:100 万件) カスタムクエリ機能を使用 ホントは AWS EC2 の いい感じの インスタンスを 使いたかっけど 間に合わなかった ※ 各型に対応したカスタムクエリについては付録 1 を参照
  • 98. 98 XML のロードとインデックス作成は遅い JSON と hstore はやや速い XML hstore JSON JSONB 0.000 5000.000 10000.000 15000.000 20000.000 25000.000 30000.000 ロード時間およびインデックス作成時間 インデックス作成時間 (ms) ロード時間 (ms) ロード時間とインデックス作成時間
  • 99. 99 このモデルだとカラム数が少ないから JSONB はやや冗長になるのかも XML hstore JSON JSONB 0 50000000 100000000 150000000 200000000 250000000 テーブルサイズ / インデックスサイズ インデックスサイズ テーブルサイズ テーブルサイズとインデックスサイズ
  • 100. 100 全件更新の性能も XML は非常に悪い hstore はかなり速い JSONB-9.5 部分更新の効果も見える XML hstore JSON JSONB JSONB-9.5 0 10000 20000 30000 40000 50000 60000 70000 80000 76042 5292 12508 12241 8829 100 万件更新時間 (ms) accounts(100 万件)全件更新時間
  • 101. 101 pgbench 走行 トランザクション内容 ・ UPDATE 3 回 ・ SELECT 1 回 ・ INSERT 1 回 同時接続数 =2 走行時間 =300 秒
  • 102. 102 XML は非常に遅い hstore は速い JSON/JSONB はこのモデルだとあまり差はない。 XML hstore JSON JSONB JSONB-9.5 通常レコード 0 200 400 600 800 1000 1200 1400 1600 1800 2000 467.436 1360.219 1066.437 1149.694 1103.781 1708.898 pgbench スループット (tps) pgbench 走行 スループット
  • 103. 103 参照も XML は遅い hstore は速い このモデルだと思ったより JSON/JSONB の差がない? UPDATE accounts SELECT accounts UPDATE tellers UPDATE branches INSERT history END 0 0.2 0.4 0.6 0.8 1 1.2 1.4 1.6 1.8 2 pgbench レイテンシ (ms) XML hstore JSON JSONB JSONB-9.5 通常レコード pgbench 走行 レイテンシ
  • 105. 105 様々なログの収集 ( fluentd との組み合わせ等) JSON 化 ログ ログ ログ JSONB カラムに格納 GIN/btree インデックス設定 ログ検索 アプリケーション syslog 等 ログ 既存の表JSONB 表
  • 106. 106 微妙なテーブル設計の救済? CREATE TABLE foo { id integer primary key, name text, ・・・ memo1 text, memo2 text, memo3 text, ・・・ memo100 text } CREATE TABLE foo { id integer primary key, name text, ・・・ memo jsonb } 可変の個数 設定されるような 予備カラム群 JSONB 型に まとめてしまう ※ きちんと設計をしていれば不要だろうけど・・・
  • 111. 111 データ管理単位 PostgreSQL MongoDB データベースクラスタ ( --dbpath 指定フォルダ) データベース データベース スキーマ (対応なし) テーブル コレクション レコード 文書 他の NoSQL 系に比べると、 RDBMS に比較的近い印象あり。
  • 112. 112 CRUD 操作 操作 PostgreSQL MongoDB 挿入 ○ ○ 読み込み ○ ○ 更新(全体) ○ ○ 更新(部分) ✗( ~ 9.4) ○ UPSERT ✗( ~ 9.4) ○ 削除 ○ ○ 部分更新の有無がポイント ⇒ 逆に言えば更新がなければ差異はない
  • 113. 113 挿入 PostgreSQL の場合 MongoDB の場合 INSERT INTO テーブル名 VALUES ( JSON 文字列 ) db. コレクション名 .insert( JSON 文字列 )
  • 114. 114 読み込み PostgreSQL の場合 MongoDB の場合 SELECT JSONB 列 FROM テーブル名 [WHERE 条件式 ] db. コレクション名 .find([ 条件式 ]) ->>' キー名 ' 演算子 値 @> ' キー名 : 値 '
  • 115. 115 更新(全体) PostgreSQL の場合 MongoDB の場合 UPDATE テーブル名 SET ( JSON 文字列 ) db. コレクション名 .update( 条件式 ,JSON 文字列 )
  • 116. 116 更新(部分) PostgreSQL の場合 (9.5 以降 ) UPDATE テーブル名 SET 値 = 値 || '( 追加するキーと値 )' UPDATE テーブル名 SET 値 = 値 || '( 追加するキーと値 )' UPDATE テーブル名 SET 値 = 値 - '( 削除するキー名 )' キー追加 キー更新 キー削除
  • 117. 117 更新(部分) MongoDB の場合 db. コレクション名 .update( 条件式 , {$set:{ キー : 値 }}) db. コレクション名 .update( 条件式 , {$set:{ キー : 値 }}) db. コレクション名 .update( 条件式 , {$unset:{ キー : 値 }} キー追加 キー更新 キー削除
  • 118. 118 削除 PostgreSQL の場合 MongoDB の場合 DELETE テーブル名 [ 条件式 ] あるいは TRUNCATE TABLE テーブル名 db. コレクション名 .remove( 条件式 )
  • 119. 119 高度な検索 操作 PostgreSQL MongoDB ソート ○ ○ 重複排除 ○ ○ グルーピング ○ ○ 集約演算 ○ ○ PostgreSQL の場合は SQL で上記を実現 MongoDB は MapReduce や Aggregation-Framework で実現
  • 120. 120 レプリケーション 機能 PostgreSQL MongoDB レプリケーション 方式 本体機能 マスタースレーブ 本体機能 マスタースレーブ 同期方式 同期 / 非同期 非同期 フェールオーバ機構 他クラスタ製品 ・ pgpool-II ・ Pacemaker 本体機能
  • 121. 121 シャーディング 機能 PostgreSQL MongoDB シャーディング 方式 本体機能にはない。 他製品でカバー。 (pgpool-II,pg_shard 等 ) 今後は、外部表継承による シャーディング相当が可能に なるかも!? (9.5 だとまだ JSONB への適用は難しい ) 本体機能 クライアントドライバ レプリケーション / シャーディングに関しては、 最初からそれを前提として開発されている MongoDB のほうが扱いやすいのかも?
  • 122. 122 性能 YCSB ベンチマークを用いて PostgreSQL JSONB と MongoDB の性能を比較してみた 用途が異なるものを同じベンチマークで 測定する意味はあるのか、というツッコミは あるかと思いますが、参考までに測定しました。 ※ JSONB 対応 YCSB については付録 2 を参照
  • 123. 123 YCSB 測定 AWS EC2(m3.2xlarge on-demand) CPU 数 8 、メモリ 30GB PostgreSQL 9.4.1 (yum) PostgreSQL の環境設定は checkpoint_segments=30 に変更したくらい。 MongoDB 3.0.2 (yum) MongoDB は特に設定なし。
  • 124. 124 YCSB 測定 測定内容 ロード (load)⇒10 万件 更新と参照 (workload-a ) 参照のみ( workload-c ) ⇒ それぞれ 10 万回実行
  • 125. 125 YCSB 測定 ロード処理 0 5 10 15 20 25 0 2000 4000 6000 8000 10000 12000 14000 16000 YCSB load Throughput PostgreSQL 9.4 MongoDB 3.0 number of concurrency Throughput(ops/sec)
  • 126. 126 YCSB 測定 更新と参照 0 5 10 15 20 25 0 5000 10000 15000 20000 25000 YCSB load Workload-a Throughput PostgreSQL 9.4 MongoDB 3.0 number of concurrency Throughput(ops/sec) 10000(opt/sec) 程度になるはず?
  • 127. 127 YCSB 測定 参照のみ 0 5 10 15 20 25 0 10000 20000 30000 40000 50000 60000 YCSB workload-c Throughput PostgreSQL 9.4 MongoDB 3.0 number of concurrency Throughput(ops/sec)
  • 128. 128 YCSB 測定 まとめ PostgreSQL は CPU 数があれば同時実行 数が多い場合にスループット向上。 MongoDB は CPU 数が多いマシンで動か しても同時実行性能は上がらない。 ⇒ その代わりシャードで書き込み分散?
  • 130. 130 PostgreSQL と NoSQL DBMS 得意 不得意 PostgreSQL スケールアップ SQL との連携 ( 結 合など ) トランザクション スケールアウト 集計処理 MongoDB スケールアウト 書き込み並列化 集計処理? スケールアップ トランザクション 結合 それぞれ向き不向きがある
  • 131. 131 サーバ構成 / スペック次第? コア数が多いサーバが用意できるなら PostgreSQL を MongoDB の代わりに 使うという解もあり? ほどほどのスペックのマシンを多数用意 できるなら MongoDB ?
  • 132. 132 PostgreSQL(+JSONB) の強み 既存の PostgreSQL 環境に 新たに JSONB 型を追加することで SQL レベルで統一して扱えるのは強み。 PostgreSQL + MongoDB 構成を PostgreSQL のみの構成にできるかも?
  • 134. 134 PostgreSQL は非構造化データを 扱う手段がいくつかある。 XML/hstore/JSON/JSONB の どれを使うかは要件次第 要件によっては、 JSON 文書格納先として MongoDB 等の NoSQL ではなく、 PostgreSQL を使うのもありうる。
  • 137. 137 Q. JSONB って日本語扱える? A. キーにも値にも日本語は使えます。 ただし、サーバエンコーディングが UTF-8 環境で使うのが無難そう。 日本語キーのパスを使って日本語を取得する例 jsonb=# SELECT '{" 種別 ":" ラーメン ", " 値段 " : 650, " スープ ":" 豚骨醤油 ", " トッピング ":[" チャーシュー "," ほうれん草 "," 海苔 "," 葱 "]}'::jsonb #> '{ トッピ ング , 2}'; ?column? ---------- " 海苔 " (1 row)
  • 138. 138 Q. JSONB ってトランザクションに対応 しているの? A. してます。 JSONB も PostgreSQL 上 では他のデータ型と一緒の扱いです。
  • 139. 139 Q. PostgreSQL の クライアントライブラリでは JSONB を オブジェクトとして扱えるの? A. すいません、きちんと調べてません。 少なくとも libpq としては特別な扱いは してないみたいです。
  • 140. 140 Q. 結局、どういうときに JSONB 型を使えばいいの? A. 開発時にスキーマが決定できない情報 を管理する場合。 ( XML や hstore も検討してみる) あるいは、外部データとして JSON を 使っていて、それを PostgreSQL で管理 したい場合とか・・・?
  • 141. 141 Q. JSON データ管理なら MongoDB とかじゃダメなの? A. それも一つの選択肢です。 スケールアウト重視なら MongoDB 。 スタートアップ開発にも向いている。 トランザクションなど堅牢性の重視や SQL アクセスしたいなら PostgreSQL 。
  • 142. 142 参考情報 ●“PostgreSQL 9.4 Documentation” http://www.postgresql.org/docs/9.4/static/index.html ●“Schema-less PostgreSQL” http://www.sraoss.co.jp/event_seminar/2014/20140911_pg94_schemales s.pdf ●SRA OSS. “PostgreSQL 9.4 評価検証報告” http://www.sraoss.co.jp/event_seminar/2014/20140911_pg94report.pdf ●第 20 回しくみ+アプリケーション勉強会 "PostgreSQL の KVS hstore の紹介” http://www.postgresql.jp/wg/shikumi/study20_materials/hstore_introduct ion/view ●EDB 社ブログ “ Open Enterprise: The PostgreSQL Open Source Database Blog from EnterpriseDB” http://blogs.enterprisedb.com/2014/09/24/postgres-outperforms-mongodb -and-ushers-in-new-developer-reality/ ●”7 つのデータベース 7 つの世界” ISBN 978-274-06907-6
  • 143. 143 付録 付録 1 pgbench モデル用クエリ 付録 2 YCSB JSONB 用クエリ
  • 146. 146 pgbench モデルのテーブル bench=# d pgbench_accounts; Table "public.pgbench_accounts" Column | Type | Modifiers ----------+---------------+----------- aid | integer | not null bid | integer | abalance | integer | filler | character(84) | Indexes: "pgbench_accounts_pkey" PRIMARY KEY, btree (aid) 通常の pgbench モデル XML モデル bench_xml=# d accounts Table "public.accounts" Column | Type | Modifiers --------+------+----------- data | xml | Indexes: "xml_aid_idx" btree (((xpath('/accounts/aid/text()'::text, data)::text[])[1]::integer))
  • 147. 147 pgbench モデルのテーブル bench_hstore=# d accounts Table "public.accounts" Column | Type | Modifiers --------+--------+----------- data | hstore | Indexes: "hstore_aid_idx" btree (((data -> 'aid'::text)::integer)) hstore モデル JSONB モデル bench_json=# d accounts Table "public.accounts" Column | Type | Modifiers --------+------+----------- data | json | Indexes: "json_aid_idx" btree (((data ->> 'aid'::text)::integer)) JSON モデル ( JSON モデルとだいたいおなじ) 今回は GIN インデックスパターンは 使いません
  • 148. 148 pgbench モデルのクエリ BEGIN; UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; SELECT abalance FROM pgbench_accounts WHERE aid = :aid; UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); END; 通常の pgbench モデル(抜粋)
  • 149. 149 pgbench モデルのクエリ UPDATE accounts SET data = xmlelement(name accounts, null, xmlelement(name aid, null, ((xpath('/accounts/aid/text()', data))::text[])[1]), xmlelement(name bid, null, ((xpath('/accounts/bid/text()', data))::text[])[1]), xmlelement(name abalance, null, (((xpath('/accounts/abalance/text()', data))::text[])[1])::int + :delta ), xmlelement(name filler, null, ((xpath('/accounts/filler/text()', data))::text[])[1])) WHERE (xpath('/accounts/aid/text()', data)::text[])[1]::int = :aid; SELECT ((xpath('/accounts/abalance/text()', data))::text[])[1]::int FROM accounts WHERE ((xpath('/accounts/aid/text()', data))::text[])[1]::int = :aid; INSERT INTO history (data) VALUES ( xmlelement(name history, null, xmlelement(name tid, null, :tid), xmlelement(name bid, null, :bid), xmlelement(name aid, null, :aid), xmlelement(name delta, null, :delta), xmlelement(name mtime, null, CURRENT_TIMESTAMP), xmlelement(name filler, null, ' ') )); XML の pgbench モデル(抜粋)
  • 150. 150 pgbench モデルのクエリ UPDATE accounts SET data = data || hstore('abalance', ((data->'abalance')::int + :delta)::text ) WHERE (data->'aid')::int = :aid; SELECT data->'abalance' FROM accounts WHERE (data->'aid')::int = :aid; INSERT INTO history (data) VALUES ( hstore( ARRAY['tid','bid','aid','delta','mtime', 'filler'], ARRAY[ ( :tid )::text, ( :bid )::text, ( :aid )::text, ( :delta )::text, CURRENT_TIMESTAMP::text, ' ']) ); hstore の pgbench モデル(抜粋)
  • 151. 151 pgbench モデルのクエリ UPDATE accounts SET data = json_build_object( 'aid', (data->>'aid')::int, 'bid', (data->>'bid')::int, 'abalance', (data->>'abalance')::int + :delta , 'filler', data->>'filler') WHERE (data->>'aid')::int = :aid; SELECT data->>'abalance' FROM accounts WHERE (data->>'aid')::int = :aid; INSERT INTO history (data) VALUES ( json_build_object( 'tid', :tid, 'bid', :bid, 'aid', :aid, 'delta', :delta, 'mtime', CURRENT_TIMESTAMP, 'filler', ' ')); JSON の pgbench モデル(抜粋)
  • 152. 152 pgbench モデルのクエリ UPDATE accounts SET data = json_build_object( 'aid', (data->>'aid')::int, 'bid', (data->>'bid')::int, 'abalance', (data->>'abalance')::int + :delta , 'filler', data->>'filler')::jsonb WHERE (data->>'aid')::int = :aid; SELECT data->>'abalance' FROM accounts WHERE (data->>'aid')::int = :aid; INSERT INTO history (data) VALUES ( json_build_object('tid', :tid, 'bid', :bid, 'aid', :aid, 'delta', :delta, 'mtime', CURRENT_TIMESTAMP, 'filler', ' ')::jsonb); JSONB の pgbench モデル(抜粋)
  • 153. 153 pgbench モデルのクエリ UPDATE accounts SET data = data || jsonb_build_object('abalance', (data->>'abalance')::int + :delta) WHERE (data->>'aid')::int = :aid; SELECT data->>'abalance' FROM accounts WHERE (data->>'aid')::int = :aid; INSERT INTO history (data) VALUES ( jsonb_build_object( 'tid', :tid, ' bid', :bid, 'aid', :aid, 'delta', :delta, 'mtime', CURRENT_TIMESTAMP, 'filler', ' ')); JSONB(9.5) の pgbench モデル(抜粋) PostgreSQL 9.5 では hstore 型と似たような 部分更新の演算子 ( || ) が追加された! (あと jsonb_build_object が追加されたっぽい)
  • 155. 155 YCSB とは Yahoo! Cloud Service Benchmark の略 いろんな NoSQL 系に 対応したベンチマーク https://github.com/brianfrankcooper/YCSB
  • 156. 156 YCSB JSONB 対応版 改造方針 YCSB JSONB 版はないので JDBC 版の SQL を JSONB を 使うモデルに合わせて修正
  • 157. 157 YCSB JSONB 対応版 JDBC 版テーブル定義 CREATE TABLE usertable (ycsb_key text, field1 text, field2 text, field3 text, field4 text, field5 text, field6 text, field7 text, field8 text, field9 text, field10 text); CREATE INDEX ycsb_key_idx ON usertable (ycsb_key); JSONB 版テーブル定義 CREATE TABLE usertable(data jsonb); CREATE INDEX ycsb_pk_idx ON usertable USING btree ((data- >'YCSB_KEY'));
  • 158. 158 YCSB JSONB 対応版 JDBC 版挿入 SQL INSERT INTO usertable VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) JSONB 版挿入 SQL INSERT INTO usertable VALUES(json_build_object('YCSB_KEY', ?, 'FIELD1', ?, 'FIELD2', ?, 'FIELD3', ?, 'FIELD4', ?, 'FIELD5', ?, 'FIELD6', ?, 'FIELD7', ?, 'FIELD8', ?, 'FIELD9', ?, 'FIILD10', ?)::jsonb) 9.5-devel だと jsonb_build_object() が あるので、 JSONB への キャストは不要
  • 159. 159 YCSB JSONB 対応版 JDBC 版更新 SQL UPDATE usertable SET FIELD1 = ? WHERE YCSB_KEY = ? JSONB 版更新 SQL UPDATE usertable SET data = json_build_object('YCSB_KEY', data- >>'YCSB_KEY', 'FIELD1', ?, 'FIELD2', data->>'FIELD2', 'FIELD3', data->>'FIELD03', 'FIELD4', data->>'FIELD4', 'FIELD5', data- >>'FIELD5', 'FIELD6', data->>'FIELD6', 'FIELD7', data->>'FIELD7', 'FIELD8', data->>'FIELD8', 'FIELD9', data->>'FIELD9', 'FIELD10', data->>'FIELD10')::jsonb WHERE data->>'YCSB_KEY' = ? 見ただけで うんざりしますよね。
  • 160. 160 YCSB JSONB 対応版 JDBC 版更新 SQL UPDATE usertable SET FIELD1 = ? WHERE YCSB_KEY = ? PostgreSQL 9.5 JSONB 版更新 SQL UPDATE usertable SET data = data || jsonb_build_object('FIELD1', ?) WHERE data->>'YCSB_KEY' = ? まだ試してないけど 9.4 版と比べると 非常にスッキリ書けるはず 参考 9.5-devel だと jsonb_build_object() が あるので、 JSONB への キャストは不要になる
  • 161. 161 YCSB JSONB 対応版 JDBC 版参照 SQL SELECT * FROM usertable WHERE YCSB_KEY = ? JSONB 版参照 SQL SELECT * FROM usertable WHERE data->>'YCSB_KEY' = ?