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.
ORMとの付き合い方
中国地方DB勉強会 in 岡山
@patorash
自己紹介
名前:尾古 豊明(おこ とよあき)
twitter:@patorash
株式会社リゾーム所属
普段はRuby on Railsでショッピングセンター向けのシステム開発をしてます。
SQLわからんマンだったのでCakePHPで初めてOR...
新支部長からの質問
RDBの新機能にORMって中々ついていけないものだと思っているんですが、普段、業
務でどこまでORMで使ってるんだろう?とか気になります。
会社の人に、「ORMってDBが変わっても、それなりに気にせず使える、ってメリットはあ...
ORMとは?
● Object-relational mapping(オブジェクト関連マッピング)
● データを取得したタイミングで、データを元にオブジェクトを生成する。
● 特定のテーブルとクラスが1対1になっていて、そのクラスのメソッド経由...
ORMの利点
1. 異なるDBの違いを吸収してくれる
2. SQLを書かなくてもいい(自動生成してくれる)
3. プレイスホルダーによってエスケープをよしなにしてくれる
(SQLインジェクション対策)
ORMのよくない点
1. 遅い(オブジェクト生成)
2. リソースを食う(メモリ消費が大きい)
3. 特定のDBの便利な機能が使えない
4. 複雑なデータを取得しようとするとSQLより難しい
5. 頑張れば1回で取得できるデータなのに、
何度も...
そもそも論として…SQL派の人へ
1. 速いのは正義ですが、そんなにスピード求められますか?
ORMでも高速にデータ取得する方法は準備されてたりしますが。
(マッピングせずに配列として取得するとか)
2. 特定のDBの機能、頻繁に使いますか?
...
そもそも論として…ORM派の人へ
1. データベース自体の変更ってよくありますか?
(ビジネスがかなり拡大してきたらありえるとは思う)
2. なにがなんでもORMで処理しなければならないことってありますか?
3. ORMを使っててもDB制約は利...
どうして二元論にしようとするのか?
1. ORMかSQLのどちらかに統一されてないと気持ち悪いですか?
2. 目的は、いいプロダクトを作ること
3. ORMを使ったほうが便利なものはORMで
4. SQLを書いた方が楽な場合はSQLで
5. と...
ORMの利点(ActiveRecord)
1. 直感的なデータ検索
2. データの整合性チェックが容易
3. コールバックによる連携更新
4. 取得したデータがオブジェクトなのでさらに直感的に
5. 変更に強い
6. テスト可能になる
7. テ...
SQLの利点
1. 方言はあるものの、だいたいどのDBでも同じ
2. ORMで表現しづらいことが比較的楽に書ける
SQLのよくない点
1. 直感的ではない
2. SQLがわかる人しか書けない
3. テストが(簡単には)できない
4. データの整合性チェックが(簡単には)できない
5. 変更に弱い
6. 作者の意図を表現できない(ORMだとメソッド名で表現で...
ORMの利点(ActiveRecord)
1. 直感的なデータ検索
2. データの整合性チェックが容易
3. コールバックによる連携更新
4. 取得したデータがオブジェクトなのでさらに直感的に
5. 変更に強い
6. テスト可能になる
7. テ...
1.直感的なデータ検索(ActiveRecord)
user = User.find 1 # => idが1のUserを取得する
user = User.find_by email: ‘admin@example.com’ # => メアドでU...
1.直感的なデータ検索(多少複雑なJOIN編)
User.joins(“INNER JOIN (#{Comment.group(:user_id).select(“user_id,
COUNT(user_id)”).to_sql}) AS co...
2. データの整合性チェック
class User < ApplicationRecord
# 必須
validates :name, presence: true
# 必須かつカタカナのみ
validates :kana, presence:...
2. データの整合性チェック
class User < ApplicationRecord
end
class Group < ApplicationRecord
end
class UserGroup < ApplicationRecord
...
6. テスト可能
● データの整合性チェック、本当に正しいものが定義できてる?
● 複雑な条件でのみ登録・更新できるパターンの検証は人力では難しい
例1)1人のユーザーが所有できるモンスターの上限は3000。
   3001番目が登録されたら…...
ORMの検証とDB制約の利用
ORMとDB制約を使ってデータの整合性を担保
DBに保存
DB制約
ORMのデータ検証
入力データ
・外部キー制約
・ユニーク制約
・NOT NULL制約
・フォーマット検証
・外部キー制約
・ユニーク制約
・NOT NULL制約
・複雑なビジ...
ORMとDB制約で冗長では?
ORMとDB制約を使ってデータの整合性を担保
DBに保存
DB制約
ORMのデータ検証
入力データ
・外部キー制約
・ユニーク制約
・NOT NULL制約
・フォーマット検証
・外部キー制約
・ユニーク制約
・NOT NULL制約
・複雑なビジ...
ORMの利用シーン
1. Webアプリケーションのいたるところで利用
2. 不具合の調査(rails console、デバッガ)
3. 頻繁に変更がありうる処理
SQLの利用シーン
1. データ分析(主に集計。UNIONしたりとか、Window関数使うとか)
2. ORMで表現するのが難しい処理(whereの条件が複雑とか)
3. 滅多に変更がない処理
まとめ
1. 適材適所で付き合おう
2. ORM使ってたとしてもDBの勉強は必要
3. ORMとDB制約のダブルチェックで安全なデータ管理
Upcoming SlideShare
Loading in …5
×

Ormとの付き合い方

932 views

Published on

第20回中国地方DB勉強会の発表資料です。

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Ormとの付き合い方

  1. 1. ORMとの付き合い方 中国地方DB勉強会 in 岡山 @patorash
  2. 2. 自己紹介 名前:尾古 豊明(おこ とよあき) twitter:@patorash 株式会社リゾーム所属 普段はRuby on Railsでショッピングセンター向けのシステム開発をしてます。 SQLわからんマンだったのでCakePHPで初めてORMに触れたときはあまりの便利さに 衝撃を受けて全てORMになってくれ!と思ったものでした。 ORMの出すSQLを読んで、SQLがわかるようになってきたので、 今SQLが読めるのはORMのおかげと言っても過言ではありません。 最近は集計処理用のSQLを書くのが楽しい。 一昨年に息子が生まれ、子育てに奮闘中。
  3. 3. 新支部長からの質問 RDBの新機能にORMって中々ついていけないものだと思っているんですが、普段、業 務でどこまでORMで使ってるんだろう?とか気になります。 会社の人に、「ORMってDBが変わっても、それなりに気にせず使える、ってメリットはあ るものの、複雑なSQLの場合、ORMよりもSQLで書いた方が(工数的に)速い場合とか あって、実際、どうすれば良いんですか?」って聞かれたりもして、ORMとどこまで付き 合うべきなんでしょうか。
  4. 4. ORMとは? ● Object-relational mapping(オブジェクト関連マッピング) ● データを取得したタイミングで、データを元にオブジェクトを生成する。 ● 特定のテーブルとクラスが1対1になっていて、そのクラスのメソッド経由でデータ を取得する(Rubyで使われるORMのActiveRecordなどの場合)
  5. 5. ORMの利点 1. 異なるDBの違いを吸収してくれる 2. SQLを書かなくてもいい(自動生成してくれる) 3. プレイスホルダーによってエスケープをよしなにしてくれる (SQLインジェクション対策)
  6. 6. ORMのよくない点 1. 遅い(オブジェクト生成) 2. リソースを食う(メモリ消費が大きい) 3. 特定のDBの便利な機能が使えない 4. 複雑なデータを取得しようとするとSQLより難しい 5. 頑張れば1回で取得できるデータなのに、 何度もクエリを発行するような処理を書いてしまいがち。 結果、さらに遅くなる…。 6. ORMでのデータ取得にこだわりすぎる人が現れる
  7. 7. そもそも論として…SQL派の人へ 1. 速いのは正義ですが、そんなにスピード求められますか? ORMでも高速にデータ取得する方法は準備されてたりしますが。 (マッピングせずに配列として取得するとか) 2. 特定のDBの機能、頻繁に使いますか? 3. ORMのプレイスホルダーを利用したエスケープって便利じゃないですか?
  8. 8. そもそも論として…ORM派の人へ 1. データベース自体の変更ってよくありますか? (ビジネスがかなり拡大してきたらありえるとは思う) 2. なにがなんでもORMで処理しなければならないことってありますか? 3. ORMを使っててもDB制約は利用しますよね? (ユニーク制約、NOT NULL制約、Indexなどなど…) 4. クエリ発行回数は意識してますか? DBへのアクセス数が多いのは怠慢ですよ!(ウッ…
  9. 9. どうして二元論にしようとするのか? 1. ORMかSQLのどちらかに統一されてないと気持ち悪いですか? 2. 目的は、いいプロダクトを作ること 3. ORMを使ったほうが便利なものはORMで 4. SQLを書いた方が楽な場合はSQLで 5. とはいえ、9割方ORMを使ってます
  10. 10. ORMの利点(ActiveRecord) 1. 直感的なデータ検索 2. データの整合性チェックが容易 3. コールバックによる連携更新 4. 取得したデータがオブジェクトなのでさらに直感的に 5. 変更に強い 6. テスト可能になる 7. テーブル定義の変更の履歴が残る
  11. 11. SQLの利点 1. 方言はあるものの、だいたいどのDBでも同じ 2. ORMで表現しづらいことが比較的楽に書ける
  12. 12. SQLのよくない点 1. 直感的ではない 2. SQLがわかる人しか書けない 3. テストが(簡単には)できない 4. データの整合性チェックが(簡単には)できない 5. 変更に弱い 6. 作者の意図を表現できない(ORMだとメソッド名で表現できる)
  13. 13. ORMの利点(ActiveRecord) 1. 直感的なデータ検索 2. データの整合性チェックが容易 3. コールバックによる連携更新 4. 取得したデータがオブジェクトなのでさらに直感的に 5. 変更に強い 6. テスト可能になる 7. テーブル定義の変更の履歴が残る
  14. 14. 1.直感的なデータ検索(ActiveRecord) user = User.find 1 # => idが1のUserを取得する user = User.find_by email: ‘admin@example.com’ # => メアドでUserを取得 users = User.admin.where(created_at: 1.month.ago..Time.zone.now) # => 1ヶ月以内に作られた管理者を取得 articles = Article.joins(:user).merge(User.normal).published .order(updated_at: :desc).limit(10) # => 一般ユーザーが作った公開中の記事を更新日降順に10件取得 soft_destroyed_comments = Commnet.only_soft_destroyed # => 論理削除されたコメントを取得
  15. 15. 1.直感的なデータ検索(多少複雑なJOIN編) User.joins(“INNER JOIN (#{Comment.group(:user_id).select(“user_id, COUNT(user_id)”).to_sql}) AS comments ON users.id = comments.user_id”).select(“*”) # => ユーザー毎のコメント数を含むユーザー一覧を取得 複雑なJOINもto_sqlを使ってSQL化(サブクエリ化)してしまえば、 そこまで難しくない。 (INNER JOINとONを書くのがダサイという意見は当然ある)
  16. 16. 2. データの整合性チェック class User < ApplicationRecord # 必須 validates :name, presence: true # 必須かつカタカナのみ validates :kana, presence: true, format: {with: /A[ァ-ー]+z/} # 必須かつ3〜20文字以内 validates :code_name, presence: true, length: { in: 3..20 } # 必須かつ一意である validates :email, presence: true, uniqueness: true end user = User.new user.valid? # => false
  17. 17. 2. データの整合性チェック class User < ApplicationRecord end class Group < ApplicationRecord end class UserGroup < ApplicationRecord # 1つのグループに1人の人が複数登録されるのを防ぐ validates :user, presence: true, uniqueness: { scope: group_id } end user_group = UserGroup.new(user_id: 1, group_id: 1) user_group.save # => true user_group = UserGroup.new(user_id: 1, group_id: 1) user_group.save # => false
  18. 18. 6. テスト可能 ● データの整合性チェック、本当に正しいものが定義できてる? ● 複雑な条件でのみ登録・更新できるパターンの検証は人力では難しい 例1)1人のユーザーが所有できるモンスターの上限は3000。    3001番目が登録されたら…? 例2)メールアドレスの重複登録はできないが、退会済ユーザーの    メールアドレスは再登録できるように。 例3)A,B,Cが登録されてようやくDが登録できる ● データの取得に関しても同様に、正しいデータが取得できてる? 例1)前回のログイン以降に更新されたデータ件数を取得 例2)公開フラグのあるデータのみを取得できているか? ユニットテストで検証が可能!(RubyならRspecやMinitestなど) ※SQLも取得結果はプログラミング言語側でテスト可能
  19. 19. ORMの検証とDB制約の利用
  20. 20. ORMとDB制約を使ってデータの整合性を担保 DBに保存 DB制約 ORMのデータ検証 入力データ ・外部キー制約 ・ユニーク制約 ・NOT NULL制約 ・フォーマット検証 ・外部キー制約 ・ユニーク制約 ・NOT NULL制約 ・複雑なビジネスロジックの検証
  21. 21. ORMとDB制約で冗長では?
  22. 22. ORMとDB制約を使ってデータの整合性を担保 DBに保存 DB制約 ORMのデータ検証 入力データ ・外部キー制約 ・ユニーク制約 ・NOT NULL制約 ・フォーマット検証 ・外部キー制約 ・ユニーク制約 ・NOT NULL制約 ・複雑なビジネスロジックの検証 DB制約がないとSQL で 更新されたら不正な データができる!
  23. 23. ORMの利用シーン 1. Webアプリケーションのいたるところで利用 2. 不具合の調査(rails console、デバッガ) 3. 頻繁に変更がありうる処理
  24. 24. SQLの利用シーン 1. データ分析(主に集計。UNIONしたりとか、Window関数使うとか) 2. ORMで表現するのが難しい処理(whereの条件が複雑とか) 3. 滅多に変更がない処理
  25. 25. まとめ 1. 適材適所で付き合おう 2. ORM使ってたとしてもDBの勉強は必要 3. ORMとDB制約のダブルチェックで安全なデータ管理

×