SlideShare a Scribd company logo
PostgreSQLのデータ型
#nds51 @civic
自己紹介
• NDS管理人 @civic
• 最近は低温調理にハマっています
40歳超えたら
自己紹介は30秒以下にしろ!
今日話す内容
• PostgreSQL特有のデータ型の紹介
• プログラムからどのように利用するか
そういえば聞いたことがある・・・
「自分の知らない分野の話をすると非常に学びになる」
という
経緯
• 数値・文字列・日付ぐらいしか使ってないぞ
• ざっとドキュメントを眺めていた
• 使ったことのないデータ型がたくさんあるぞ
• 特にPostgreSQLはデータ型が多い
• もっとデータベースの機能を使ったほうが良いのでは
?
• 日付を8桁の文字で保持→DATE型
• ???→PostgreSQLが用意するデータ型
質問
• みなさんがメインで使っているRDBMS製品は?
• postgresql
• mysql
• sqlserver
• oracle
各種RDBMSが対応する
データ型を比較
データ型の対応を調べてみた
postgresql mysql sqlserver oracle
数値
文字列
日付
論理値
幾何データ
XML
JSON
バイナリ
....
思ったほど
大差なかった・・・
思ったより大差なかった・・・
• PostgreSQLにしかないと思っていた型
• 最近のバージョンではサポートしている
• 例:JSON
• postgresql 9.2
• mysql 5.7
• sqlserver 2016
PostgreSQL特有
ってほどでもないけど
面白そうなデータ型の紹介
PostgreSQL データ型
#nds51 @civic
特有ってほどでもないけど面白そうな
json / jsonb型
JSON(JavaScript Object Notation)
{
"foo": 123,
"bar": "Hello World",
"hoge": [1, 2, 3]
}
JSONデータ
json型
• postgresql 9.2以降
• mysql 5.7
• sqlserver 2016
• oracle チェック制約のみ
CREATE TABLE mytable(
id integer,
info json
);
jsonb型
• postgresql 9.4以降
• jsonをバイナリで保持
• 検索効率向上
• 各種関数・演算子のサポート
• インデックスサポート
CREATE TABLE mytable(
id integer,
info jsonb
);
使いどころ
使いどころ
• 入力によって柔軟な構造が必要なケース
• アドレス帳の追加属性とか?
JSONが使えるなら
1列でいいじゃん!
なんでもJSONにするのは危険
• 1つの列に複数の意味のデータを入れるべきではない
• 制約が使えない・外部キーが使えない
• クエリが複雑になる
• 検索や関連に使われないデータのみに使用したい
参考: PostgreSQLのアンチパターン : 何でもかんでもjsonに入れる
https://yakst.com/ja/posts/2445
使用例
本の情報 books
CREATE TABLE books(
id integer PRIMARY KEY,
name text,
price integer,
info jsonb
);
INSERT INTO books VALUES
(1, 'book1', 45745,
'{"format": "text", "tags": ["english","game","
検索
SELECT * FROM books
WHERE
info @> '{"format": "pdf"}'::jsonb;
formatがpdfの本を検索
@> 包含演算子
JSONパス・値を保持するか
感想
• textにjson入れるよりはJSON検証も行われる
• インデックスや各種関数、演算子が使えて便利
• id, key, valueだけのテーブル(EAV)よりマシか
• 外部キーは絶対マズい
• 検索条件に使うのは要件次第か
用法用量を守ろう
範囲型
範囲型
• 数値や日付の範囲を表すデータ型
• postgresql 9.2以降
• mysql
• sqlserver
• oracle
PostgreSQL特有!
start end
範囲型
• 数値
• int4range: 4バイト整数範囲
• int8range: 8バイト整数範囲
• numrange: 実数範囲
• 日付
• tsrange: 日付時刻範囲
• tszrange: 日付時刻範囲(タイムゾーンつき)
• daterange: 日付範囲
使いどころ
2列で持っていたデータを1列で
• from, to, start, end
• 開始よりも終了が大きいという整合性
境界が明確
• 3以上7以下(閉じた境界)
• '[3, 7]'::int4range
• 3以上7未満(開いた上限)
• '[3, 7)'::int4range
• 3以上(境界のない上限)
• '[3, ]'::int4range
3 7
3 7
3
重なりや含有をチェックする演算子
• 含有
'[10, 20]'::int4range @> 14
• 重なり
'[10, 20]'::int4range && '[15, 30]'::int4range
10 20
14
10 2015 30
インデックスもサポート
使用例
予約テーブル
• EXCLUDEの排他制約で予約の重複を防ぐ制約
CREATE TABLE reservation(
during daterange,
EXCLUDE USING GIST(during WITH &&)
);
INSERT INTO reservation
VALUES('[2017-03-10, 2017-03-12]');
INSERT INTO reservation
VALUES('[2017-03-11, 2017-03-13]');
--重なりがあるのでエラー
↑duringの重なりの排他
めっちゃ便利!
2つのデータ型を紹介しました
プログラムから
どう利用するか?
プログラミング言語から
• プログラミング言語からDBを使うときには様々な
ライブラリを通している
• DBアクセス用API
• ORマッパーなどの便利ライブラリ
• 標準APIは各種DBの最小公倍数的な機能
• JDBC APIで提供されるデータ型にJSONはない
Javaの例
PostgreSQL
Java
Application
JDBC Driver
for PostgreSQL
JDBC
API
EclipseLinkJPA
PostgreSQL特有の機能は
ネイティブなところまで
どうやって使うのか
• ネイティブ対応しているレイヤーを使用
• JDBC for PostgreSQL
• テキスト経由で受け渡し→SQLで型変換
• PostgreSQL方言
• ライブラリ側の対応次第
具体的に考えてみる
• jsonb型をJava / Pythonから利用
CREATE TABLE json_test(
id integer,
info jsonb
)
id info
1 {"a": 100, "b": "Hello"}
2 {"a": 200, "b": "World"}
Javaの場合
https://github.com/civic/postgresql-java-json
検証ケース
• SELECTとINSERTについて考える
• 低レベルAPI → JDBC API
• 高レベルAPI → JPA(永続化標準API)
JDBC API (低レベルAPI)
resultSet.getString("info");
// {"a": 100, "b": "Hello"}
SELECT
ResultSet#getStringで文字列として取得可能
JDBC API (低レベルAPI)
INSERT
PGobjectを使用。 ※postgresqlドライバの機能
import org.postgresql.util.PGobject;
PGobject pgobj =new PGobject();
pgobj.setValue(json_string); //json文字列
pgobj.setType("jsonb");
preparedStatement.setObject(1, pgobj);
Java的にはベンダー製パッケージのimportは
ちょっと抵抗がある
JDBC API (低レベルAPI)
INSERT
SQL文内でキャスト
PreparedStatement ps =conn.prepareStatement(
"INSERT INTO json_test(info) VALUES(jsonb(?))"
);
ps.setString(1, json_string); //json文字列
JPA (高レベルAPI)
SELECT / INSERT
Converterを作成すれば
SQLデータ型とJavaデータ型を相互変換できる
@Entity
@Table(name = "json_test")
public class JsonTest implements Serializable {
// ... 中略 ...
@Column(name = "info")
@Convert(converter = JsonbConverter.class)
private String info;
Pythonの場合
https://github.com/civic/postgresql-python-json
Pythonの例
PostgreSQL
Python
Application
psycopg2DB API
SQLAlchemy
PostgreSQL特有の機能は
ネイティブ対応なところまで
libpq
検証ケース
• SELECTとINSERTについて考える
• 低レベルAPI → psycopg2
• 高レベルAPI → SQLAlchemy
psycopg2 (低レベルAPI)
cur.execute(
"SELECT info FROM json_test WHERE id=1"
)
row = cur.fetchone()
print(row[0])
# {'b': 'Hello', 'a': 100}
SELECT
何もしなくても、dict(辞書型)として取得できる
psycopg2 (低レベルAPI)
INSERT
psycopg2.extras.Jsonを使用し、dict→Json
from psycopg2.extras import Json
#json objectで更新
cur.execute(
"INSERT INTO json_test(info) VALUES(%s)",
[
Json({"a":30, "b": "update"})
]
)
psycopg2 (低レベルAPI)
INSERT
SQL文内でキャスト。
import json
# dictを文字列化してSQLに渡す
cur.execute(
"INSERT INTO json_test(info) VALUES(jsonb(%s))",
[
json.dumps({"a":30, "b": "update"}) //dict→str
]
)
SQLAlchemy (高レベルAPI)
SELECT / INSERT
SQLAlchemyは至れり尽くせり。
各DBベンダー用方言(dialect)が用意されている。
from sqlalchemy.dialects.postgresql import JSONB
class JsonTest(Base):
__tablename__ = 'json_test'
id = Column(Integer, primary_key=True)
info = Column(JSONB) # JSONB型の列と宣言
...
まとめ
まとめ
• PostgreSQL特有のデータ型が便利そう
正規化を失わないように
• プログラミング言語からもpg特有の型は使えそう
• Java
• 標準APIのままでは使いにくい
• ベンダー実装の機能を使うか型変換で
• Python
• ダックタイピングできるのでJavaほど厳しくない
• SQLAlchemy便利
参考
• PostgreSQL 9.6.2文書
• PGCon2014 JSONB データ型を使ってみよう
• Oracle® Database SQL言語リファレンス
• MySQL 5.7 Reference Manual
• データ型 (Transact-SQL) - MSDN - Microsoft
• PostgreSQLのアンチパターン : 何でもかんでもjsonに入れる
• JPA 2.1 の 新機能 Converter まとめ
• Psycopg - PostgreSQL database adapter for Python

More Related Content

PPTX
第52回なんてかんたんなJavaEE
PDF
20120830 DBリファクタリング読書会第三回
PPTX
Analytics Environment
PDF
便利なHerokuと active recordの 速度改善tips
PDF
JavaScriptで出来る、あんなことこんなこと
PDF
JJUG CCC 2017 Spring LT about JPA
PDF
初心者向けWordPress DB & Performance
PDF
第52回なんてかんたんなJavaEE
20120830 DBリファクタリング読書会第三回
Analytics Environment
便利なHerokuと active recordの 速度改善tips
JavaScriptで出来る、あんなことこんなこと
JJUG CCC 2017 Spring LT about JPA
初心者向けWordPress DB & Performance

What's hot (20)

PDF
シェル芸勉強会へようこそ
PDF
⑮jQueryをおぼえよう!その1
PDF
Phpのはなし
PDF
JSONB型でpostgresをNoSQLっぽく使う
PDF
⑳CSSでアニメーション!その1
PPTX
Go で Unit Test をやってみた
PPTX
20151205 中国地方db勉強会 dbm_fs
PDF
ActiveRecord::Enumのススメ
PPTX
Famo.usはもう試したかい?
PDF
Database smells
PDF
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
PDF
20121206 VOYAGE LT - 名前重要って言うけどさ
PPTX
いまいまMySQL@OSC2016長岡
PPTX
いまいまMySQL@OSC2016島根
PDF
今日はMongoDBの話はしない
PPTX
Hadoop Streamingを使って お好きな言語でMap☆Reduce!
PPTX
altJS勉強会「Haxeすごいからみんな使え!」
PDF
あなたが知らない リレーショナルモデル
PDF
真にスレッドセーフなHash mapとは #渋谷java
PPTX
MongoDBの可能性の話
シェル芸勉強会へようこそ
⑮jQueryをおぼえよう!その1
Phpのはなし
JSONB型でpostgresをNoSQLっぽく使う
⑳CSSでアニメーション!その1
Go で Unit Test をやってみた
20151205 中国地方db勉強会 dbm_fs
ActiveRecord::Enumのススメ
Famo.usはもう試したかい?
Database smells
なぜ、いま リレーショナルモデルなのか(理論から学ぶデータベース実践入門読書会スペシャル)
20121206 VOYAGE LT - 名前重要って言うけどさ
いまいまMySQL@OSC2016長岡
いまいまMySQL@OSC2016島根
今日はMongoDBの話はしない
Hadoop Streamingを使って お好きな言語でMap☆Reduce!
altJS勉強会「Haxeすごいからみんな使え!」
あなたが知らない リレーショナルモデル
真にスレッドセーフなHash mapとは #渋谷java
MongoDBの可能性の話
Ad

Viewers also liked (20)

PPTX
第49回emailを安全んにつかうための心がけ
PDF
条件式評価器の実装による管理ツールの抽象化
PPTX
入門系の本を一冊も読まずにデータサイエンスに入門してみる
PDF
Drupal Developer Days Keynote
PPTX
A guide to using twitter - for researchers
PPTX
Design pattern-refactor-functional
PDF
Devel for Drupal 8
PDF
Goをカンストさせる話
PPTX
HoloLens x Graphics 入門
PDF
フォントの選び方・使い方
PDF
The Marketer's Guide To Customer Interviews
PDF
The Be-All, End-All List of Small Business Tax Deductions
PDF
What am i buying understanding website cost and technology 17 ntc
PPTX
Thank you 3.25.2017
PPTX
Webセキュリティ入門(xss)
PDF
Knit One, Compute One - Software Art Thou?
PDF
The Fall of Trump
PDF
いまさら聞けないselectあれこれ
PPTX
How to go about Setting Goals the Right Way!
DOCX
La última reconstrucción del Puente del Ebro en Elciego .- 1874
第49回emailを安全んにつかうための心がけ
条件式評価器の実装による管理ツールの抽象化
入門系の本を一冊も読まずにデータサイエンスに入門してみる
Drupal Developer Days Keynote
A guide to using twitter - for researchers
Design pattern-refactor-functional
Devel for Drupal 8
Goをカンストさせる話
HoloLens x Graphics 入門
フォントの選び方・使い方
The Marketer's Guide To Customer Interviews
The Be-All, End-All List of Small Business Tax Deductions
What am i buying understanding website cost and technology 17 ntc
Thank you 3.25.2017
Webセキュリティ入門(xss)
Knit One, Compute One - Software Art Thou?
The Fall of Trump
いまさら聞けないselectあれこれ
How to go about Setting Goals the Right Way!
La última reconstrucción del Puente del Ebro en Elciego .- 1874
Ad

Similar to 第51回NDS PostgreSQLのデータ型 #nds51 (20)

PDF
RDBってなに?
PPTX
Couch Db勉強会0623 by yssk22
PPTX
EmbulkとDigdagとデータ分析基盤と
PPTX
EmbulkとDigdagとデータ分析基盤と
PDF
Jjugccc2017spring-postgres-ccc_m1
PPTX
Node.jsで使えるファイルDB"NeDB"のススメ
PDF
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
PDF
アナリティクスをPostgreSQLで始めるべき10の理由@第6回 関西DB勉強会
PDF
Yesod(at FPM2012)
PDF
⑯jQueryをおぼえよう!その2
PPTX
Sql world を支える技術
PDF
PHP開発者のためのNoSQL入門
PDF
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
PPTX
AWSerにも知ってほしいDBの話
PDF
.NET最先端技術によるハイパフォーマンスウェブアプリケーション
KEY
Osc2012.dbに行ってきました
PPTX
MySQLメインの人がPostgreSQLのベンチマークをしてみた話
PPTX
サーバーレスでアンケートフォームを作ってみた
PDF
【de:code 2020】 PostgreSQL もスケールさせよう! - Hyperscale (Citus) -
PDF
Chugokudb18_2
RDBってなに?
Couch Db勉強会0623 by yssk22
EmbulkとDigdagとデータ分析基盤と
EmbulkとDigdagとデータ分析基盤と
Jjugccc2017spring-postgres-ccc_m1
Node.jsで使えるファイルDB"NeDB"のススメ
RDB技術者のためのNoSQLガイド NoSQLの必要性と位置づけ
アナリティクスをPostgreSQLで始めるべき10の理由@第6回 関西DB勉強会
Yesod(at FPM2012)
⑯jQueryをおぼえよう!その2
Sql world を支える技術
PHP開発者のためのNoSQL入門
MongoDBを用いたソーシャルアプリのログ解析 〜解析基盤構築からフロントUIまで、MongoDBを最大限に活用する〜
AWSerにも知ってほしいDBの話
.NET最先端技術によるハイパフォーマンスウェブアプリケーション
Osc2012.dbに行ってきました
MySQLメインの人がPostgreSQLのベンチマークをしてみた話
サーバーレスでアンケートフォームを作ってみた
【de:code 2020】 PostgreSQL もスケールさせよう! - Hyperscale (Citus) -
Chugokudb18_2

More from civicpg (7)

PDF
オンライン英会話のモチベーション維持!
PPTX
#nds54 ルーチンワーク自動化の話
PPTX
#nds53 IoTプラットフォーム・工作でスーヴィード(低温調理)
PPTX
jupyterの紹介 #nds48
PPTX
#nds47 WebのテストをPythonでやってエビデンス取得作業から開放?
PPTX
私の好きなPython構文 vol.2 #nds46
PDF
Amazon SESのメール受信対応でサーバー減らせた話 #nds44
オンライン英会話のモチベーション維持!
#nds54 ルーチンワーク自動化の話
#nds53 IoTプラットフォーム・工作でスーヴィード(低温調理)
jupyterの紹介 #nds48
#nds47 WebのテストをPythonでやってエビデンス取得作業から開放?
私の好きなPython構文 vol.2 #nds46
Amazon SESのメール受信対応でサーバー減らせた話 #nds44

第51回NDS PostgreSQLのデータ型 #nds51

Editor's Notes

  • #6: 例えば日付型を8桁の文字で保持するより、DATE型で保持したほうがよい ・不正な日付データ ・日付用の関数 ・データサイズ 同じように自分がよく知らなかったデータ型もどんどん使えばいいのでは?
  • #9: ポスグレにはこんなにたくさんのデータ型があるんだよ!って言いたかったんだけど
  • #13: あらためてタイトルの紹介
  • #16: PostgreSQLはいち早く対応したが、最近のバージョンではmysql, sqlserverでもjsonが使えるようです。 Oracleは文字列データとして扱うがJSONとして検証するためのCHECK制約だけがあるっぽい。
  • #17: こっちのほうがいいです 特殊なケースを除いてjson → jsonbでOK
  • #23: 本の情報を保存しよう!
  • #25: 1列に複数の情報は入れるべきではない。原則 柔軟な補足データを格納する場合に検討。 ・EAVパータン ・ジェイウォークパターン
  • #30: 開始<終了という挿入ルールだったり、CHECK制約があったはず。
  • #32: betweenでやってたこと
  • #45: getStringでJSON文字列が取得できる
  • #46: JDBC APIにはJSON型はない。 JDBCの提供するインターフェース経由で使うのが通常。PostgreSQL提供のドライバの機能を使うしかない。 アプリケーションのどこでも書くのではなく、共通ライブラリなど限定された箇所で使うべき。
  • #47: 文字列としてsetStringするので、標準APIのみで可能。
  • #48: JPAという仕様で、Converterが定義されているのでjsonb型ーStringの変換ができる
  • #50: Pythonの場合はORマッパー的なライブラリは標準APIになっていない
  • #53: Javaのときと同じようにPostgreSQL用ドライバが提供する機能でJson型をサポート
  • #54: Javaのときと同じようにJSON文字列を渡して、SQL文内で型変換する。
  • #55: カスタムデータタイプの機能が予めDBベンダー別に用意済み。