ORM
#データベース
ORMとは
テーブルとオブジェクトをマッピングし、オブジェクトをそのテーブルであるかのように表現する
また、そのオブジェクトを用いて、マッピングテーブルを操作できるようにする
ORMの主なメリット
1. DB操作をSQL無しでオブジェクト指向で行える
2. セキュリティ(SQLインジェクション対策)の向上を狙える
3. DBの移植性が上がる
ORMの主なデメリット
1. 速度が生SQLよりも遅い場合がある
2. 複雑なSQL(主にクエリ・読込)が書けない
ORM vs. SQL論争
ORMで全部解決!!ってわけでもないのが世の常。
「ORMとか百害あって一利なしだ」て意見、逆に「SQLはクソコードで読めねぇ」ていう意見、色々あるわけです。
O/Rマッピングは百害あって一利なし! - Qiita
language agnostic - Using an ORM or plain SQL? - Stack Overflow
どう使い分けるよ
このORMとSQLをどう使い分けよかなと思っとるんですが、自分としましては...以下がいいかなと
変更系処理はORM
読込系処理はSQL
ORMは、複雑なSQL書けない、パフォーマンス遅いってのは確かにそうだなって思うんです。
でも、使いやすいからさ、変更だけはORMでやらせてくんね?って思うわけ
プロジェクトが小さいなら...
プロジェクトが小さいなら、性能とかあんまシビアになってこないから、ORMでいいよ、うん。
そんな複雑なSQL発行せんやろたぶん。
所感.icon
正味な話さ、複雑なSQLって読み込み時くらいしか使わんくね?onigiri.w2.icon
CUD(Create, Update, Delete)って、そんな複雑なことせんよな?www
てなると以下の使い分けがいいのでは?
読込は生のSQL
変更はORM
できるだけ楽したいんよな...
だからさ、ORMつかわせてくれよ...たのむよ
参考:DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
まさにこの人のように、変更・読込を別々にしよう。
そしてら、うまいこと行くはずよ多分
あと、1点だけ気になってたことがあってさ...
ORMってトランザクション処理というかブロックの制御ってちゃんとできるんかな?
ここ複雑なことになってたらだるそうやなって思ったÅ
良さげな英語記事見つけた
(3) Get know your ORM - avoid bad habits... | LinkedIn
まあでもさいずれにせよさ...
SQLからは逃れられねぇよ!!!
参考
ORMは使ったほうがよいの?SQL - Qiita
O/Rマッピングは百害あって一利なし! - Qiita
ORMとはなんぞや - WEB開発ノート
ORMとは?|SQLAlchemy 概要と基本の使い方
O/Rマッピング(O/Rマッパー / ORM)とは - 意味をわかりやすく - IT用語辞典 e-Words
オブジェクト関係マッピング - Qiita
切り取り線.icon
ORMとはなんぞや - WEB開発ノート
ORMとは、Object-Relational Mappingの頭文字をとったものです。
その名前からわかる通り、オブジェクトと関係(関係データベース、RDB)とのマッピングを行うものです。
オブジェクトとRDBをつなげるやつってことやなonigiri.w2.icon
多くのプログラミング言語はオブジェクトを扱うので、そのオブジェクトをRDBに保存できるように、対応付けを簡単にするためORMを使います。
SQLを直接書くことなく、オブジェクトのメソッドでDB操作ができる、ということです。
はいはい、ここ重要ポイントonigiri.w2.icon
SQLを使わずにDB操作が可能なんよ
また、DBの作成やマイグレーションといったDB操作もORMで行うことができます
へぇ〜〜〜、ORMありきのマイグレーションなのねonigiri.w2.icon
RDB特有と言うよりはORM特有の概念なのね
オブジェクト関係マッピング - Qiita
次項で説明する「インピーダンス・ミスマッチ」を解消して
関係データベース(RDB)のレコードを、オブジェクトとして直感的に扱えるようにする。
また、RDBにアクセスするプログラムを書く際の煩雑な処理を軽減させ、
プログラマはSQLを意識することなくプログラムを書ける。
ここでも言ってるな。SQLを意識することなくプログラムを書けるとonigiri.w2.icon
なるほどなるほど
インピーダンス・ミスマッチ
オブジェクト指向は「現実世界の物事に即したデータモデル」である一方で、
関係データベースは「検索やCRUDなどの処理に最適化されたデータモデル」となっている。
この間を取り持つのがORMだろ?onigiri.w2.icon
だから、マッピングて言ってるもんな
ORMとは?|SQLAlchemy 概要と基本の使い方
ORMは、簡単に言えば、RDB(Relational Database: 関係データベース)に対するデータの操作をオブジェクト指向型言語(Object-Oriented Programming Language: OOP1)のやり方で扱えるようにするための手法と言えます。
はいはい、オブジェクト指向言語のやり方でDBを操作するのねonigiri.w2.icon
確かに、Todo.save(), Todo.find()とかって、オブジェクト指向っぽいな
ORMを使わない場合の課題
1. DBへの操作は動的SQLで行うことになるのだが、文法エラーがあるか実行時まで不明
2. プログラム言語とは全く異なるSQLを書く必要があること自体しんどい
3. 1オブジェクトに関係するテーブルが2つ以上あると、読込処理、更新処理ともにしんどい
ホイホイ、まあ、SQLのことはできれば気にしたくないよなonigiri.w2.icon
全部プログラムコードだけで書きたい
ORMのメリット
1. SQLを書かなくていい
2. オブジェクト指向的にDB操作可能
3. RDBへの処理がカプセル化されてて使いやすい
はいはい、使いやすいねこれだとonigiri.w2.icon
ただし、課題もある
1. ORMツールの使い方を覚えないといけない
2. 内部の挙動が把握できない(SQLのチューニングに課題)
まあ、どっちもわかるonigiri.w2.icon
ただ、「1.」は覚えれば良いだけの話なので別に問題ない。
loggingライブラリだって、様々な言語を使うたびに覚えてないといけない。
それと一緒やから、ここは別にonigiri.w2.iconにとっては課題ではない。
問題は「2.」やな
気づいたら、N+1問題が起きてたとかありそうやし。
SQLの速度遅い時にどうしようもない状況になったりしそうやし。
カスタマイズできるとしても、そのカスタマイズ方法をちゃんと知る必要がある
まあ、ここは別に良いんやけど
とにかく内部にSQLを隠されすぎて、性能劣化とか起きた時にチューニングしにくいってのは結構なマイナスポイント
ORMではなくストアドを使用するのも1つの方法
ストアドとはOracleで言うとPL/SQLで書かれたDB内部のプログラムですが、PostgresSQLにも、Microsft SQL Serverにも同様の機能が存在します。
ストアドは「手続き型言語」にはなりますが、SQLをベースにした文法であり、単発のSQLでは書けない複雑な一連の処理を定義することができます。
既にSQLは理解していて「SQLよりも複雑な処理が必要」という動機であれば、ORMではなくストアドを使用するのも一つの方法です(※ストアドができれば、後はそれを呼び出すだけでよい)。
ストアドね、覚えておこうonigiri.w2.icon
SQLを書かずに、その定義されてる処理を呼び出すみたいな感じよな。
頭の隅に置いておこうか
ORMは使ったほうがよいの?SQL - Qiita
特定のクラスとテーブルが一対一になっていて、そのクラスのインターフェースを使用し、データ操作を行える
データ取得時に、そのデータを元にオブジェクトを生成
クラスとテーブルは1:1になるように表現されてるんか
あ〜〜〜、そうか、ちょっと理解したぞ
各テーブルをオブジェクトで表現してるのが「ORM」か
テーブル操作をオブジェクト指向っぽくできるってそう言うことね。理解。
言って仕舞えば、ORMで表現されたオブジェクトは、テーブルそのものって言い方ができるな
ORMのメリット
1. SQL処理を簡単に短く書ける
2. RDBの具体(MySQL, PostgreSQL, Oracle, SQLite, ...)を変えても、コードを変更する必要がない
はいはい、よく言われてるORMの利点の1つがありますonigiri.w2.icon
具体DBをコードへの影響なしに変えれるっていう。
ORMが緩衝材になってくれるっていう。
うんうん。
ORMのデメリット
1. 複雑なクエリをかけない
2. 複雑なクエリを書こうとすると、SQLを書くことになり、SQLとORMの記述が混在して統一性がなくなる
なるほど、理解しましたonigiri.w2.icon
複雑なクエリは書けないのね。
でもSQLを使えば書けると。はいはい。
「2.」の方は、ちゃんとディレクトリ・ファイル構成を綺麗にしておけば、そこまでデメリットではないと思うなonigiri.w2.icon
統一性がなくなるのは仕方ないと思う。ORMの制約があるのだし。
統一性がなくなるからって、0から全部SQLとかマジで書きたくない。
原則はORMで一部複雑な箇所はSQLって言う棲み分けは全然あり。
ただ、スパゲッティにならんように、ORM, SQLを使ってる箇所をいい感じに区分けることは大事
ORM非推奨は、新人が使う場合、ORMになれると内部的に何が起こっているのかまで目を向けることが少なくなる。また、DBの違いを吸収してくれることを使うのはあまりない。
これなぁ、グサッとくるわぁonigiri.w2.icon
俺なんか、SQLさっぱりわからんからなww
SELECT, INSERTくらいよ
DBの違いを吸収する場面は確かにないw
そもそもリリース後にDBを変えることって結構稀やし
長いプロジェクトは、テーブル構造などが変わるため、どうしてもORMで表現できず、複雑なSQLを要求される場合が現実的に出てくる。
へぇ〜〜〜〜〜onigiri.w2.icon
まあ、そうやんな、結局ORMの内部ではSQLやってくれてるもんな。
ORMの目的は「SQLを覚えさせない」ではないからな。
内部でSQL使ってるなら、やっぱり知識としてSQL・DB知識は必要やな。
てまあ、これは当たり前やけど。
SQL使おうが、ORM使おうが、DB知識・SQL知識は絶対必要やわ。
O/Rマッピングは百害あって一利なし! - Qiita
私の場合、ORMを使う主な理由は「セキュリティ」ですね。
いまでもSQLインジェクションが絶えないのは、SQLは本質的には、文字列じゃないことにあると思います。
正確には文字列ではなく、メタ文字列であるべきかと思ってます。
セキュリティ面ね。
別にORMを使わずとも、プレースホルダーを使う的なサムシングあるよなonigiri.w2.icon
q.icon ORMでセキュリティが上がるの?onigiri.w2.icon
また、特に他人の書いたSQLの○○コードを読むのはつらいです。
DBにストアドプロシージャーを作るのが前提だともう訳がわかりません。
はいはい、他人の書いたSQLはスパゲッティ過ぎてマジ無理理論ねonigiri.w2.icon
これはわかる。SQLってほんまにクソコードであればあるほど、読めなくなる。
普通のプログラミング言語よりも
マジで副クエリとかあると、いよいよ意味がわからんくなる
DBの入れ替えは普通に起こりうる
へぇ、あるんや。世界って広いなonigiri.w2.icon
https://qiita.com/gomiryo/items/6d448c500749f91242d2#comment-337f3d40c06ef33cf906
俺はこの人におおむね同意するわonigiri.w2.icon
CRUD以外の複雑なSQLを書く場面にあまり出会あったことがないからさ、単純なCRUDでほぼ十分じゃね?って思っちゃうのよ
だから、現状のスタンスとしてはORM推奨派
そして、単純なCRUDで対応できないDB操作は、別でSQLを書いたらいいやん。それは。
もし、システムを育てていく時に、ORM機能よりもSQLを書くことが多くなり始めたら、その時またORMに対して考えを改める。
現時点では、ORMを使うのは全然アリだと思う。
何回もSQL書きたくないわ。
CRUDしか必要ない簡単なシステムとかは特にな。
SQLのいい点(ORMと比較して) - still deeper
個人的にはORMで抽象化された範囲で十分かつシンプルなクエリが中心という使い方で十分であれば、ORMを採用した方がいいと思います。
https://qr.ae/pvJ3eV
ORM の利点:
ポータブル: ORM を使用して、構造を 1 回記述すると、ORM レイヤーが、構成された DBMS に適した最終的なステートメントを処理します。これは、MS SQL では「テーブルから上位 100 を選択する」のに対し、MySQL では select ステートメントの最後に「limit 0,100」として limit のような単純な操作が追加されるため、優れた利点です。
データのネスト: リレーションシップの場合、ORM レイヤーが自動的にデータを取得します。
単一言語: SQL 言語を知らなくても、開発言語だけでデータベースを処理できます。
追加は変更に似ています。ほとんどの ORM レイヤーは、新しいデータの追加 (SQL 挿入) とデータの更新 (SQL 更新) を同じ方法で処理します。これらにより、コードの記述と保守が簡単になります。
ORMの短所
遅い:未加工の SQL を記述する場合と ORM を使用する場合のパフォーマンスを比較すると、変換レイヤーがないため、未加工の方がはるかに高速です。
チューニング: SQL 言語とデフォルトの DBMS をよく知っている場合は、その知識を使用してクエリを高速化できますが、ORM を使用する場合は同じではありません。
複雑なクエリ:一部の ORM レイヤーには、特にクエリの実行時に制限があるため、生の SQL を記述していることに気付くことがあります。
学習: ビッグ データ プロジェクトで作業していてパフォーマンスに満足できない場合は、DBMS のヒットを最小限に抑えるために ORM レイヤーを学習する必要があります。