È buona norma SQL utilizzare il GUID per collegare più tabelle allo stesso campo Id?

1

Voglio collegare più tabelle a una tabella many-to-many (m2m).

Una tabella si chiamerebbe posizione e questa tabella si troverà sempre su un lato della tabella m2m.

Ma avrò un elenco di diverse tabelle, ad esempio:

  • Carte
  • Foto
  • Illustrazioni
  • Vettori

L'utilizzo di GUID tra queste tabelle per collegarlo a una singola colonna in un'altra tabella dovrebbe essere considerato "Good Practice"? Mysql mi consentirà di farlo automaticamente in cascata gli aggiornamenti e cancellarli? In tal caso, più cascate comportano problemi?

UPDATE

Ho letto quel GUID (un numero esadecimale) Generalmente occupa più spazio in un database e rallenta le query. Tuttavia potrei comunque generare id 'unici' semplicemente avendo l'iniziale della tabella come parte dell'id in modo che l'id della carta di tabella sia c0001, e quindi Illustrazioni sia I001. Indipendentemente da questo cambiamento, le domande rimangono valide.

    
posta Mallow 13.11.2012 - 02:23
fonte

5 risposte

2

Per default i database non supportano questo tipo di relazione (come tu hai disegnato). L'ho usato prima senza imporre la chiave esterna che va a più tavoli diversi. Dovevo occuparmi di tutte le relazioni nel codice. Generalmente è considerata una cattiva idea.

Il modo "giusto" è di avere tabelle CardLocation , PhotographLocation , ecc. ognuna con la propria chiave primaria Guid (ad esempio CardLocationId ). Se ti capita di dover appendere dati comuni da ogni relazione, allora crei un'altra tabella chiamata LocationRelationship e crei la chiave primaria delle tabelle delle relazioni (ad esempio CardLocationId ) anche una chiave esterna che fa riferimento a LocationRelationshipId . Quindi, ogni record in CardLocation ha un record corrispondente in LocationRelationship . In questo modo è possibile applicare tutte le relazioni nel database relazionale. Sfortunatamente è molto più complicato.

Modifica

Dopo aver riflettuto un po 'di più, l'altro modo per farlo è avere Card , Photograph , ecc., tutti derivano da una base comune (chiamiamola Locatable ). Quindi crei una nuova tabella chiamata Locatable con la chiave primaria LocatableId . Quindi CardId è sia una chiave primaria che dovrebbe essere anche una chiave esterna che fa riferimento a LocatableId e PhotographId è anche una chiave esterna a LocatableId . Quindi hai solo una tabella molti-a-molti chiamata LocatableLocation con chiavi esterne a LocatableId e LocationId .

Meno tabelle e sembra implicare meglio l'intento.

    
risposta data 13.11.2012 - 03:34
fonte
2

Ho commenti sul tuo attuale modello di dati.

1 - Dovresti avere un m-m separato per ogni relazione e non 1 tabella come ti mostri attualmente nel modello. Una ragione è che un'eventualità della tabella m-m potrebbe essere per uno o più valori FK. Un'eliminazione a cascata può eliminare diverse righe nella tabella m-m che contengono valori FK che non si desidera eliminare.

2 - La tua relazione dalla tabella da un lato a quella di giunzione è probabilmente facoltativa da un lato non obbligatoria mentre la modelli. La relazione facoltativa causa la creazione di un FK Null e ciò impedisce che si verifichi una sovrapposizione rimuovendo il valore non null e sostituendolo con null (se questo è ciò che si desidera).

3- La tua relazione dalla m-m alla tabella Location probabilmente non dovrebbe essere obbligatoria in quanto eliminerebbe le posizioni sull'eliminazione di una Carta, ad esempio. Potresti desiderare che questo sia facoltativo (vedi 2 sopra).

4 - Hai davvero bisogno di m-m? Sei sicuro? La tua attività non è chiara dalla domanda, ma forse hai solo bisogno di un 1-m. Dimostralo a te stesso con un esempio prima di modellarlo.

5 - È possibile evitare di avere 4 tabelle che probabilmente avrebbero le stesse colonne creando 1 tabella delle risorse con una colonna di tipo. Il tipo potrebbe essere: Carta, Illustrazione, ecc. In questo modo si salvano 3 tabelle e 3 tabelle di giunzione.

6 - Non è bene usare nomi di tabelle plurali. Microsoft lo faceva, ma non va bene! Preferisci nomi di tabelle singolari. I nomi plurali sono utili per denominare le raccolte.

Ora come da domanda relativa al GUID, puoi usare GUID ma renderà il test molto difficile. Renderebbe anche trovare una riga utilizzando GUID un incubo per l'utente se questa è una funzione prevista nel sistema. Le prestazioni possono risentire di enormi database. Prendi in considerazione l'utilizzo del tipo int quando possibile. Coding Horor - GUID come pro e contro del PK .

    
risposta data 13.11.2012 - 04:00
fonte
1

un GUID viene solitamente rappresentato come una stringa esadecimale, ma è più appropriato memorizzarlo in un formato binario (piuttosto che varchar) se lo spazio è una considerazione; di solito è in un RDBMS.

Non c'è niente di sbagliato nell'usare un GUID come chiave esterna o chiave primaria. Se assicuri che le tue tabelle abbiano gli indici corretti, non dovrebbe influire affatto sulle prestazioni.

    
risposta data 13.11.2012 - 02:54
fonte
1

Non vedo nulla inerentemente sbagliato con questo design, ma devi notare che stai associando implicitamente un Card , Illustration , Photograph e Vector avendo loro condividono una chiave.

La tua posizione avrà più serie di attributi. Ogni set conterrà zero o uno Card , Illustration , ecc. Sono questi Card e Illustration più correlati di qualsiasi altra carta o illustrazione collegata alla posizione? In caso contrario, lo schema non modella i dati in modo accurato.

Quello che hai qui non è una relazione "molti-a-molti". Location può avere correttamente molti Vectors (e così via), ma ogni Vector può avere solo un Location . Questa è solo una relazione molti-uno. Se è ciò di cui hai bisogno, puoi farlo molto più semplice: la tabella Location ha la chiave primaria e le altre tabelle hanno semplicemente una chiave esterna indietro alla tabella Location , senza un vincolo univoco su quella chiave esterna colonna.

Infine, se stai collezionando un numero di attributi su una posizione, perché non avere solo una tabella LocationAttribute che memorizza

  • LocationID
  • AttributeTypeId
  • Valore ( varchar o qualsiasi altra cosa)

e quindi un set definito o una tabella di tipi di attributi - 1 = Card , 2 = Photograph e così via.

    
risposta data 13.11.2012 - 03:49
fonte
1

Lo scopo di Guid è garantire valori univoci nei database distribuiti. Ad esempio, se si generano FooBars in 2000 database separati, si utilizzerà un Guid per garantire che siano univoci senza dover controllare i database 2000 per verificare se il valore esiste. L'algoritmo Guid ha l'indirizzo mac inserito nell'algoritmo per garantire che 2 macchine non generino lo stesso valore.

Il lato negativo di un Guid è che è grande. Ciò significa che gli indici saranno più grandi e potrebbero non adattarsi alla memoria. Ciò significa che la corrispondenza del valore Guid è lenta. Utilizza un Guid solo quando ti serve un guid.

Se i dati vengono generati in una posizione centrale (non distribuita), si vorrà utilizzare un numero intero. Rendilo auto_increment. Ciò manterrà le cose piccole su disco e memoria. E la corrispondenza è più veloce.

Stai provando a utilizzare 1 tabella di mappatura per tutte le tabelle. Ma con quel design non è possibile inserire una chiave esterna nella tabella di mappatura. Invece dovresti avere una mappatura separata per ciascuno.

"Potresti" creare una tabella Master con Schede, Vettori, Illustrazioni, ecc. come sottotipi tramite chiave esterna. Quindi utilizzare la tabella principale nella mappatura alla posizione. Ma fallo solo se le cose sono veramente sotto-tipi di un tipo di master.

    
risposta data 13.11.2012 - 21:19
fonte

Leggi altre domande sui tag