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

MySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システムMySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システムKouhei Sutou
 
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~Miki Shimogai
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugMasatoshi Tada
 
ClojureではじめるSTM入門
ClojureではじめるSTM入門ClojureではじめるSTM入門
ClojureではじめるSTM入門sohta
 
ウェブセキュリティのありがちな誤解を解説する
ウェブセキュリティのありがちな誤解を解説するウェブセキュリティのありがちな誤解を解説する
ウェブセキュリティのありがちな誤解を解説するHiroshi Tokumaru
 
power-assert in JavaScript
power-assert in JavaScriptpower-assert in JavaScript
power-assert in JavaScriptTakuto Wada
 
行ロックと「LOG: process 12345 still waiting for ShareLock on transaction 710 afte...
行ロックと「LOG:  process 12345 still waiting for ShareLock on transaction 710 afte...行ロックと「LOG:  process 12345 still waiting for ShareLock on transaction 710 afte...
行ロックと「LOG: process 12345 still waiting for ShareLock on transaction 710 afte...Masahiko Sawada
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織Takafumi ONAKA
 
『データ解析におけるプライバシー保護』勉強会 秘密計算
『データ解析におけるプライバシー保護』勉強会 秘密計算『データ解析におけるプライバシー保護』勉強会 秘密計算
『データ解析におけるプライバシー保護』勉強会 秘密計算MITSUNARI Shigeo
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021Hiroshi Tokumaru
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうRyuji Tsutsui
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?Yoshitaka Kawashima
 
関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐりKazuyuki TAKASE
 
PostgreSQL 15の新機能を徹底解説
PostgreSQL 15の新機能を徹底解説PostgreSQL 15の新機能を徹底解説
PostgreSQL 15の新機能を徹底解説Masahiko Sawada
 
MySQLで論理削除と正しく付き合う方法
MySQLで論理削除と正しく付き合う方法MySQLで論理削除と正しく付き合う方法
MySQLで論理削除と正しく付き合う方法yoku0825
 
Quine・難解プログラミングについて
Quine・難解プログラミングについてQuine・難解プログラミングについて
Quine・難解プログラミングについてmametter
 
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところY Watanabe
 

What's hot (20)

MySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システムMySQL・PostgreSQLだけで作る高速あいまい全文検索システム
MySQL・PostgreSQLだけで作る高速あいまい全文検索システム
 
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
FizzBuzzで学ぶJavaの進化
FizzBuzzで学ぶJavaの進化FizzBuzzで学ぶJavaの進化
FizzBuzzで学ぶJavaの進化
 
ClojureではじめるSTM入門
ClojureではじめるSTM入門ClojureではじめるSTM入門
ClojureではじめるSTM入門
 
ウェブセキュリティのありがちな誤解を解説する
ウェブセキュリティのありがちな誤解を解説するウェブセキュリティのありがちな誤解を解説する
ウェブセキュリティのありがちな誤解を解説する
 
power-assert in JavaScript
power-assert in JavaScriptpower-assert in JavaScript
power-assert in JavaScript
 
行ロックと「LOG: process 12345 still waiting for ShareLock on transaction 710 afte...
行ロックと「LOG:  process 12345 still waiting for ShareLock on transaction 710 afte...行ロックと「LOG:  process 12345 still waiting for ShareLock on transaction 710 afte...
行ロックと「LOG: process 12345 still waiting for ShareLock on transaction 710 afte...
 
PostgreSQLアーキテクチャ入門
PostgreSQLアーキテクチャ入門PostgreSQLアーキテクチャ入門
PostgreSQLアーキテクチャ入門
 
エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織エンジニアの個人ブランディングと技術組織
エンジニアの個人ブランディングと技術組織
 
『データ解析におけるプライバシー保護』勉強会 秘密計算
『データ解析におけるプライバシー保護』勉強会 秘密計算『データ解析におけるプライバシー保護』勉強会 秘密計算
『データ解析におけるプライバシー保護』勉強会 秘密計算
 
SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021SPAセキュリティ入門~PHP Conference Japan 2021
SPAセキュリティ入門~PHP Conference Japan 2021
 
Python 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそうPython 3.9からの新定番zoneinfoを使いこなそう
Python 3.9からの新定番zoneinfoを使いこなそう
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?それはYAGNIか? それとも思考停止か?
それはYAGNIか? それとも思考停止か?
 
関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり関数型プログラミングのデザインパターンひとめぐり
関数型プログラミングのデザインパターンひとめぐり
 
PostgreSQL 15の新機能を徹底解説
PostgreSQL 15の新機能を徹底解説PostgreSQL 15の新機能を徹底解説
PostgreSQL 15の新機能を徹底解説
 
MySQLで論理削除と正しく付き合う方法
MySQLで論理削除と正しく付き合う方法MySQLで論理削除と正しく付き合う方法
MySQLで論理削除と正しく付き合う方法
 
Quine・難解プログラミングについて
Quine・難解プログラミングについてQuine・難解プログラミングについて
Quine・難解プログラミングについて
 
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
 

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
 

Recently uploaded

論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 

Recently uploaded (10)

論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 

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.© おしまい