Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PostgreSQLとPythonとSQL

2,439 views

Published on

SQLやDBの簡単な概要とPythonの親和性、FDW等について
の資料です。

みんなのPython勉強会#19 で使用しました。
https://startpython.connpass.com/event/37958/

Published in: Technology
  • Be the first to comment

PostgreSQLとPythonとSQL

  1. 1. 1 SQLで遊んでみよう! - PostgreSQLで始めるDB再入門 - みんなのPython勉強会2016/12/7 山田聡@denzowill
  2. 2. 2 本発表内容は所属する会社と 何ら関係はなく、私個人の見解しか含んでおりません
  3. 3. 3 0.Who am I? http://enterprisezine.jp/dbonline/detail/8307?p=2 ● 山田聡@denzowill ● StartPythonClubスタッフ ● 株式会社アシスト勤務 ● DBエンジニア6年目 ● ノンプログラマ、趣味でPython ● PostgreSQLとOracleが担当
  4. 4. 4 アジェンダ 1.データベースって? 2.PostgreSQLとPython 3.SQLの基本 4.FDW
  5. 5. 5 アジェンダ 1.データベースって? 2.PostgreSQLとPython 3.SQLの基本 4.FDW
  6. 6. 6 1.データベース ● 軍事情報をあつめた基地が由来 ● 様々な目的で利用するため、整理統合されたデータの集合体 ● データ活用の基盤として存在 一元管理 共有利用 独立性
  7. 7. 7 1.データベース ● 軍事情報をあつめた基地が由来 ● 様々な目的で利用するため、整理統合されたデータの集合体 ● データ活用の基盤として存在 一元管理 共有利用 独立性 同じデータが 散ってるのつらい アプリとデータは お互いに疎でありたい みんなで 仲良くしたい
  8. 8. 8 以降DBは全部RDBMSのことです
  9. 9. 9 1.データベースの種類 メジャーな 商用RDBMS
  10. 10. 10 1.データベースの種類 メジャーな オープンソースの RDBMS
  11. 11. 11 1.OSSDBと商用DB 無償で利用できる ソースが公開されている 自己責任※有償サポートも ライセンス料がかかる ソース非公開(1企業開発) メーカ責任 発展性 安定性 など など
  12. 12. 12 1.OSSDBと商用DB 技術に自身があるなら 全然活用できる! 何かあったら不安だから メーカにまかせたい! 本当に止められないシステムに 挑戦的なシステムや コストを抑えたいシステムに など など
  13. 13. 13 1.OSSDBと商用DBの機能差 ● コア機能はほとんど差はない ● パフォーマンス(パラレル) ● 高可用性(レプリケーション) ● セキュリティ ● 管理補助の充実
  14. 14. 14 1.OSSDBと商用DBの機能差 ● コア機能はほとんど差はない ● パフォーマンス(パラレル) ● 高可用性(レプリケーション) ● セキュリティ ● 管理補助の充実
  15. 15. 15 アジェンダ 1.データベースって? 2.PostgreSQLとPython 3.SQLの基本 4.FDW
  16. 16. 16 2.PostgreSQLとPython
  17. 17. 17 2.PostgreSQLはPythonが大好き ● PL/Python ● SQL関数がPythonでかける ● PgAdmin4 ● 管理ツールはFlask製
  18. 18. 18 2.PostgreSQLはPythonが大好き ● PL/Python ● SQL関数がPythonでかける ● PgAdmin4 ● 管理ツールはFlask製 sampledb=# CREATE OR REPLACE FUNCTION hello_python(hello_count int) sampledb-# RETURNS SETOF text sampledb-# AS $$ sampledb$# sampledb$# for n in range(hello_count): sampledb$# yield "HELLO WORLD" sampledb$# sampledb$# $$ LANGUAGE plpythonu; CREATE FUNCTION sampledb=# select hello_python(5); hello_python -------------- HELLO WORLD HELLO WORLD HELLO WORLD HELLO WORLD HELLO WORLD (5 rows)
  19. 19. 19 2.PostgreSQLはPythonが大好き ● PL/Python ● SQL関数がPythonでかける ● PgAdmin4 ● 管理ツールはFlask製
  20. 20. 20 アジェンダ 1.データベースって? 2.PostgreSQLとPython 3.SQLの基本 4.FDW
  21. 21. 21 3.SQLの基本 SQL Structured Query Language ● RDBMSへの操作用 ● 非手続き型言語 ● データの検索・操作 ● 最近はRDBMS以外でも使える
  22. 22. 22 射影 3.SQLの基本 SELECT col1, col2 FROM table1; tabl1のすべての行のcol1,col2を 表示してください。
  23. 23. 23 選択 3.SQLの基本 SELECT col1, col2 FROM table1 WHERE col3 = 100; tabl1のcol3が100の行について col1,col2を表示してください。
  24. 24. 24 ソート 3.SQLの基本 SELECT col1, col2 FROM table1 WHERE col3 = 100 ORDER BY col1; tabl1のcol3が100の行について col1,col2をcol1の順番で 表示してください。
  25. 25. 25 結合 3.SQLの基本 SELECT table1.col1, table2.col1 FROM table1 JOIN table2 ON table1.co2 = tabl2.col3 table1のcol2とtable2のcol3について 同じ行を取得して、table1のcol1と table2のcol1を表示してください。
  26. 26. 26 結合 3.SQLの基本 SELECT table1.col1, table2.col1 FROM table1 JOIN table2 ON table1.co2 = table2.col3 JOIN table3 ON table2.col2 = table3.col2; table1のcol2とtable2のcol3について 同じ行を取得して、さらにその行のcol2と table3のcol2が同じ行についてtable1の col1とtable2のcol1を表示してください。
  27. 27. 27 集約 3.SQLの基本 SELECT col1, count(*) FROM table1 GROUP BY col1; tabl1についてcol1が同じものを まとめて、それぞれについて行数を 表示(count(*))してください。
  28. 28. 28 3.SQLの基本 col1 | col2 | col3 -----------+------+------ APPLE | 1 | 100 APPLE | 2 | 100 APPLE | 2 | 300 PEN | 1 | 100 PEN | 1 | 200 PINEAPPLE | 1 | 200 PINEAPPLE | 1 | 100 PINEAPPLE | 2 | 100 PINEAPPLE | 2 | 300 PINEAPPLE | 2 | 400 col1 | count -----------+------- PEN | 2 APPLE | 3 PINEAPPLE | 5
  29. 29. 29 ここまで欲しいデータの条件しか 指定していないことに お気づきですか?
  30. 30. 30 3.手続き型 SQLは非手続き型 ●ほしいデータの条件を指定するだけ ●データをどう取り出すかは指定しない ●取り出す経路はシステム側に託す ●データをどう取り出すか含め開発する ●どれをループするのか ●どれを条件として比較するのか Pythonは手続き型
  31. 31. 31 3.手続き型 col1 | col2 | col3 -----------+------+------ APPLE | 1 | 100 APPLE | 2 | 100 APPLE | 2 | 300 PEN | 1 | 100 PEN | 1 | 200 PINEAPPLE | 1 | 200 PINEAPPLE | 1 | 100 PINEAPPLE | 2 | 100 PINEAPPLE | 2 | 300 PINEAPPLE | 2 | 400 [ { "col1": "APPLE", "col2": 1, "col3": 100, }, { "col1": "APPLE", "col2": 2, "col3": 100, }, : Pythonで扱う想定でディクショナリにしたもの
  32. 32. 32 3.SQLで処理したなら sampledb=# SELECT col1, col2 FROM table1 sampledb-# WHERE col3 = 100 ORDER BY col1; col1 | col2 -----------+------ APPLE | 1 APPLE | 2 PEN | 1 PINEAPPLE | 1 PINEAPPLE | 2 (5 rows)
  33. 33. 33 3.Pythonで同じ処理をするなら result = [] # col3==100のデータに絞込 for row in data: if row["col3"] == 100: result.append(row) # col1でソート result.sort(key=lambda x: x["col1"]) # 結果の表示 for row in result: print row["col1"], row["col2"]
  34. 34. 34 3.Pythonで同じ処理をするなら result = [] # col3==100のデータに絞込 for row in data: if row["col3"] == 100: result.append(row) # col1でソート result.sort(key=lambda x: x["col1"]) # 結果の表示 for row in result: print row["col1"], row["col2"]
  35. 35. 35 3.Pythonで同じ処理をするなら result = [] # col3==100のデータに絞込 for row in data: if row["col3"] == 100: result.append(row) # col1でソート result.sort(key=lambda x: x["col1"]) # 結果の表示 for row in result: print row["col1"], row["col2"]
  36. 36. 36 3.Pythonで同じ処理をするなら result = [] # col3==100のデータに絞込 for row in data: if row["col3"] == 100: result.append(row) # col1でソート result.sort(key=lambda x: x["col1"]) # 結果の表示 for row in result: print row["col1"], row["col2"]
  37. 37. 37 3.Pythonで同じ処理をするなら 逆でも結果は 同じだが、遅くなる 開発者が最適な 手続きを考える result = [] # col3==100のデータに絞込 for row in data: if row["col3"] == 100: result.append(row) # col1でソート result.sort(key=lambda x: x["col1"]) # 結果の表示 for row in result: print row["col1"], row["col2"]
  38. 38. 38 非手続き型言語(SQL)では誰が 手続きを考えるのか
  39. 39. 39 3.SQLで手続きを作る流れ プランナ,オプティマイザ ※製品で呼称は違う SQL 表の行数 データの分布
  40. 40. 40 3.SQLで手続きを作る流れ プランナ,オプティマイザ ※製品で呼称は違う SQL 表の行数 データの分布 実行計画
  41. 41. 41 3.SQLで手続きを作る流れ プランナ,オプティマイザ ※製品で呼称は違う SQL 表の行数 データの分布 実行計画 データへ アクセスする手続き
  42. 42. 42 3.SQLで手続きを作る流れ ●大体はプランナの実行計画のほうが優れている ●何個も表が結合するSQLの最適解は人間には無理 ●たまにプランナも失敗する ●プランナが上手に動ける環境を整えるのが大事
  43. 43. 43 アジェンダ 1.データベースって? 2.PostgreSQLとPython 3.SQLの基本 4.FDW
  44. 44. 44 4.FDW Foreign Data Wrapper 外部データラッパー: PostgreSQL 9.1から導入された拡張機能 外部のDBや、CSVといった外部リソースを PostgreSQLのテーブルとして扱う機能。 様々なリソースにSQLで透過的にアクセス できます。
  45. 45. 45 4.FDW SQL FDW
  46. 46. 46 4.FDWの種類 https://wiki.postgresql.org/wiki/Foreign_data_wrappers
  47. 47. 47 4.FDWの作り方 FDWの仕様に従って必要な インターフェースを実装するだけ!
  48. 48. 48 4.FDWの作り方 FDWの仕様に従って必要な インターフェースを実装するだけ! C言語で!
  49. 49. 49 4.FDWの作り方 FDWの仕様に従って必要な インターフェースを実装するだけ! C言語で! つらいorz
  50. 50. 50 4.FDWの作り方 https://wiki.postgresql.org/wiki/Foreign_data_wrappers Type: Multicorn?
  51. 51. 51 4.FDWの作り方 http://multicorn.org/
  52. 52. 52 4.Multicorn ● PythonでFDWを実装できるライブラリ ● Multicornのクラスを継承して実装するだけ from multicorn import ForeignDataWrapper class ConstantForeignDataWrapper(ForeignDataWrapper): def __init__(self, options, columns): super(ConstantForeignDataWrapper, self).__init__(options, columns) self.columns = columns def execute(self, quals, columns): for index in range(20): line = {} for column_name in self.columns: line[column_name] = '%s %s' % (column_name, index) yield line
  53. 53. 53 残りの時間で独自のFDWを実装
  54. 54. 54 残りの時間で独自のFDWを実装 するには残りの時間が 短すぎるので続きは次の機会で
  55. 55. 55 あなたもPythonと PostgreSQLで遊んでみてください

×