Content-Length: 307128 | pFad | https://www.slideshare.net/slideshow/sqlor/15499745#31
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か? | PPTSQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
- 3. SQL
-- 販売成績上位10コを抽出
select * from sales
where deleted = false
order by amount desc
limit 10
文法的には正しいけど…
copyright© 2012 kuwata-lab.com all rights reserved
- 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. 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. 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. 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. 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. 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
- 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. Ruby
## 使い方
def sales_top(n, rows)
return top(n, active(to_sales(rows)))
end
分解した関数を
組み合わせる
copyright© 2012 kuwata-lab.com all rights reserved
- 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
- 18. • 「全体」 「部分」
を に分解する機能
• 「部分」 「全体」
から を構築する機能
• 「部分」に名前をつけて抽象化する機能
copyright© 2012 kuwata-lab.com all rights reserved
- 20. SQL
-- 販売成績上位10コを抽出
select * from sales
where deleted = false
order by amount desc
limit 10
copyright© 2012 kuwata-lab.com all rights reserved
- 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. 「部分」を組み合わせて 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
- 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. 「部分」を組み合わせて 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
- 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. サンプルコード:
Sequel
copyright© 2012 kuwata-lab.com all rights reserved
- 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. 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
- 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
- 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
- 40. • SQLには部品化の機能がない
→ SQLが長くなる・わかりにくい
→ 複数のSQLで要素の重複が多い
• ORMはSQL要素の部品化ができる
→ SQL構築が簡潔・わかりやすい
→ 複数のSQLで部品を共用できる
copyright© 2012 kuwata-lab.com all rights reserved
- 41. • SQLには部品化の機能がない
→ SQLが長くなる・わかりにくい
→ 複数のSQLで要素の重複が多い
• ORMはSQL要素の部品化ができる
→ SQL構築が簡潔・わかりやすい
→ 複数のSQLで部品を共用できる
copyright© 2012 kuwata-lab.com all rights reserved
- 43. まだ進化の途中な
高水準へと進化 ので暖かい目を!
Lisp, Ruby Modern ORM
C, Pascal JDBC, DBI
Assembler SQL
低水準から
copyright© 2012 kuwata-lab.com all rights reserved
- 45. • 一般のプログラミング言語には
「分解」「構築」「抽象化」
の機能がある
• SQLはそれらが弱っちい
• モダンなORMなら、それらの機能
をSQLに提供できる
ORMはSQLの高水準言語 or DSL!
copyright© 2012 kuwata-lab.com all rights reserved
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: https://www.slideshare.net/slideshow/sqlor/15499745#31
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy