私が取り組んでいる1つのWebアプリケーション内で、すべてのデータベース操作は、Entity Framework ORMで定義されたいくつかの汎用リポジトリを使用して抽象化されています。
ただし、汎用リポジトリのシンプルなデザインを実現するには、関連するすべてのテーブルで一意の整数(Int32
C#、int
SQL)を定義する必要があります。これまで、これは常にテーブルのPKであり、IDENTITY
。
外部キーは頻繁に使用され、これらの整数列を参照します。これらは、一貫性とORMによるナビゲーションプロパティの生成の両方に必要です。
通常、アプリケーション層は次の操作を実行します。
- テーブルからの初期データロード(*)-
SELECT * FROM table
- 更新 -
UPDATE table SET Col1 = Val1 WHERE Id = IdVal
- 削除 -
DELETE FROM table WHERE Id = IdVal
- 挿入 -
INSERT INTO table (cols) VALUES (...)
頻度の低い操作:
- 一括挿入 -
BULK INSERT ... into table
その後に(*)すべてのデータロード(生成された識別子を取得するため) - 一括削除 -これは通常の削除操作ですが、ORMの観点からは「一括」です。
DELETE FROM table where OtherThanIdCol = SomeValue
- 一括更新 -これは通常の更新操作ですが、ORMの観点からは「一括」です。
UPDATE table SET SomeCol = SomeVal WHERE OtherThanIdCol = OtherValue
*すべての小さなテーブルはアプリケーションレベルでキャッシュされ、ほとんどすべてSELECTs
がデータベースに到達しません。典型的なパターンは、初期ロードと多数のINSERT
s、UPDATE
s、DELETE
sです。
現在のアプリケーションの使用状況に基づいて、どのテーブルでも1億レコードに達する可能性は非常にわずかです。
質問: DBAの観点から見ると、このテーブル設計の制限があると、重大な問題が発生しますか?
[編集]
回答(素晴らしいフィードバックをありがとう)と参考記事を読んだ後、詳細を追加する必要があるように感じます。
現在のアプリケーションの詳細 -モデルを他のアプリケーションにも再利用できるかどうかを理解したいので、現在のWebアプリケーションについては触れませんでした。ただし、私の特定のケースは、DWHから多くのメタデータを抽出するアプリケーションです。ソースデータは非常に乱雑で(奇妙な方法で非正規化され、いくつかの不整合があり、多くの場合自然な識別子がありません)、私のアプリは明確に分離されたエンティティを生成しています。また、生成された識別子(
IDENTITY
)の多くが表示されるため、ユーザーはそれらをビジネスキーとして使用できます。これは、大規模なコードのリファクタリングに加えて、GUIDの使用を除外します。「行を一意に識別する唯一の方法であってはなりません」(Aaron Bertrand♦)-これは非常に良いアドバイスです。また、すべてのテーブルでUNIQUE CONSTRAINTを定義して、ビジネスの重複が許可されないようにします。
フロントエンドアプリ駆動設計とデータベース駆動設計 -設計の選択はこれらの要因によって引き起こされます
Entity Frameworkの制限 -複数の列PKは許可されますが、値は更新できません
カスタム制限 -単一の整数キーを持つことで、データ構造と非SQLコードが大幅に簡素化されます。たとえば、すべての値リストには整数キーと表示値があります。さらに重要なことは、キャッシュ用にマークされたテーブルが
Unique int key -> value
マップに入れられることを保証します。
複雑な選択クエリ -すべての小さな(20〜30K未満のレコード)テーブルデータがアプリケーションレベルでキャッシュされるため、これはほとんど発生しません。これにより、アプリケーションコードを書くときの生活が少し難しくなります(LINQを書くのが難しくなります)が、データベースのヒットはずっと良くなります。
リストビュー -
SELECT
ロード時にクエリ(すべてがキャッシュされます)または次のようなクエリを生成しません。SELECT allcolumns FROM BigTable WHERE filter1 IN (val1, val2) AND filter2 IN (val11, val12)
他のすべての必要な値はキャッシュルックアップ(O(1))を通じてフェッチされるため、複雑なクエリは生成されません。
ビューの編集 -次の
SELECT
ようなステートメントを生成します。SELECT allcolumns FROM BigTable WHERE PKId = value1
(すべてのフィルターと値はint
sです)