Domanda

Scenario

Ho 3 tabelle di database. Uno è per le immagini e gli altri due sono People & amp; Posti. Dal momento che ogni persona può avere molte immagini e ogni luogo può avere molte immagini, voglio avere una relazione ONE TO MANY tra persone e immagini, nonché luoghi e immagini.

Domanda

La chiave esterna deve essere chiamata con lo stesso nome della chiave primaria? O è possibile per me chiamare la chiave esterna nella tabella delle immagini qualcosa di generico, ad esempio "PKTableID". In questo modo ho solo bisogno di una tabella di immagini.

Aiuto molto apprezzato.

Saluti,

EDIT:

Il motivo per voler avere una sola tabella di immagini è perché ogni immagine si riferisce solo a una singola altra tabella. Oltre a questo, ho usato l'esempio qui di due tabelle, il database effettivamente che userò avrà 20 tabelle, quindi volevo sapere se era ancora possibile utilizzare una TABELLA DI IMMAGINI SINGOLA PER 20 RELAZIONI DA UNO A MOLTO ?

È stato utile?

Soluzione

Modifica

Se un'immagine è sempre e solo di proprietà di una delle venti tabelle, questo design potrebbe funzionare:

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

Dove OwnerTable è il nome o il codice della tabella a cui appartiene OwnerId.

Ciò risparmierebbe 20 FK nella tabella immagine o 20 tabelle di associazione. Quindi, nei join, dovresti specificare OwnerTable, a seconda della tabella a cui ti stai unendo.

Dovresti usare tipi convertibili per gli ID (ad es. TINYINT, SMALLINT e INT) e preferibilmente un tipo per tutti (ad es. INT) e dovresti gestire tu stesso l'integrità referenziale anche se innesca o qualche altro codice.

/ EDIT

Sono necessarie 5 tabelle, non 3:

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

Puoi chiamare i campi come vuoi. People.Id, ImagesPeople.PersonId, ecc.

Ma ciò che non puoi fare è qualcosa del genere:

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

Bene, puoi, ma il database non ti aiuterà a far rispettare la relazione, né ti dirà a quale tabella appartiene l'FK. Come lo sapresti? Esistono soluzioni alternative hacker come scaglionare gli incrementi dell'ID, aggiungere una colonna di tipo a Immagini o utilizzare GUID.

In alternativa:

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

Puoi anche fare delle Immagini una "Cosa". A volte vedi disegni come questo. Ti dà integrità referenziale, ma non digitare esclusività. Potresti avere lo stesso ThingId in Persone, Luoghi e Immagini e al database non importerebbe. Dovresti codificare tu stesso quella regola.

Modifica: su suggerimento di Cylon Cat, scenario 4:

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

Qui, le immagini sono di proprietà esclusiva di una persona o di un luogo. Simile alla versione 2, ma con chiavi esterne dichiarate. Potrebbe avere alcuni vantaggi in termini di prestazioni rispetto al design a 5 tavoli, poiché sono necessari meno join. Perdi " Immagine " come entità distinta, sostituita da " PeopleImage " e " PlaceImage " ;.

Altri suggerimenti

Come ha sottolineato Peter, hai davvero bisogno di molte o molte relazioni, a meno che tu non voglia limitare le tue immagini alle immagini con una sola persona, inoltre, un buon indice dei luoghi rifletterà la natura gerarchica dei nomi dei luoghi (Montmartre, Parigi, Francia = tre nomi possibili per un posto).

Ora tecnicamente puoi chiamare i tuoi indici e le tue tabelle qualsiasi cosa che non sia una parola riservata e che non sia già stata utilizzata, X, Y, Z12345 e WOBBLY sono tutti nomi validi per un indice.

In pratica, tuttavia, è meglio seguire una convenzione di denominazione che punti su ciò che viene archiviato ea cosa serve. Quindi le tabelle PEOPLE_X_IMAGES e un PLACES_X_IMAGES sarebbero una buona idea nel tuo caso. Non hai davvero bisogno di nulla su persone o luoghi nella tabella delle immagini reali. Allo stesso modo non hai bisogno di nulla sulle immagini nelle tabelle PEOPLE e PLACES.

È possibile aggiungere teoricamente due chiavi esterne alla tabella delle immagini, una per Persone e una per Luoghi. Quindi è possibile consentire null e unire le colonne appropriate durante l'esecuzione di una query. Questa non è una soluzione molto, perché come appare questa tabella quando hai 14 tavoli che devono unirsi ad esso?

Se non hai intenzione di usare i GUID, allora dico di averlo impostato come molti-a-molti per il bene del prossimo che deve capirlo.

È possibile utilizzare una tabella ma per le relazioni occorrerebbero venti campi diversi. Se si imposta una relazione di chiave esterna, tutti i dati devono essere correlati alla tabella padre, non è possibile memorizzare due relazioni di chiave esterna in una tabella. Quindi devi impostare una colonna per ogni fk che vuoi avere.

Che ne dici

Person (PersonId PK, Name, ImageId FK)
Image (ImageId PK, Name)
Place (PlaceId PK, Name, ImageId FK)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top