Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
PgDay2012 LightningTalk
SQL上級者にこそ知って欲しい


なぜ
O/Rマッパー
             が重要か?
      makoto kuwata <kwa@kuwata-lab.com>
         ...
問:次のSQLは
何が問題でしょう?



 copyright© 2012 kuwata-lab.com all rights reserved
SQL
--	 販売成績上位10コを抽出
select	 *	 from	 sales
where	 deleted	 =	 false
order	 by	 amount	 desc
limit	 10

                  ...
話は変わって、
他のプログラミング言語



  copyright© 2012 kuwata-lab.com all rights reserved
Ruby
##	 販売実績上位Nコを抽出
def	 sales_top(n,	 rows)
	 	 xs	 =	 rows.map	 {|row|	 Sale.new(*row)	 }
	 	 xs	 =	 xs.select	 {|x|	 !...
Ruby
##	 販売実績上位Nコを抽出
def	 sales_top(n,	 rows)
	 	 xs	 =	 rows.map	 {|row|	 Sale.new(*row)	 }
	 	 xs	 =	 xs.select	 {|x|	 !...
Ruby
##	 販売実績上位Nコを抽出
def	 sales_top(n,	 rows)
	 	 xs	 =	 rows.map	 {|row|	 Sale.new(*row)	 }
	 	 xs	 =	 xs.select	 {|x|	 !...
Ruby
##	 販売実績上位Nコを抽出
def	 sales_top(n,	 rows)
	 	 xs	 =	 rows.map	 {|row|	 Sale.new(*row)	 }
	 	 xs	 =	 xs.select	 {|x|	 !...
Ruby
##	 販売実績上位Nコを抽出
def	 sales_top(n,	 rows)
	 	 xs	 =	 rows.map	 {|row|	 Sale.new(*row)	 }
	 	 xs	 =	 xs.select	 {|x|	 !...
Ruby
##	 販売実績上位Nコを抽出
def	 sales_top(n,	 rows)
	 	 xs	 =	 rows.map	 {|row|	 Sale.new(*row)	 }
	 	 xs	 =	 xs.select	 {|x|	 !...
複数の関数に分解
(リファクタリング)




 copyright© 2012 kuwata-lab.com all rights reserved
Ruby
def	 to_sales(rows)
	 	 rows.map	 {|row|	 Sale.new(*row)	 }
end

def	 active(sales)
	 	 sales.select	 {|x|	 !	 x.dele...
Ruby
##	 使い方
def	 sales_top(n,	 rows)
	 	 return	 top(n,	 active(to_sales(rows)))
end
                                    ...
専用のクラスを定義
 (オブジェクト指向)




 copyright© 2012 kuwata-lab.com all rights reserved
Ruby
clas	 Sales
	 	 def	 initialize(rows)
	 	 	 	 @all	 =	 rows.map	 {|row|	 Sales.new(*row)	 }
	 	 end
	 	 attr_reader	 ...
Ruby
##	 使い方
Sales.new(rows).active().top(10).all()


                                      分解したメソッドを
                    ...
プログラミング言語が
持っている基本機能



  copyright© 2012 kuwata-lab.com all rights reserved
• 「全体」 「部分」
      を    に分解する機能

• 「部分」 「全体」
      から   を構築する機能

• 「部分」に名前をつけて抽象化する機能




     copyright© 2012 kuwata-lab.c...
改めて、次のSQLは
何が問題でしょう?



 copyright© 2012 kuwata-lab.com all rights reserved
SQL
--	 販売成績上位10コを抽出
select	 *	 from	 sales
where	 deleted	 =	 false
order	 by	 amount	 desc
limit	 10




        copyrig...
SQLは、分解・構築・
抽象化の機能が弱っちい!



  copyright© 2012 kuwata-lab.com all rights reserved
そこで
O/R Mapper!!

  copyright© 2012 kuwata-lab.com all rights reserved
ORMを使うことで、

•SQLを小さい部品に分解
• 部品からSQL全体を構築
• 部品に名前をつけて抽象化
できるようになる!

   copyright© 2012 kuwata-lab.com all rights reserved
サンプルコード:

ActiveRecord (Rails3)

     copyright© 2012 kuwata-lab.com all rights reserved
Ruby
                             where deleted = false
class	 Sales	 <	 ActiveReocrd::Base
                              ...
「部分」を組み合わせて                                              Ruby
          「全体」を構築

Sales.active().top(10).all()

##	 これは
##	...
サンプルコード:

DataMapper

 copyright© 2012 kuwata-lab.com all rights reserved
Ruby
class	 Sales
                          where deleted = false
	 	 include	 DataMapper::Resource
                      ...
「部分」を組み合わせて                                              Ruby
          「全体」を構築

Sales.active().top(10).all()

##	 これも
##	...
別のサンプル:

副問い合わせ


copyright© 2012 kuwata-lab.com all rights reserved
SQL
--	 年齢が20歳の社員が所属する部署一覧
select	 *	 from	 departments
where	 id	 in
	 	 (select	 dept_id	 from	 employees
	 	 	 where	 a...
サンプルコード:

      Sequel

copyright© 2012 kuwata-lab.com all rights reserved
副問い合わせを切り出して
     名前を付ける
                                                        Ruby
dept_ids	 =	 Employee.select(:dept_i...
Ruby
dept_ids	 =	 Employee.select(:dept_id)	 
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 .filter(:age=>20)
Department.filter(:i...
別のサンプル:

重複した式


copyright© 2012 kuwata-lab.com all rights reserved
SQL
--	 誕生日をもとに年齢を計算
select	 date_part('year',	 age(birth))	 	 	 
	 	 	 	 	 	 	 as	 age,	 count(*)
from	 users
where	 date...
サンプルコード:

SQLAlchemy

 copyright© 2012 kuwata-lab.com all rights reserved
年齢の計算式を表す構文木を作り、                                       Python
from	 sqlalchemy.sql	 import	 func	 as	 fn
age	 =	 fn.date_p...
つまり



copyright© 2012 kuwata-lab.com all rights reserved
• SQLには部品化の機能がない
 → SQLが長くなる・わかりにくい
 → 複数のSQLで要素の重複が多い

• ORMはSQL要素の部品化ができる
 → SQL構築が簡潔・わかりやすい
 → 複数のSQLで部品を共用できる


    co...
• SQLには部品化の機能がない
 → SQLが長くなる・わかりにくい
 → 複数のSQLで要素の重複が多い

• ORMはSQL要素の部品化ができる
 → SQL構築が簡潔・わかりやすい
 → 複数のSQLで部品を共用できる


    co...
たとえるなら



copyright© 2012 kuwata-lab.com all rights reserved
まだ進化の途中な
               高水準へと進化                                  ので暖かい目を!

Lisp, Ruby                                     ...
まとめ



copyright© 2012 kuwata-lab.com all rights reserved
• 一般のプログラミング言語には
 「分解」「構築」「抽象化」
 の機能がある

• SQLはそれらが弱っちい
• モダンなORMなら、それらの機能
 をSQLに提供できる

    ORMはSQLの高水準言語 or DSL!



    c...
おしまい
copyright© 2012 kuwata-lab.com all rights reserved
Nächste SlideShare
Wird geladen in …5
×

von

SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 1 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 2 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 3 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 4 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 5 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 6 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 7 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 8 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 9 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 10 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 11 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 12 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 13 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 14 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 15 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 16 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 17 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 18 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 19 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 20 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 21 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 22 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 23 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 24 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 25 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 26 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 27 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 28 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 29 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 30 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 31 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 32 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 33 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 34 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 35 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 36 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 37 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 38 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 39 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 40 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 41 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 42 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 43 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 44 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 45 SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? Slide 46
Nächste SlideShare
よろしい、ならばMicro-ORMだ
Weiter

194 Gefällt mir

Teilen

SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?

(PgDay2012発表資料) SQLにとって、なぜO/Rマッパーが重要かを説明した資料です。

Ähnliche Bücher

Kostenlos mit einer 30-tägigen Testversion von Scribd

Alle anzeigen

Ähnliche Hörbücher

Kostenlos mit einer 30-tägigen Testversion von Scribd

Alle anzeigen

SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?

  1. 1. PgDay2012 LightningTalk SQL上級者にこそ知って欲しい なぜ O/Rマッパー が重要か? makoto kuwata <kwa@kuwata-lab.com> http://www.kuwata-lab.com/
  2. 2. 問:次のSQLは 何が問題でしょう? copyright© 2012 kuwata-lab.com all rights reserved
  3. 3. SQL -- 販売成績上位10コを抽出 select * from sales where deleted = false order by amount desc limit 10 文法的には正しいけど… copyright© 2012 kuwata-lab.com all rights reserved
  4. 4. 話は変わって、 他のプログラミング言語 copyright© 2012 kuwata-lab.com all rights reserved
  5. 5. Ruby ## 販売実績上位Nコを抽出 def sales_top(n, rows) xs = rows.map {|row| Sale.new(*row) } xs = xs.select {|x| ! x.deleted_at } xs = xs.sort_by {|x| - x.amount } xs = xs[0, 10] return xs end copyright© 2012 kuwata-lab.com all rights reserved
  6. 6. Ruby ## 販売実績上位Nコを抽出 def sales_top(n, rows) xs = rows.map {|row| Sale.new(*row) } xs = xs.select {|x| ! x.deleted_at } xs = xs.sort_by {|x| - x.amount } xs = xs[0, 10] select from相当 return xs end copyright© 2012 kuwata-lab.com all rights reserved
  7. 7. Ruby ## 販売実績上位Nコを抽出 def sales_top(n, rows) xs = rows.map {|row| Sale.new(*row) } xs = xs.select {|x| ! x.deleted_at } xs = xs.sort_by {|x| - x.amount } xs = xs[0, 10] return xs where相当 end copyright© 2012 kuwata-lab.com all rights reserved
  8. 8. Ruby ## 販売実績上位Nコを抽出 def sales_top(n, rows) xs = rows.map {|row| Sale.new(*row) } xs = xs.select {|x| ! x.deleted_at } xs = xs.sort_by {|x| - x.amount } xs = xs[0, 10] return xs order by相当 end copyright© 2012 kuwata-lab.com all rights reserved
  9. 9. Ruby ## 販売実績上位Nコを抽出 def sales_top(n, rows) xs = rows.map {|row| Sale.new(*row) } xs = xs.select {|x| ! x.deleted_at } xs = xs.sort_by {|x| - x.amount } xs = xs[0, 10] return xs limit相当 end copyright© 2012 kuwata-lab.com all rights reserved
  10. 10. Ruby ## 販売実績上位Nコを抽出 def sales_top(n, rows) xs = rows.map {|row| Sale.new(*row) } xs = xs.select {|x| ! x.deleted_at } xs = xs.sort_by {|x| - x.amount } xs = xs[0, 10] return xs end 1つの関数でいろんな ことをやりすぎている copyright© 2012 kuwata-lab.com all rights reserved
  11. 11. 複数の関数に分解 (リファクタリング) copyright© 2012 kuwata-lab.com all rights reserved
  12. 12. Ruby def to_sales(rows) rows.map {|row| Sale.new(*row) } end def active(sales) sales.select {|x| ! x.deleted_at } end def top(n, sales) sales = sales.sort_by {|x| - x.amount } return sales[0, 10] end copyright© 2012 kuwata-lab.com all rights reserved
  13. 13. Ruby ## 使い方 def sales_top(n, rows) return top(n, active(to_sales(rows))) end 分解した関数を 組み合わせる copyright© 2012 kuwata-lab.com all rights reserved
  14. 14. 専用のクラスを定義 (オブジェクト指向) copyright© 2012 kuwata-lab.com all rights reserved
  15. 15. Ruby clas Sales def initialize(rows) @all = rows.map {|row| Sales.new(*row) } end attr_reader :all def active @all = @all.select {|x| ! x.deleted } return self end def top(n) @all = @all.sort_by {|x| - x.amount } @all = @all[0, n] return self end end copyright© 2012 kuwata-lab.com all rights reserved
  16. 16. Ruby ## 使い方 Sales.new(rows).active().top(10).all() 分解したメソッドを 組み合わせる copyright© 2012 kuwata-lab.com all rights reserved
  17. 17. プログラミング言語が 持っている基本機能 copyright© 2012 kuwata-lab.com all rights reserved
  18. 18. • 「全体」 「部分」 を に分解する機能 • 「部分」 「全体」 から を構築する機能 • 「部分」に名前をつけて抽象化する機能 copyright© 2012 kuwata-lab.com all rights reserved
  19. 19. 改めて、次のSQLは 何が問題でしょう? copyright© 2012 kuwata-lab.com all rights reserved
  20. 20. SQL -- 販売成績上位10コを抽出 select * from sales where deleted = false order by amount desc limit 10 copyright© 2012 kuwata-lab.com all rights reserved
  21. 21. SQLは、分解・構築・ 抽象化の機能が弱っちい! copyright© 2012 kuwata-lab.com all rights reserved
  22. 22. そこで O/R Mapper!! copyright© 2012 kuwata-lab.com all rights reserved
  23. 23. ORMを使うことで、 •SQLを小さい部品に分解 • 部品からSQL全体を構築 • 部品に名前をつけて抽象化 できるようになる! copyright© 2012 kuwata-lab.com all rights reserved
  24. 24. サンプルコード: ActiveRecord (Rails3) copyright© 2012 kuwata-lab.com all rights reserved
  25. 25. Ruby where deleted = false class Sales < ActiveReocrd::Base に相当する「部分」 named_scope :active, {:conditions=>"deleted = false"} named_scope :top, lambda do |n| {:order=>"amount desc", :limit=>n} end order by amount desc limit n end に相当する「部分」 copyright© 2012 kuwata-lab.com all rights reserved
  26. 26. 「部分」を組み合わせて Ruby 「全体」を構築 Sales.active().top(10).all() ## これは ## select * from sales ## where deleted = false ## order by amount desc limit 10 ## を生成して実行する ※(2012-12-19) 「と同じ」を「を生成して実行する」に修正 copyright© 2012 kuwata-lab.com all rights reserved
  27. 27. サンプルコード: DataMapper copyright© 2012 kuwata-lab.com all rights reserved
  28. 28. Ruby class Sales where deleted = false include DataMapper::Resource に相当する「部分」 def self.active where(:deleted => false) end def self.top(n) order(:amount.desc).limit(n) end end order by amount desc limit n に相当する「部分」 copyright© 2012 kuwata-lab.com all rights reserved
  29. 29. 「部分」を組み合わせて Ruby 「全体」を構築 Sales.active().top(10).all() ## これも ## select * from sales ## where deleted = false ## order by amount desc limit 10 ## を生成して実行する ※(2012-12-19) 「と同じ」を「を生成して実行する」に修正 copyright© 2012 kuwata-lab.com all rights reserved
  30. 30. 別のサンプル: 副問い合わせ copyright© 2012 kuwata-lab.com all rights reserved
  31. 31. SQL -- 年齢が20歳の社員が所属する部署一覧 select * from departments where id in (select dept_id from employees where age = 20) order by name SQLに「部品化」の機能が ないことを示す典型例 ※(2012-12-13) "select id" を "select dept_id" に修正 copyright© 2012 kuwata-lab.com all rights reserved
  32. 32. サンプルコード: Sequel copyright© 2012 kuwata-lab.com all rights reserved
  33. 33. 副問い合わせを切り出して 名前を付ける Ruby dept_ids = Employee.select(:dept_id) .filter(:age=>20) Department.filter(:id=>dept_ids).all() SQL構築が簡潔になる SQL select * from departments where id in (select dept_id from employees where age = 20) copyright© 2012 kuwata-lab.com all rights reserved
  34. 34. Ruby dept_ids = Employee.select(:dept_id) .filter(:age=>20) Department.filter(:id=>dept_ids).all() Budget.filter(:dept_id=>dept_ids).all() 部品化した副問い合わせを複数の SQLで共用できる(with句より便利) copyright© 2012 kuwata-lab.com all rights reserved
  35. 35. 別のサンプル: 重複した式 copyright© 2012 kuwata-lab.com all rights reserved
  36. 36. SQL -- 誕生日をもとに年齢を計算 select date_part('year', age(birth)) as age, count(*) from users where date_part('year', age(birth)) < 20 group by date_part('year', age(birth)) order by age 同じ式が重複して出現 copyright© 2012 kuwata-lab.com all rights reserved
  37. 37. サンプルコード: SQLAlchemy copyright© 2012 kuwata-lab.com all rights reserved
  38. 38. 年齢の計算式を表す構文木を作り、 Python from sqlalchemy.sql import func as fn age = fn.date_part('year', fn.age(User.birth)) rows = DBSession .query(age, fn.count('*')) .select_from(User) .filter(age < 20) .group_by(age) .order_by(age) .all() それを複数箇所で使用できる copyright© 2012 kuwata-lab.com all rights reserved
  39. 39. つまり copyright© 2012 kuwata-lab.com all rights reserved
  40. 40. • SQLには部品化の機能がない → SQLが長くなる・わかりにくい → 複数のSQLで要素の重複が多い • ORMはSQL要素の部品化ができる → SQL構築が簡潔・わかりやすい → 複数のSQLで部品を共用できる copyright© 2012 kuwata-lab.com all rights reserved
  41. 41. • SQLには部品化の機能がない → SQLが長くなる・わかりにくい → 複数のSQLで要素の重複が多い • ORMはSQL要素の部品化ができる → SQL構築が簡潔・わかりやすい → 複数のSQLで部品を共用できる copyright© 2012 kuwata-lab.com all rights reserved
  42. 42. たとえるなら copyright© 2012 kuwata-lab.com all rights reserved
  43. 43. まだ進化の途中な 高水準へと進化 ので暖かい目を! Lisp, Ruby Modern ORM C, Pascal JDBC, DBI Assembler SQL 低水準から copyright© 2012 kuwata-lab.com all rights reserved
  44. 44. まとめ copyright© 2012 kuwata-lab.com all rights reserved
  45. 45. • 一般のプログラミング言語には 「分解」「構築」「抽象化」 の機能がある • SQLはそれらが弱っちい • モダンなORMなら、それらの機能 をSQLに提供できる ORMはSQLの高水準言語 or DSL! copyright© 2012 kuwata-lab.com all rights reserved
  46. 46. おしまい copyright© 2012 kuwata-lab.com all rights reserved
  • ssuser581ffc

    Dec. 16, 2020
  • ssusera4d074

    Dec. 7, 2020
  • ssuser8c8762

    Feb. 21, 2020
  • sisimaru244

    Feb. 12, 2020
  • yukinishi4

    Feb. 7, 2020
  • ssuseraae6851

    Feb. 6, 2020
  • TakayukiChiyo

    Sep. 22, 2019
  • teamasa

    Jul. 7, 2019
  • YasuhitoIwakura

    Nov. 19, 2018
  • MasayaChonan

    Feb. 23, 2018
  • mktktmr

    Oct. 31, 2017
  • HidekiTanaka9

    Sep. 21, 2017
  • jasdfhnakano

    Apr. 17, 2017
  • MihoTanaka8

    Apr. 10, 2017
  • takeshifukshima

    Mar. 27, 2017
  • syamaguchi

    Feb. 7, 2017
  • yoichi221

    Jan. 28, 2017
  • toshiakisako

    Jan. 27, 2017
  • folocolo

    Jan. 16, 2017
  • sakuban

    Jan. 8, 2017

(PgDay2012発表資料) SQLにとって、なぜO/Rマッパーが重要かを説明した資料です。

Aufrufe

Aufrufe insgesamt

90.009

Auf Slideshare

0

Aus Einbettungen

0

Anzahl der Einbettungen

5.358

Befehle

Downloads

0

Geteilt

0

Kommentare

0

Likes

194

×