編集
1 つのイメージが 20 のテーブルの 1 つだけによって所有されている場合、この設計は機能する可能性があります。
People (PersonId, Name)
Places (PlaceId, Name)
Dogs (DogId, Breed)
Doors (DoorId, Height, Width)
Images (ImageId, ImageBinary, OwnerId, OwnerTable)
OwnerTable は、OwnerId が属するテーブルの名前またはコードです。
これにより、イメージ テーブルで 20 個の FK、または 20 個の関連付けテーブルを節約できます。次に、結合で、結合先のテーブルに応じて、OwnerTable を指定します。
Id には変換可能な型 (TINYINT、SMALLINT、INT など) を使用する必要があり、できればすべてに対して 1 つの型 (INT など) を使用する必要があり、トリガーやその他のコードを使用して参照整合性を自分で管理する必要があります。
/編集
3 つではなく、5 つのテーブルが必要です。
People (PersonId, Name)
Places (PlaceId, Name)
Images (ImageId, ImageBinary)
ImagesPeople (ImageId, PersonId)
ImagesPlaces (ImageId, PlaceId)
フィールドは好きなように呼び出すことができます。People.Id、ImagesPeople.PersonId など。
しかし、あなたができないことは次のようなものです:
People (PersonId, Name)
Places (PlaceId, Name)
Images (ImageId, ImageBinary, PlaceOrPersonId)
できますが、データベースは関係を強化するのに役立ちませんし、FK がどのテーブルに属しているかを教えてくれません。どうやって知る?ID のインクリメントをずらしたり、イメージにタイプ列を追加したり、GUID を使用したりするなど、ハック的な回避策があります。
または:
Things (ThingId PK, Type)
People (ThingId PK/FK, Name, Age)
Places (ThingId PK/FK, Name, LatLon)
Images (ImageId PK, ImageBinary, ThingId FK)
画像を「モノ」にすることもできます。たまにこういうデザインを見かけます。参照整合性は提供されますが、型の排他性は提供されません。People、Places、および Images で同じ ThingId を持つことができ、データベースは気にしません。そのルールを自分でコーディングする必要があります。
編集: Cylon Cat の提案で、シナリオ 4:
People (PersonId, Name)
Places (PlaceId, Name)
PeopleImages (PeopleImageId, ImageBinary)
PlaceImages (PlaceImageId, ImageBinary)
ここでは、画像は 1 人の人物または場所によって独占的に所有されています。バージョン 2 に似ていますが、外部キーが宣言されています。必要な結合が少ないため、5 つのテーブル設計よりもパフォーマンスが向上する場合があります。「PeopleImage」と「PlaceImage」に置き換えられた、別個のエンティティとしての「Image」を失います。