ORMを使用する場合、データベース設計で注意すべき点は何ですか


19

オブジェクトリレーショナルマッパー(ORM)ウィキペディアを使用してデータベースにアクセスすることがわかっている場合に注意すべきデータベース設計の落とし穴は何ですか?Entity Framework NHibernateまたはLLBLGenProも参照してください。

例として、SqlServerのRPC呼び出しの2100パラメーターの制限に注意してください。これは、LLBLgenを使用し、複合主キーが使用されているときにテーブルを結合する場合の問題です。複合キーのMSDN記事を参照してください


4
オフェンスはありませんが、「複数の主キーを持つテーブルを結合する」..これにより、テーブルの基本ルールの1つ、テーブルごとに1つのPKが再定義されます。正確にはどういう意味ですか?
マリアン

これはどのように2100パラメーター制限に達しますか?その数の列を持つテーブルがありますか?また、「オブジェクトロールモデリング」では
ジョンサンダース

SQL 'IN'(LINQ array.Contains(member))に値の大きなリストを渡すと、2100パラメーターの制限が問題になることがあります。ただし、データベースの設計には実際には何もありません。それはクエリパターンの問題です。それから「苦しむ」ORMの最も簡単な回避策は、リストを[永続的な]一時テーブルに挿入し、それに結合するか、または元々どこからでもクエリされるアイテムを選択するサブクエリを使用することです。(とにかく、ORマッパーを使用しているかどうかに関係なく、SQLの「IN」に何千ものアイテムを渡すことは一般に悪いことです)。
クリストファー

@ジョンは、はいリレーショナルマッピングオブジェクト
BozoJoe

4
@BozoJoe:テーブルは、定義上、1つの主キーのみを持つことができます。単一のテーブルに複数の主キーを定義できるDBMSはありません。
a_horse_with_no_name

回答:


17

主に第3正規形への標準正規化手法を実行します。一部のORMは、データベースレベルで定義された関係を取得できるため、手動で行う必要はありません。

私は本当に反対に行き、ORMについて何を知っておくべきか尋ねます。次のことを確認してください。-クエリのプロファイルを作成するにはどうすればよいですか?-ORMをオーバーライドして独自のクエリを作成するにはどうすればよいですか?-代わりにストアドプロシージャを使用できますか?

データベースは、おそらくアプリよりも長持ちするため、ORMに依存しない必要があります。


+1:「データベースはORMに依存しない」。データベース設計の標準に準拠すると、優れたORMも満足します。
MicSim

12
  1. ORMにスキーマを作成または更新させないでください。生成されたSQLを常にテンプレートとして使用しますが、変更を行う前にそれを確認します(ORMは冗長なインデックスを作成し、不正なデータ型を使用しています...

  2. ORMができないことを認識してください。Djangoはしばらくの間、ORMを介したgroup byをサポートしていませんでしたが、これは苦労しました(それでも、レガシーシステムは楽しいです!)。したがって、ORMのコードを記述しているDBAでなくても、DBMにとってORMの制限を認識することは必須です。

  3. 定期的に、スローログを取得し、mysqlslowlogを介して集計し、トップ10程度を確認します。基本的には、全体で最も集約時間のかかったクエリが表示されます。平均1秒しかかからず、過去1か月に5万回実行されたクエリは、その集計レポートにひどい親指のように突き出します;)

ORMを完全にダンプするほど極端に進むとは言いません。ORMを使用する開発者がDBAでない場合、ORMと同じくらい悪いSQLを書く可能性があります。したがって、最終的には何が起こっているかを見るためにDBAに落ちます。


1
また、ストアドプロシージャに非常に複雑なロジックを配置することを検討してください。ORMはストアドプロシージャを呼び出すことができ、非常に複雑なロジックの場合、プロシージャのパフォーマンスチューニングが簡単になります。
HLGEM

7

SequelActiveRecord for RubyのようなORMによって作成されたデータベースとは異なるレガシーデータベースについて、私はすぐに気づきました。

  1. と呼ばれるすべてのテーブルでの主キーの使用'id'。ええ、それはオーバーライドできますidが、デフォルトです。
  2. テーブルに複数の名前を使用する。
  3. アンダースコア(「ヘビケース」)を使用して、テーブルとフィールドの説明的な名前を作成する単語を区切ります。
  4. _id外部キーへの追加の使用:レイアウトは通常次のようになりreferenced_table_idます。

私はORMを信頼していなかったため、長年にわたって手作業でSQLを書いてきましたが、過去2〜3年にわたって、前述の2つのORMの使用を開始し、既存のデータベースとの統合の良さに感銘を受けました。そして、彼らの慣習が守られている場合、データベースをどれだけうまく解読できるか、またはレガシーDBを理解するために必要なヒントを時間をかけて提供します。

ORMで適切に動作するようにスキーマを設計するための一般的なガイドラインがあるかどうかはわかりませんが、いくつかの標準があればメリットがあると思います。特に優れたオブジェクト指向言語を使用していて、スケジュールが厳しい場合は、ORMの時間と場所は間違いなくあります。


1
参考:多くのORマッパーの命名規則の違いに対処するツールがあります。Entity FrameworkおよびLinq-to-SQLのルールベースの名前付けを処理するVisual Studioのアドインがあります。詳細については、huagati.com / dbmltoolsを参照してください。
クリストファーA

1
Idは、idフィールドに名前を付けるためのSQLアンチパターンであり、使用しないでください。
HLGEM

なぜ説明するのですか?1対多や多対1のようなルックアップを行う必要がある場合、テーブル間の関係をどのように処理しますか?私が使用するORMでは、IDを使用しないことはフローに確実に反します。
ティンマン

2

(:))使用しているORマッパーによって多少異なりますので、問題のORマッパーをサポートしている/サポートしていないdbの調査に時間をかけます。

たとえば、MicrosoftのORマッパーは、SQL Serverの組み込みデータ型のすべてをサポートしておらず、一部の新しい/高度なTSQL機能(再帰クエリ、オプティマイザーヒントなど)をサポートしていません。

理論的には、優れたORマッパーは、適切に設計されたリレーショナルデータベーススキーマを優れたオブジェクトモデルに克服する(そしてマッピングできる)ほど柔軟でなければなりません。現実には、パズルのすべてのピースが配置される前にまだやることがあります。多くのORマッパーは高度なマッピングをサポートしていますが、多くの場合、複雑なクエリとパフォーマンスの問題を犠牲にします。

DBのパフォーマンスを向上させるため(およびDBAの健全性を維持するために:))、DBスキーマ設計に関してはベストプラクティスに従う必要があります。最初に正規化し、[/ if]が必要な場合は非正規化します。コード側では、オブジェクトモデルを使いすぎないでください。ORマッパーが複雑な継承モデルと多くのテーブルをマージするエンティティをサポートしている場合でも、これらはデータベースなどにヒットする非常に複雑なクエリで問題が発生するリスクがある領域です。プロファイル、プロファイル、プロファイル、およびORM生成されたクエリを許可します。ORマッパーで生成されたクエリは、通常のSQLクエリと同じように微調整できることが多く、オブジェクト側で機能的に同等の2つのクエリ(linqクエリなど)が大きく異なるSQLクエリになる場合があることに注意してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.