Question

Scénario

J'ai 3 tables de base de données. L'un est pour les images et les deux autres sont des personnes et amp; Des endroits. Étant donné que chaque personne peut avoir plusieurs images et que chaque lieu peut avoir plusieurs images, je souhaite avoir une relation UN À PLUSIEUX entre les personnes et les images, ainsi que les lieux et les images.

Question

La clé étrangère doit-elle porter le même nom que la clé primaire? Ou est-il possible pour moi d'appeler la clé étrangère dans la table des images quelque chose de générique, par exemple "PKTableID". De cette façon, je n'ai besoin que d'une seule table d'images.

Une aide grandement appréciée.

Cordialement,

EDIT:

Si vous souhaitez ne disposer que d'une seule table d'images, chaque image ne fait référence qu'à une seule autre table. En plus de cela, j'ai utilisé l'exemple de deux tables. La base de données que j'utiliserai comportera 20 tables. Je voulais donc savoir s'il était encore possible d'utiliser une seule table pour 20 relations individuelles. ?

Était-ce utile?

La solution

EDIT

Si une image n'appartient qu'à une seule des vingt tables, cette structure pourrait fonctionner:

People (PersonId, Name)
Places (PlaceId, Name)
Dogs (DogId, Breed)
Doors (DoorId, Height, Width)
Images (ImageId, ImageBinary, OwnerId, OwnerTable)

Où OwnerTable est le nom ou le code de la table à laquelle appartient OwnerId.

Cela vous ferait économiser 20 FK dans la table d’image, ou 20 tables d’association. Ensuite, dans les jointures, vous spécifierez OwnerTable, en fonction de la table à laquelle vous vous connectez.

Vous devez utiliser des types convertibles pour les ID (par exemple, TINYINT, SMALLINT et INT), et de préférence un type pour tous (par exemple, INT), et vous devez gérer vous-même l'intégrité référentielle par le biais de déclencheurs ou d'un autre. code.

/ EDIT

Vous avez besoin de 5 tables et non de 3:

People (PersonId, Name)
Places (PlaceId, Name)
Images (ImageId, ImageBinary)
ImagesPeople (ImageId, PersonId)
ImagesPlaces (ImageId, PlaceId)

Vous pouvez appeler les champs comme vous le souhaitez. People.Id, ImagesPeople.PersonId, etc.

Mais ce que vous ne pouvez pas faire est quelque chose comme ceci:

People (PersonId, Name)
Places (PlaceId, Name)
Images (ImageId, ImageBinary, PlaceOrPersonId)

Bien, vous le pouvez, mais la base de données ne vous aidera pas à renforcer la relation, ni à vous dire à quelle table appartient le FK. Comment saurais tu? Il existe des solutions astucieuses telles que l’échelonnement des incréments d’identification, l’ajout d’une colonne de type à Images ou l’utilisation de GUID.

Alternativement:

Things (ThingId PK, Type)
People (ThingId PK/FK, Name, Age)
Places (ThingId PK/FK, Name, LatLon)
Images (ImageId PK, ImageBinary, ThingId FK)

Vous pouvez également faire des images une "chose". Parfois, vous voyez des dessins comme celui-ci. Cela vous donne une intégrité référentielle, mais pas une exclusivité de types. Vous pouvez avoir le même ThingId dans les personnes, les lieux et les images, et la base de données ne s’en soucie pas Vous devez coder cette règle vous-même.

Modifier: à la suggestion de Cylon Cat, scénario 4:

People (PersonId, Name)
Places (PlaceId, Name)
PeopleImages (PeopleImageId, ImageBinary)
PlaceImages (PlaceImageId, ImageBinary)

Ici, les images appartiennent exclusivement à une personne ou à un lieu. Similaire à la version 2, mais avec des clés étrangères déclarées. Il peut présenter des avantages en termes de performances par rapport à la conception à 5 tables, car moins de jointures sont nécessaires. Vous perdez " Image " en tant qu'entité distincte, remplacée par "PeopleImage". et "PlaceImage".

Autres conseils

Comme Peter l'a souligné, vous avez vraiment besoin de relations multiples, à moins que vous ne vouliez restreindre vos images à des images composées d'une seule personne. Par ailleurs, un index de bonnes adresses reflétera la nature hiérarchique des noms de lieux (Montmartre, Paris, France). = trois noms possibles pour un lieu).

Techniquement, vous pouvez appeler vos index et vos tables de tout ce qui n’est pas un mot réservé et qui n’a pas déjà été utilisé. X, Y, Z12345 et WOBBLY sont des noms valides pour un index.

Dans la pratique, il est toutefois préférable de suivre une convention de dénomination qui indique ce qui est stocké et à quoi sert Les tables PEOPLE_X_IMAGES et une table PLACES_X_IMAGES seraient donc une bonne idée dans votre cas. Vous n'avez pas vraiment besoin de quoi que ce soit à propos de personnes ou de lieux dans le tableau des images réelles. De même, vous n'avez besoin de rien des images dans les tableaux PEOPLE et PLACES.

Vous pouvez théoriquement ajouter deux clés étrangères à la table des images, une pour les personnes et une pour les lieux. Vous pouvez ensuite autoriser les valeurs NULL et rejoindre les colonnes appropriées lors de l'exécution d'une requête. Ce n’est pas vraiment une solution, car à quoi ressemble cette table lorsque vous avez 14 tables à joindre?

Si vous n'allez pas utiliser de GUID, je vous dis de le configurer autant que possible pour le prochain utilisateur qui doit le comprendre.

Vous pouvez utiliser une table, mais vous aurez besoin de vingt champs différents pour les relations. Si vous configurez une relation de clé étrangère, toutes les données doivent alors se rapporter à la table parent. Vous ne pouvez pas stocker deux relations de clé étrangère dans une seule table. Vous devez donc configurer une colonne pour chaque fk que vous souhaitez avoir.

Que diriez-vous de

Person (PersonId PK, Name, ImageId FK)
Image (ImageId PK, Name)
Place (PlaceId PK, Name, ImageId FK)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top