SlideShare a Scribd company logo
1 of 20
Download to read offline
Nippondanji 氏に
怒られても仕方ない
配列型とJSON型の
使い方 (in PostgreSQL)
Makoto Kuwata
http://www.kuwata-lab.com/
https://github.com/kwatch/
理論から学ぶデータベース実践入門Night LT
copyright 2015 kuwata-lab.com all rights reserved.©
配列型とは?
複数の値を持てるデータ型
集合と違い、順番を保持できるのがポイント
>> select '{34.6582, 139.7020}'::float[];
float8
------------------
{34.6582,139.702}
(1 row)
floatの配列型
へのキャスト
'{ }' が配列の
リテラル
copyright 2015 kuwata-lab.com all rights reserved.©
JSON型とは?
JSONデータを保持できるデータ型
キーと値の組や、構造が不定なデータが保存できる
>> select '{"type":"string", "required":true}'::json;
json
------------------------------------
{"type":"string", "required":true}
(1 row)
JSON型
へのキャスト
copyright 2015 kuwata-lab.com all rights reserved.©
なんで怒られちゃうの?
第一正規化を平然と無視してるから
>> create table bookmark (
id serial primary key
, url text not null
, title text not null
, tags text[]
);
>> select * from bookmark;
id | url | title | tags
----+---------------------+---------+-----------------
1 | https://example.com | Example | {'news','game'}
(1 row)
1つのカラムに複数の値!
しかも順序つき!
copyright 2015 kuwata-lab.com all rights reserved.©
話は変わって、サンプルデータ
ID Name
101 T-Shirt
102 Sweater
Product ID Color Code
101 White W
101 Black B
102 White WH
102 Ivory IV
102 Gray GR
product テーブル coloring テーブル
copyright 2015 kuwata-lab.com all rights reserved.©
joinすると…
ID Name Code Color
101 T-Shirt W White
101 T-Shirt B Black
102 Sweater WH White
102 Sweater IV Ivory
102 Sweater GR Gray
from product join coloring
on product.id = coloring.product_id
copyright 2015 kuwata-lab.com all rights reserved.©
でも欲しいのは…
ID Name (Code, Color)
101 T-Shirt
(W, White)
(B, Black)
102 Sweater
(WH, White)
(IV, Ivory)
(GR, Gray)
1 : N の関係を保ったまま結果を取り出したい
1 : N の形で取得したい
copyright 2015 kuwata-lab.com all rights reserved.©
join
>> select product.id, product.name, c.color
from product
left join coloring c
on product.id = c.product_id
;
id | name | color
-----+---------+-------
101 | T-Shirt | White
101 | T-Shirt | Black
102 | Sweater | White
102 | Sweater | Ivory
102 | Sweater | Gray
(5 rows)
これがうれしくない
copyright 2015 kuwata-lab.com all rights reserved.©
集約関数 array_agg()
>> select product.id, product.name, coloring.color
, array_agg(c.color) as colors
from product
left join coloring c
on product.id = c.product_id
group by product.id, product.name
;
id | name | colors
-----+---------+--------------------
101 | T-Shirt | {White,Black}
102 | Sweater | {White,Ivory,Gray}
(2 rows)
複数の値を配列型で取得!
1 : N で取り出せてる!
copyright 2015 kuwata-lab.com all rights reserved.©
行コンストラクタ
>> select product.id, product.name
, array_agg((c.code, c.color)) as colors
from product
left join coloring c
on product.id = c.product_id
group by product.id, product.name
;
id | name | colors
-----+---------+----------------------------------------
101 | T-Shirt | {"(W,White)","(B,Black)"}
102 | Sweater | {"(WH,White)","(IV,Ivory)","(GR,Gray)"}
(2 rows)
または row(c.code, c.color)
行の配列だけど
パースが必要になる
copyright 2015 kuwata-lab.com all rights reserved.©
集約関数 json_agg()
>> select product.id, product.name
, json_agg((c.code, c.color)) as colors
from product
left join coloring c
on product.id = c.product_id
group by product.id, product.name
;
id | name | colors
-----+---------+-----------------------------
101 | T-Shirt | [{"f1":"W","f2":"White"}, +
| | {"f1":"B","f2":"Black"}]
102 | Sweater | [{"f1":"WH","f2":"White"}, +
| | {"f1":"IV","f2":"Ivory"}, +
| | {"f1":"GR","f2":"Gray"}]
(2 rows)
キーが f1, f2, ... に
なってしまう ;(
copyright 2015 kuwata-lab.com all rights reserved.©
複合型
>> create type code_name as (code text, name text);
>> select product.id, product.name
, json_agg((c.code, c.color)::code_name) as colors
from product
left join coloring c
on product.id = c.product_id
group by product.id, product.name;
id | name | colors
-----+---------+---------------------------------
101 | T-Shirt | [{"code":"W","name":"White"}, +
| | {"code":"B","name":"Black"}]
102 | Sweater | [{"code":"WH","name":"White"}, +
| | {"code":"IV","name":"Ivory"}, +
| | {"code":"GR","name":"Gray"}]
(2 rows)
code_name型へ
キャストすると
キー名が設定される
copyright 2015 kuwata-lab.com all rights reserved.©
相関サブクエリ
>> select product.id, product.name
, ( select json_agg(t.*)
from ( select code, color from coloring c2
where c2.product_id = product.id
) as t
) as colors
from product
left join coloring c
on product.id = c.product_id
group by product.id, product.name
;
...(前ページと同じ結果なので省略)...
うまくいくけど
三重の入れ子は
複雑すぎる…
copyright 2015 kuwata-lab.com all rights reserved.©
問題点
使いやすいとはとても言えない
SQLごとに複合型を定義するわけにもいかないし、

かといって相関サブクエリだと複雑すぎる
DBドライバが配列型やJSON型に未対応
Python用以外は全滅に近い (PHPもRubyもJavaもダメ)、

いったんtext型として取得してからパースする必要あり
copyright 2015 kuwata-lab.com all rights reserved.©
所感
配列型やJSON型を嫌う人は結構いる
第一正規化に反するので、気持ちはわかる
クエリ結果に使うのはいいんじゃない?
大事なのはテーブルが正規化されていることであり、

クエリ結果にまで同じことを求める必要はない
1 : N のまま取り出せるのはやはり便利
とても自然であり、本来あるべき姿

(なぜ今まで出来なかったのか?)
copyright 2015 kuwata-lab.com all rights reserved.©
考察
我々が欲しいのはRelationalなのか?
欲しいのは速くて便利でトランザクションが使えるDBであり、
必ずしもRelationalである必要はない
ID Name Code Color
101 T-Shirt W White
101 T-Shirt B Black
102 Sweate
r
WH White
102 Sweate
r
IV Ivory
102 Sweate
r
GR Gray
ID Name Code,Color
101 T-Shirt (W, White)
(B, Black)
102 Sweater (WH, White)
(IV, Ivory)
(GR, Gray)
正直、tupleの集合より 木構造のほうが便利やで
こんなこと言ってたら
怒られても仕方ない
copyright 2015 kuwata-lab.com all rights reserved.©
まとめ
配列型とJSON型の集約関数を使うと、

1 : N を 1 : N のまま取り出せるよ!
array_agg() と json_agg()
現状では使いやすくはない
複合型の定義も相関サブクエリもしんどい、

DBドライバの対応状況はもっとしんどい
copyright 2015 kuwata-lab.com all rights reserved.©
PostgreSQLに興味がわいたら
2015-11-27(Fri)
詳細は「ポスグレ カンファレンス 2015」でggr
公式バナーなのに「e」が抜けているけど
たぶんデザイナーじゃない人が作ってるし
大目に見てあげて!
copyright 2015 kuwata-lab.com all rights reserved.©
使い方 より 作り方 を知りたいなら
内部構造から学ぶPostgreSQL
̶ 設計・運用計画の鉄則 ̶
勝俣智成、佐伯昌樹、原田登志
技術評論社
2014-09-04
copyright 2015 kuwata-lab.com all rights reserved.©
おしまい

More Related Content

What's hot

コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門Kohei Tokunaga
 
押さえておきたい、PostgreSQL 13 の新機能!! (PostgreSQL Conference Japan 2020講演資料)
押さえておきたい、PostgreSQL 13 の新機能!! (PostgreSQL Conference Japan 2020講演資料)押さえておきたい、PostgreSQL 13 の新機能!! (PostgreSQL Conference Japan 2020講演資料)
押さえておきたい、PostgreSQL 13 の新機能!! (PostgreSQL Conference Japan 2020講演資料)NTT DATA Technology & Innovation
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメYoji Kanno
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターンSoudai Sone
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなKentaro Matsui
 
マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!mosa siru
 
デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣Masahiro Nishimi
 
SQLアンチパターン - ジェイウォーク
SQLアンチパターン - ジェイウォークSQLアンチパターン - ジェイウォーク
SQLアンチパターン - ジェイウォークke-m kamekoopa
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうRyuji Tsutsui
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みChihiro Ito
 
pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)NTT DATA Technology & Innovation
 
KafkaとAWS Kinesisの比較
KafkaとAWS Kinesisの比較KafkaとAWS Kinesisの比較
KafkaとAWS Kinesisの比較Yoshiyasu SAEKI
 
Spring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作るSpring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作るGo Miyasaka
 
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】Masahito Zembutsu
 
ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割
ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割
ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割Recruit Lifestyle Co., Ltd.
 
なかったらINSERTしたいし、あるならロック取りたいやん?
なかったらINSERTしたいし、あるならロック取りたいやん?なかったらINSERTしたいし、あるならロック取りたいやん?
なかったらINSERTしたいし、あるならロック取りたいやん?ichirin2501
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Taku Miyakawa
 

What's hot (20)

コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門
 
HTTP/2 入門
HTTP/2 入門HTTP/2 入門
HTTP/2 入門
 
押さえておきたい、PostgreSQL 13 の新機能!! (PostgreSQL Conference Japan 2020講演資料)
押さえておきたい、PostgreSQL 13 の新機能!! (PostgreSQL Conference Japan 2020講演資料)押さえておきたい、PostgreSQL 13 の新機能!! (PostgreSQL Conference Japan 2020講演資料)
押さえておきたい、PostgreSQL 13 の新機能!! (PostgreSQL Conference Japan 2020講演資料)
 
オブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメオブジェクト指向エクササイズのススメ
オブジェクト指向エクササイズのススメ
 
PostgreSQLアンチパターン
PostgreSQLアンチパターンPostgreSQLアンチパターン
PostgreSQLアンチパターン
 
テスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるなテスト文字列に「うんこ」と入れるな
テスト文字列に「うんこ」と入れるな
 
マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!マイクロにしすぎた結果がこれだよ!
マイクロにしすぎた結果がこれだよ!
 
デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣デキるプログラマだけが知っているコードレビュー7つの秘訣
デキるプログラマだけが知っているコードレビュー7つの秘訣
 
ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開ヤフー社内でやってるMySQLチューニングセミナー大公開
ヤフー社内でやってるMySQLチューニングセミナー大公開
 
SQLアンチパターン - ジェイウォーク
SQLアンチパターン - ジェイウォークSQLアンチパターン - ジェイウォーク
SQLアンチパターン - ジェイウォーク
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
 
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajpAt least onceってぶっちゃけ問題の先送りだったよね #kafkajp
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
 
pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_hint_planを知る(第37回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
KafkaとAWS Kinesisの比較
KafkaとAWS Kinesisの比較KafkaとAWS Kinesisの比較
KafkaとAWS Kinesisの比較
 
Spring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作るSpring Boot × Vue.jsでSPAを作る
Spring Boot × Vue.jsでSPAを作る
 
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
Docker入門-基礎編 いまから始めるDocker管理【2nd Edition】
 
ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割
ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割
ホットペッパービューティーにおけるモバイルアプリ向けAPIのBFF/Backend分割
 
なかったらINSERTしたいし、あるならロック取りたいやん?
なかったらINSERTしたいし、あるならロック取りたいやん?なかったらINSERTしたいし、あるならロック取りたいやん?
なかったらINSERTしたいし、あるならロック取りたいやん?
 
Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方Javaのログ出力: 道具と考え方
Javaのログ出力: 道具と考え方
 

Viewers also liked

正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?kwatch
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラムkwatch
 
Emacsいじめの現場
Emacsいじめの現場Emacsいじめの現場
Emacsいじめの現場Eric Sartre
 
Gunosy Go lang study #6 net http url
Gunosy Go lang study #6 net http urlGunosy Go lang study #6 net http url
Gunosy Go lang study #6 net http urlInnami Satoshi
 
PHPerがgolangでもがいてる話@第1回 関西Golang勉強会
PHPerがgolangでもがいてる話@第1回 関西Golang勉強会PHPerがgolangでもがいてる話@第1回 関西Golang勉強会
PHPerがgolangでもがいてる話@第1回 関西Golang勉強会Keisuke Utsumi
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門kwatch
 

Viewers also liked (6)

正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラム
 
Emacsいじめの現場
Emacsいじめの現場Emacsいじめの現場
Emacsいじめの現場
 
Gunosy Go lang study #6 net http url
Gunosy Go lang study #6 net http urlGunosy Go lang study #6 net http url
Gunosy Go lang study #6 net http url
 
PHPerがgolangでもがいてる話@第1回 関西Golang勉強会
PHPerがgolangでもがいてる話@第1回 関西Golang勉強会PHPerがgolangでもがいてる話@第1回 関西Golang勉強会
PHPerがgolangでもがいてる話@第1回 関西Golang勉強会
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門
 

Similar to Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方

Introduction of Oracle Database Architecture
Introduction of Oracle Database ArchitectureIntroduction of Oracle Database Architecture
Introduction of Oracle Database ArchitectureRyota Watabe
 
10分で分かるr言語入門ver2.9 14 0920
10分で分かるr言語入門ver2.9 14 0920 10分で分かるr言語入門ver2.9 14 0920
10分で分かるr言語入門ver2.9 14 0920 Nobuaki Oshiro
 
PostgreSQL Unconference #29 Unicode IVS
PostgreSQL Unconference #29 Unicode IVSPostgreSQL Unconference #29 Unicode IVS
PostgreSQL Unconference #29 Unicode IVSNoriyoshi Shinoda
 
generate_series関数使い込み
generate_series関数使い込みgenerate_series関数使い込み
generate_series関数使い込みkawarasho
 
10分で分かるr言語入門ver2.10 14 1101
10分で分かるr言語入門ver2.10 14 110110分で分かるr言語入門ver2.10 14 1101
10分で分かるr言語入門ver2.10 14 1101Nobuaki Oshiro
 
20211112_jpugcon_gpu_and_arrow
20211112_jpugcon_gpu_and_arrow20211112_jpugcon_gpu_and_arrow
20211112_jpugcon_gpu_and_arrowKohei KaiGai
 
Gura プログラミング言語の紹介
Gura プログラミング言語の紹介Gura プログラミング言語の紹介
Gura プログラミング言語の紹介Yutaka Saito
 
Siv3Dで楽しむゲームとメディアアート開発
Siv3Dで楽しむゲームとメディアアート開発Siv3Dで楽しむゲームとメディアアート開発
Siv3Dで楽しむゲームとメディアアート開発Ryo Suzuki
 
S02 t1 sta_py_tsuji_0702_slides
S02 t1 sta_py_tsuji_0702_slidesS02 t1 sta_py_tsuji_0702_slides
S02 t1 sta_py_tsuji_0702_slidesTakeshi Akutsu
 
MySQL8.0 SYS スキーマ概要
MySQL8.0 SYS スキーマ概要MySQL8.0 SYS スキーマ概要
MySQL8.0 SYS スキーマ概要Shinya Sugiyama
 
Java puzzlers 2013 at JavaFesta Japan
Java puzzlers 2013 at JavaFesta JapanJava puzzlers 2013 at JavaFesta Japan
Java puzzlers 2013 at JavaFesta JapanYoshio Terada
 
[db tech showcase Tokyo 2018] #dbts2018 #D27 『Verticaの進化が止まらない! 機械学習、データレイク、処...
[db tech showcase Tokyo 2018] #dbts2018 #D27 『Verticaの進化が止まらない! 機械学習、データレイク、処...[db tech showcase Tokyo 2018] #dbts2018 #D27 『Verticaの進化が止まらない! 機械学習、データレイク、処...
[db tech showcase Tokyo 2018] #dbts2018 #D27 『Verticaの進化が止まらない! 機械学習、データレイク、処...Insight Technology, Inc.
 
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)Hiro H.
 

Similar to Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方 (16)

Introduction of Oracle Database Architecture
Introduction of Oracle Database ArchitectureIntroduction of Oracle Database Architecture
Introduction of Oracle Database Architecture
 
10分で分かるr言語入門ver2.9 14 0920
10分で分かるr言語入門ver2.9 14 0920 10分で分かるr言語入門ver2.9 14 0920
10分で分かるr言語入門ver2.9 14 0920
 
PostgreSQL Unconference #29 Unicode IVS
PostgreSQL Unconference #29 Unicode IVSPostgreSQL Unconference #29 Unicode IVS
PostgreSQL Unconference #29 Unicode IVS
 
generate_series関数使い込み
generate_series関数使い込みgenerate_series関数使い込み
generate_series関数使い込み
 
10分で分かるr言語入門ver2.10 14 1101
10分で分かるr言語入門ver2.10 14 110110分で分かるr言語入門ver2.10 14 1101
10分で分かるr言語入門ver2.10 14 1101
 
20211112_jpugcon_gpu_and_arrow
20211112_jpugcon_gpu_and_arrow20211112_jpugcon_gpu_and_arrow
20211112_jpugcon_gpu_and_arrow
 
Gura プログラミング言語の紹介
Gura プログラミング言語の紹介Gura プログラミング言語の紹介
Gura プログラミング言語の紹介
 
Siv3Dで楽しむゲームとメディアアート開発
Siv3Dで楽しむゲームとメディアアート開発Siv3Dで楽しむゲームとメディアアート開発
Siv3Dで楽しむゲームとメディアアート開発
 
S02 t1 sta_py_tsuji_0702_slides
S02 t1 sta_py_tsuji_0702_slidesS02 t1 sta_py_tsuji_0702_slides
S02 t1 sta_py_tsuji_0702_slides
 
MySQL8.0 SYS スキーマ概要
MySQL8.0 SYS スキーマ概要MySQL8.0 SYS スキーマ概要
MySQL8.0 SYS スキーマ概要
 
Aaなゲームをjsで
AaなゲームをjsでAaなゲームをjsで
Aaなゲームをjsで
 
Aaなゲームをjsで
AaなゲームをjsでAaなゲームをjsで
Aaなゲームをjsで
 
Java puzzlers 2013 at JavaFesta Japan
Java puzzlers 2013 at JavaFesta JapanJava puzzlers 2013 at JavaFesta Japan
Java puzzlers 2013 at JavaFesta Japan
 
[db tech showcase Tokyo 2018] #dbts2018 #D27 『Verticaの進化が止まらない! 機械学習、データレイク、処...
[db tech showcase Tokyo 2018] #dbts2018 #D27 『Verticaの進化が止まらない! 機械学習、データレイク、処...[db tech showcase Tokyo 2018] #dbts2018 #D27 『Verticaの進化が止まらない! 機械学習、データレイク、処...
[db tech showcase Tokyo 2018] #dbts2018 #D27 『Verticaの進化が止まらない! 機械学習、データレイク、処...
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
 

More from kwatch

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Pythonkwatch
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアルkwatch
 
なんでもID
なんでもIDなんでもID
なんでもIDkwatch
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方kwatch
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐkwatch
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)kwatch
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!kwatch
 
PHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するPHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するkwatch
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?kwatch
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Pythonkwatch
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策kwatch
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurialkwatch
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -kwatch
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみたkwatch
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"kwatch
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンkwatch
 
Underlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R MapperUnderlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R Mapperkwatch
 
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -kwatch
 
Benchmarker - A Good Friend for Performance
Benchmarker - A Good Friend for PerformanceBenchmarker - A Good Friend for Performance
Benchmarker - A Good Friend for Performancekwatch
 
How to Create a High-Speed Template Engine in Python
How to Create a High-Speed Template Engine in PythonHow to Create a High-Speed Template Engine in Python
How to Create a High-Speed Template Engine in Pythonkwatch
 

More from kwatch (20)

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Python
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアル
 
なんでもID
なんでもIDなんでもID
なんでもID
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!
 
PHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較するPHPとJavaScriptにおけるオブジェクト指向を比較する
PHPとJavaScriptにおけるオブジェクト指向を比較する
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurial
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジン
 
Underlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R MapperUnderlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R Mapper
 
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
 
Benchmarker - A Good Friend for Performance
Benchmarker - A Good Friend for PerformanceBenchmarker - A Good Friend for Performance
Benchmarker - A Good Friend for Performance
 
How to Create a High-Speed Template Engine in Python
How to Create a High-Speed Template Engine in PythonHow to Create a High-Speed Template Engine in Python
How to Create a High-Speed Template Engine in Python
 

Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方

  • 1. Nippondanji 氏に 怒られても仕方ない 配列型とJSON型の 使い方 (in PostgreSQL) Makoto Kuwata http://www.kuwata-lab.com/ https://github.com/kwatch/ 理論から学ぶデータベース実践入門Night LT
  • 2. copyright 2015 kuwata-lab.com all rights reserved.© 配列型とは? 複数の値を持てるデータ型 集合と違い、順番を保持できるのがポイント >> select '{34.6582, 139.7020}'::float[]; float8 ------------------ {34.6582,139.702} (1 row) floatの配列型 へのキャスト '{ }' が配列の リテラル
  • 3. copyright 2015 kuwata-lab.com all rights reserved.© JSON型とは? JSONデータを保持できるデータ型 キーと値の組や、構造が不定なデータが保存できる >> select '{"type":"string", "required":true}'::json; json ------------------------------------ {"type":"string", "required":true} (1 row) JSON型 へのキャスト
  • 4. copyright 2015 kuwata-lab.com all rights reserved.© なんで怒られちゃうの? 第一正規化を平然と無視してるから >> create table bookmark ( id serial primary key , url text not null , title text not null , tags text[] ); >> select * from bookmark; id | url | title | tags ----+---------------------+---------+----------------- 1 | https://example.com | Example | {'news','game'} (1 row) 1つのカラムに複数の値! しかも順序つき!
  • 5. copyright 2015 kuwata-lab.com all rights reserved.© 話は変わって、サンプルデータ ID Name 101 T-Shirt 102 Sweater Product ID Color Code 101 White W 101 Black B 102 White WH 102 Ivory IV 102 Gray GR product テーブル coloring テーブル
  • 6. copyright 2015 kuwata-lab.com all rights reserved.© joinすると… ID Name Code Color 101 T-Shirt W White 101 T-Shirt B Black 102 Sweater WH White 102 Sweater IV Ivory 102 Sweater GR Gray from product join coloring on product.id = coloring.product_id
  • 7. copyright 2015 kuwata-lab.com all rights reserved.© でも欲しいのは… ID Name (Code, Color) 101 T-Shirt (W, White) (B, Black) 102 Sweater (WH, White) (IV, Ivory) (GR, Gray) 1 : N の関係を保ったまま結果を取り出したい 1 : N の形で取得したい
  • 8. copyright 2015 kuwata-lab.com all rights reserved.© join >> select product.id, product.name, c.color from product left join coloring c on product.id = c.product_id ; id | name | color -----+---------+------- 101 | T-Shirt | White 101 | T-Shirt | Black 102 | Sweater | White 102 | Sweater | Ivory 102 | Sweater | Gray (5 rows) これがうれしくない
  • 9. copyright 2015 kuwata-lab.com all rights reserved.© 集約関数 array_agg() >> select product.id, product.name, coloring.color , array_agg(c.color) as colors from product left join coloring c on product.id = c.product_id group by product.id, product.name ; id | name | colors -----+---------+-------------------- 101 | T-Shirt | {White,Black} 102 | Sweater | {White,Ivory,Gray} (2 rows) 複数の値を配列型で取得! 1 : N で取り出せてる!
  • 10. copyright 2015 kuwata-lab.com all rights reserved.© 行コンストラクタ >> select product.id, product.name , array_agg((c.code, c.color)) as colors from product left join coloring c on product.id = c.product_id group by product.id, product.name ; id | name | colors -----+---------+---------------------------------------- 101 | T-Shirt | {"(W,White)","(B,Black)"} 102 | Sweater | {"(WH,White)","(IV,Ivory)","(GR,Gray)"} (2 rows) または row(c.code, c.color) 行の配列だけど パースが必要になる
  • 11. copyright 2015 kuwata-lab.com all rights reserved.© 集約関数 json_agg() >> select product.id, product.name , json_agg((c.code, c.color)) as colors from product left join coloring c on product.id = c.product_id group by product.id, product.name ; id | name | colors -----+---------+----------------------------- 101 | T-Shirt | [{"f1":"W","f2":"White"}, + | | {"f1":"B","f2":"Black"}] 102 | Sweater | [{"f1":"WH","f2":"White"}, + | | {"f1":"IV","f2":"Ivory"}, + | | {"f1":"GR","f2":"Gray"}] (2 rows) キーが f1, f2, ... に なってしまう ;(
  • 12. copyright 2015 kuwata-lab.com all rights reserved.© 複合型 >> create type code_name as (code text, name text); >> select product.id, product.name , json_agg((c.code, c.color)::code_name) as colors from product left join coloring c on product.id = c.product_id group by product.id, product.name; id | name | colors -----+---------+--------------------------------- 101 | T-Shirt | [{"code":"W","name":"White"}, + | | {"code":"B","name":"Black"}] 102 | Sweater | [{"code":"WH","name":"White"}, + | | {"code":"IV","name":"Ivory"}, + | | {"code":"GR","name":"Gray"}] (2 rows) code_name型へ キャストすると キー名が設定される
  • 13. copyright 2015 kuwata-lab.com all rights reserved.© 相関サブクエリ >> select product.id, product.name , ( select json_agg(t.*) from ( select code, color from coloring c2 where c2.product_id = product.id ) as t ) as colors from product left join coloring c on product.id = c.product_id group by product.id, product.name ; ...(前ページと同じ結果なので省略)... うまくいくけど 三重の入れ子は 複雑すぎる…
  • 14. copyright 2015 kuwata-lab.com all rights reserved.© 問題点 使いやすいとはとても言えない SQLごとに複合型を定義するわけにもいかないし、
 かといって相関サブクエリだと複雑すぎる DBドライバが配列型やJSON型に未対応 Python用以外は全滅に近い (PHPもRubyもJavaもダメ)、
 いったんtext型として取得してからパースする必要あり
  • 15. copyright 2015 kuwata-lab.com all rights reserved.© 所感 配列型やJSON型を嫌う人は結構いる 第一正規化に反するので、気持ちはわかる クエリ結果に使うのはいいんじゃない? 大事なのはテーブルが正規化されていることであり、
 クエリ結果にまで同じことを求める必要はない 1 : N のまま取り出せるのはやはり便利 とても自然であり、本来あるべき姿
 (なぜ今まで出来なかったのか?)
  • 16. copyright 2015 kuwata-lab.com all rights reserved.© 考察 我々が欲しいのはRelationalなのか? 欲しいのは速くて便利でトランザクションが使えるDBであり、 必ずしもRelationalである必要はない ID Name Code Color 101 T-Shirt W White 101 T-Shirt B Black 102 Sweate r WH White 102 Sweate r IV Ivory 102 Sweate r GR Gray ID Name Code,Color 101 T-Shirt (W, White) (B, Black) 102 Sweater (WH, White) (IV, Ivory) (GR, Gray) 正直、tupleの集合より 木構造のほうが便利やで こんなこと言ってたら 怒られても仕方ない
  • 17. copyright 2015 kuwata-lab.com all rights reserved.© まとめ 配列型とJSON型の集約関数を使うと、
 1 : N を 1 : N のまま取り出せるよ! array_agg() と json_agg() 現状では使いやすくはない 複合型の定義も相関サブクエリもしんどい、
 DBドライバの対応状況はもっとしんどい
  • 18. copyright 2015 kuwata-lab.com all rights reserved.© PostgreSQLに興味がわいたら 2015-11-27(Fri) 詳細は「ポスグレ カンファレンス 2015」でggr 公式バナーなのに「e」が抜けているけど たぶんデザイナーじゃない人が作ってるし 大目に見てあげて!
  • 19. copyright 2015 kuwata-lab.com all rights reserved.© 使い方 より 作り方 を知りたいなら 内部構造から学ぶPostgreSQL ̶ 設計・運用計画の鉄則 ̶ 勝俣智成、佐伯昌樹、原田登志 技術評論社 2014-09-04
  • 20. copyright 2015 kuwata-lab.com all rights reserved.© おしまい