エンドユーザーがアップロードしたファイルを追跡するデータベーステーブルを設計しようとしています。
ファイルはさまざまなコンテキストでアップロードできます。
各コンテキストは異なるテーブルです。
例として:
この(不自然な)シナリオのエンティティ/テーブルは次のとおりです。
Employees (Id, Name)
Expenses (Id, Date, RequestedRefund, RequestedByEmployeeId)
Pets (Id, Name, Type, BelongsToEmployeeId)
ファイル自体に関する情報を追跡するFiles
というテーブルがすでにあります。Files (Id, Name, Size, Extension, Folder)
私の質問は、経費領収書のアップロードとペットの写真のアップロードをファイルレコードに対してどのようにマッピングするかです。私はこれを2つの方法で実行できることを知っています。
汎用マッピングテーブルを1つ用意します:GenericFileMap (FileId, ContextId, Type)
どこ
FileId
はファイルレコードのIDですContextId
は、取得しようとしているコンテキストレコードのIDです。Type
は、コンテキスト自体を説明するフィールドですこのシナリオでは、従業員のすべての経費領収書を次のように取得します。
_SELECT *
FROM Employee e
INNER JOIN Expenses ex ON e.Id = ex.RequestedByEmployeeId
INNER JOIN GenericFileMap g ON g.ContextId = ex.Id AND g.Type = 'expense'
INNER JOIN Files f ON g.FileId = f.Id
_
エンティティ/コンテキストテーブルごとに個別のマッピングテーブルを用意します。
ExpenseFiles (ExpenseId, FileId)
PetFiles (PetId, FileId)
領収書のクエリは次のようになります。
_SELECT *
FROM Employee e
INNER JOIN Expenses ex ON e.Id = ex.RequestedByEmployeeId
INNER JOIN ExpenseFiles ef ON ef.ExpenseId = ex.Id
INNER JOIN Files f ON ef.FileId = f.Id
_
最初のオプションは、リレーショナルデータベースで処理を行う「正規化された」方法ではないと思います。しかし、これを検討している唯一の理由は、私の特定の状況では、ユーザーがファイルをアップロード/添付できる少なくとも15の異なるコンテキストがあることです。
最初のオプションから私が見る唯一の利点は、すべてのコンテキストごとにテーブルとストアドプロシージャ(CRUDに1つずつ)を作成および複製する時間を節約できることです。
ただし、2番目のオプションは、物事を行う「正しい」方法であると思われます。
私の質問:
次の理由により、オプション#1は必要ありません。
ContextId
とType
をFiles
テーブルに配置することもできます。TypeID TINYINT
_フィールド(および関連するType
ルックアップテーブル)を使用すると、毎回非効率的な文字列比較を行う必要がなくなります。おそらく最善の方法は、変更されたオプション#2です。はい、コンテキスト固有のファイルマップテーブル(たとえば、ExpenseFiles
、PetFiles
など)から始めますが、_ContextTypeID TINYINT
_列も追加します既存のFiles
テーブル内。また、_ContextTypeID TINYINT NOT NULL
_を主キーとする新しいContextType
ルックアップテーブルも必要です(ただし、notにしてIDENTITY
列にします)。 Name
列をルックアップテーブルに追加し、Files
からContextType
への外部キーをContextTypeID
に追加できます。 Files
テーブルにこの新しい列があると、関連するレコードがどのコンテキスト固有のファイルマップ/プロパティテーブルにあるかを簡単に判断できます。
オプション#2を使用する理由は、15の異なるコンテキストがある場合でも、必然的に、少なくともそれらの一部は時間の経過とともに進化および分岐するためです。だからあなたは持っているかもしれません:
ExpenseFiles (ExpenseId, FileId, Date, Total)
PetFiles (PetId, FileId, Name, Age, AnimalType)