2009-02-05 16 views
21

Una domanda di progettazione DB: quando decidi di utilizzare le tabelle di relazione 1 a 1?Quando utilizzare le relazioni 1 a 1 tra le tabelle del database?

Uno dei posti che vedo è, ad esempio, quando si ha una tabella User e UserProfile, la gente li divide invece di mettere tutte le colonne solo in una tabella Utente.

Tecnicamente, puoi semplicemente mettere tutte le colonne in una tabella poiché la loro relazione è 1-a-1.

So che qualcuno ha detto che per la tabella UserProfile, nel tempo è necessario modificare la tabella per aggiungere più colonne, ma non credo che questo sia un motivo valido per dividere le tabelle.

Quindi, se devo progettare una tabella utente e una tabella UserProfile, è meglio per me limitarmi a farlo in una tabella?

+0

Possibile duplicato di [C'è mai un momento in cui l'uso di una relazione di database 1: 1 ha senso?] (Http://stackoverflow.com/questions/517417/is-there-ever-a-time-where-using -a-database-11-relationship-fa-sense) – Tripartio

risposta

16

L'unica volta che ho usato una relazione 1 a 1 è quando voglio che appartenga polimorficamente a più oggetti.

Come un indirizzo, ad esempio. Un utente ha un indirizzo, un'azienda ha un indirizzo, un ristorante in vetrina ha un indirizzo. Tutte le istanze sono gestite nella stessa tabella e hanno lo stesso codice che la governa. Pensa a come refactoring del tuo datamodel in modo da poterlo riutilizzare in altri luoghi.

5

Solo quando i campi nella tabella UserProfile non sono richiesti per tutto il numero di record nella tabella utente. Ad esempio se hai 3.000.000 di utenti, ma solo 3.000 di questi hanno UserProfiles, può essere sensato dividerli (per evitare un sacco di colonne vuote).

Anche se ora un giorno con l'aumento dei database velocità e costi economici di archiviazione, non fa molta differenza dividerli per questo motivo ...

10

Pensa a come progettare gli oggetti di business. Avrai un oggetto User con 50 proprietà su di esso, o hai intenzione di avere un oggetto User con alcune proprietà di dettaglio, e poi un oggetto Profile che contiene altri dati per un profilo?

È necessario utilizzare 1-a-1 quando i dati nella tabella sono correlati, ma non sono lì per lo stesso scopo. (probabilmente potrebbe essere meglio indicato)

Inoltre può rendere le cose più facili da trovare. Non molte cose odio di più che dover guardare attraverso un tavolo con 75 colonne.

2

Ne ho visto uno di recente in cui avevi una tabella, con la maggior parte dei dati, quindi un'altra tabella con molti e molti dati opzionali.

La seconda tabella aveva un terzo delle righe, ma tre volte il numero di colonne.

Questo è stato eseguito alcuni anni fa evitando un sacco di null in colonne, ad esempio lo spazio vuoto.

Tuttavia, se lo state facendo ora, tenterei di non disturbare. Vivi con lo spazio vuoto La seccatura che può causare lo sviluppo di applicazioni semplicemente non ne vale la pena, e lo spazio è più economico del tempo di sviluppo.

9

Il motivo classico è evitare colonne nullable.

Avere un valore NULL in una colonna può rendere più difficile scrivere SQL chiaro (gestibile). @Ovid ha scritto su questo here, attingendo al lavoro di Chris Date.

+0

+1 Buona risposta. Dal punto di vista dello sviluppatore di un'applicazione, sarei ancora tentato di vivere con i valori null e utilizzare un buon ORM come NHibernate. –

3

Questa è una copia e incolla diretta da un'altra domanda che è comparsa oggi in questa discussione, ma ci si sente utile anche qui. Is there ever a time where using a database 1:1 relationship makes sense?

Io li uso principalmente per alcuni motivi. Uno è cambiamenti significativi nella velocità di cambiamento dei dati. Alcune delle mie tabelle possono avere tracce di controllo in cui tengo traccia delle versioni precedenti dei record, se mi interessa solo tenere traccia delle versioni precedenti di 5 colonne su 10 suddividendo queste 5 colonne su una tabella separata con un meccanismo di controllo su di essa è più efficiente. Inoltre, potrei avere dei record (diciamo per un'app di contabilità) che sono solo di scrittura. Non è possibile modificare gli importi in dollari o l'account a cui erano destinati, se si è commesso un errore, è necessario creare un record corrispondente per scrivere, correggere il record errato, quindi creare una voce di correzione. Ho dei vincoli sulla tabella che fanno rispettare il fatto che non possono essere aggiornati o cancellati, ma potrei avere un paio di attributi per quell'oggetto che sono malleabili, quelli sono tenuti in una tabella separata senza la restrizione sulla modifica. Un'altra volta che faccio questo è nelle applicazioni di registrazione medica. Vi sono dati relativi a una visita che non possono essere modificati una volta che è stato firmato e altri dati relativi a una visita che possono essere modificati dopo la chiusura. In tal caso, suddividerò i dati e inserirò un trigger sulla tabella bloccata che rifiuta gli aggiornamenti sulla tabella bloccata una volta firmato, ma consentendoti di aggiornare i dati che il medico non ha firmato.

Un altro poster ha commentato che il 1: 1 non è stato normalizzato, non sarei d'accordo con questo in alcune situazioni, specialmente con i sottotitoli. Supponiamo che abbia una tabella dei dipendenti e che la chiave primaria sia il loro SSN (è un esempio, salviamo il dibattito sul fatto che questa sia una buona chiave o meno per un altro thread). I dipendenti possono essere di diversi tipi, ad esempio temporanei o permanenti e se sono permanenti hanno più campi da compilare, come il numero di telefono dell'ufficio, che dovrebbe essere non nullo se il tipo = 'Permanente'. In un 3 ° database di moduli normali la colonna dovrebbe dipendere solo dalla chiave, ovvero dal dipendente, ma in realtà dipende dal dipendente e dal tipo, quindi una relazione 1: 1 è perfettamente normale e auspicabile in questo caso. Previene anche tabelle troppo sparse, se ho 10 colonne che sono normalmente riempite, ma 20 colonne aggiuntive solo per determinati tipi.

0

Penso che Shane D abbia una ragione che è abbastanza valida. Poiché anche io mi sono imbattuto nella stessa situazione per una tabella con circa 40 colonne, i dati per queste colonne sono caricati tramite csvs e usati solo per scopi di reporting e un insieme di colonne per elaborare quei file, che sono frequentemente aggiornabili.

Quindi, se manteniamo una tabella come soluzione. Eseguiamo aggiornamenti frequenti su tale tabella e aggiorneremo solo 5 colonne di 50. Ritengo che ogni aggiornamento disturba l'assegnazione delle righe e vi è un'elevata possibilità di concatenamento di righe, quindi per evitare il concatenamento di righe, ho seguito l'approccio di separazione dei dati basato sull'attività DML.

Fatemi sapere se una soluzione migliore

1

Questo è stato ben indirizzato, ma mi limiterò a aggiungere una breve nota per chiarire qualcosa che non era ovvio per me e non è stato esplicitamente dichiarato. Una relazione 1 a 1 non significa che per ogni record nella tabella A ci sia 1 record corrispondente nella tabella B. Invece, per ogni record nella tabella A ci saranno 0 o 1 record corrispondenti nella tabella B.

Shane D. e altri descrivono scenari che sfruttano questo fatto.