Oltre la normalizzazione nel database

7

Attualmente sto lavorando alla creazione di un nuovo schema del database come parte di un nuovo importante prodotto. I nostri precedenti record di indirizzo del cliente (in un prodotto precedente) hanno qualcosa del genere nel nostro schema corrente (non tutte le colonne sono mostrate):

AddressID, AddressLine1, AddressLine2, City, State. Zip, Country, Etc.

Voglio normalizzarlo in modo che in realtà un indirizzo si rompa in:

  • 1 indirizzo a molte linee di indirizzo
  • 1 indirizzo a un codice postale / postale

Quindi, ho inviato una comunicazione dicendo che il codice postale ora sarà nella sua tabella e che ogni "indirizzo" corrisponde a un codice postale / postale. Anche gli indirizzi verrebbero suddivisi in modo da poter supportare più di 2 linee di indirizzo con una relazione da 1 a molti.

Alcune persone nel mio gruppo ora stanno dicendo che sto finendo di normalizzare il database. Sono io?

Nota, non sono un DBA, ma ritengo che questo sia più logico e più efficiente dello schema precedente.

Aggiorna

Thx a tutti per il loro contributo. Non ho intenzione di rompere l'indirizzo o le cerniere per i propri tavoli. Il mio piano originale era di avere una ricerca del codice postale e di riutilizzarla per gli indirizzi, quindi avrei solo bisogno di un set di zip, ma lascerò semplicemente tutto sul record stesso, e avrò una tabella separata per le ricerche zip.

    
posta Jon Raynor 29.08.2011 - 23:05
fonte

12 risposte

17

Sei troppo anormale (e come specialista di database, non lo dico spesso).

Pensa a come usi questi dati e vedrai che ha più senso essere in una tabella. Se ogni indirizzo è correlato a più codici postali, una seconda tabella ha senso. Poiché il rapporto è uno a uno, non è affatto necessario dividere il tavolo a meno che non si disponga di un record troppo ampio, il che è raro il caso in una tabella di indirizzi.

Anche perché la tua configurazione non è il modo comune in cui sono archiviati questi dati, creerai un problema di manutenzione in quanto i nuovi sviluppatori saranno confusi dalla struttura. In realtà, ogni indirizzo dovrebbe essere completamente contenuto in un record.

    
risposta data 29.08.2011 - 23:23
fonte
3

Sì e no. È possibile avere una tabella di ricerca per i codici postali, tuttavia, non utilizzerei una chiave per mettere in relazione i due. Utilizza il codice postale effettivo nel record dell'indirizzo.

E dal momento che AddressLine1, AddressLine2, ecc. sono davvero piuttosto arbitrari, piuttosto che romperli nella propria tabella, basta cambiare il campo in AddressLines e farlo includere i feed di riga dove applicabile.

Renderà più facile la ricerca in un unico campo. E tu li mostri sempre insieme comunque. Poiché sono solo testo libero, non puoi fare nulla di significativo con loro divisi. Sei due campi AddressLine attualmente possono contenere qualsiasi cosa, dai numeri di casella, numeri di appt, indirizzi, cura del testo, ecc ... e non sai mai quale conterrà cosa. Se lo sai, dovrebbero essere etichettati meglio.

    
risposta data 29.08.2011 - 23:15
fonte
3

La tabella dei codici postali non è troppo insolita e ha senso se vuoi che altre informazioni siano legate ai codici postali: altre colonne nella tabella del codice di avviamento postale o riferimenti da altre tabelle (sulla falsariga dei venditori regioni che sono insiemi di codici postali).

Presumo che tu voglia le linee di indirizzo nella loro tabella perché vuoi seguire la prima forma normale. Non ho mai visto nessuno farlo davvero, probabilmente perché è così improbabile che tu abbia bisogno di più di un numero molto piccolo di colonne per le linee di indirizzo, mai.

Trovo improbabile che ne ricaverai un valore pratico. Prendi in considerazione alcune delle altre cose che potresti fare per modellare rigorosamente nomi e indirizzi:

1 Avere una tabella separata per ogni nome, invece di prima, ultima, metà, dal momento che una persona potrebbe avere un numero qualsiasi di nomi (ed è molto più comune che per le linee di indirizzo avere un gran numero di loro).

1 Gli indirizzi sono molti per molti con entità, dal momento che nel mondo reale questo è effettivamente il modo in cui funziona.

2 Utilizza il software di standardizzazione degli indirizzi per ottenere il giusto numero di mappature.

3 Supporto per l'indirizzamento internazionale per tutti i paesi.

4 Avere un nome da molti a molti con indirizzo, perché potresti usare nomi più informali quando contatti qualcuno a casa.

5 Avere il nome da molti a molti con l'entità, dal momento che alcune persone potrebbero usare soprannomi solo con certe persone.

Ora immagina di scrivere una query per inserire il nome e l'indirizzo di un gruppo di persone su un rapporto.

Qualcuno di questi modi di modellare i dati è sbagliato? No, non dentro e di se stessi. Ma per la maggior parte delle applicazioni sono più utili di quanto valgano. La tua domanda non ha reso il tuo caso diverso da quello che ti è sembrato logico. Sarei molto attento ad avere una buona giustificazione per la complessità aggiunta prima di apportare questa modifica, perché è una resistenza che unisce 14 tabelle per una query semplice, e quelle 14 tabelle possono insinuarsi su di te.

    
risposta data 29.08.2011 - 23:33
fonte
1

È difficile da dire. Di solito i codici postali e i codici postali non sono normalizzati in una tabella separata (dalla maggior parte dei database che ho visto), ma ci possono essere casi in cui ha senso. Non so abbastanza del tuo dominio aziendale per sapere se lo fa. Ho visto i database di report contenenti tabelle di codici postali / zip e quindi anche altri dati (alcuni codici - non so a cosa servivano) associati a ciascun codice postale / postale. In quel caso, gli indirizzi facevano riferimento ai codici postali / zip attraverso una combinazione di ID di territorio e qualcos'altro ... non era così semplice come speravo!

La normalizzazione delle linee di indirizzo sembra eccessiva. Quante volte farai riferimento allo stesso valore di Address Line 1 (supponendo che capisco cosa stai facendo)? Suppongo che potrebbe accadere dove hai centinaia di record in tutti i tipi di tabelle che fanno riferimento a "123 Main Street" ma mi sembra molto improbabile (ma se fai hai quel dati quindi potrebbe avere un senso).

    
risposta data 29.08.2011 - 23:09
fonte
1

Non ne so abbastanza della tua applicazione per sapere quando questa quantità di dati analizzati ha senso. Se hai bisogno di un strong controllo sulle combinazioni di codice postale paese-città-stato (registrazione degli elettori, risposta del veicolo di emergenza), puoi avere una tabella per gestirlo. Hai davvero bisogno di una strong comprensione di come funzioni, quindi non dipingi i tuoi utenti in un angolo dati. Le città possono avere più codici postali e alcuni codici postali possono avere più città o altre entità. Assicurati di poter giustificare questa complessità aggiuntiva. Altri membri della vostra azienda non sono d'accordo. Hai bisogno di un argomento migliore della normalizzazione.

Non è necessario suddividere le linee di indirizzo.

    
risposta data 29.08.2011 - 23:43
fonte
1

Un altro motivo per dividere le cose è se devi offrire la tua applicazione in più lingue dove la stessa città, stato e nome del paese possono essere diversi in ogni lingua.

Ho visto lo stesso indirizzo essere diverso in una lingua piuttosto che in un'altra. (pensa a rue e street) ma concordo sul fatto che per la maggior parte delle applicazioni i campi degli indirizzi possono essere tutti in una tabella.

Rompere un indirizzo in più campi rende la stampa delle etichette molto più facile e consente le condizioni del bordo in cui è l'indirizzo: intorno alla curva, all'angolo di x e y, in fondo alla strada da qui, e laggiù. Gli standard degli indirizzi nordamericani non vengono seguiti in tutto il mondo, quindi alcuni campi di indirizzi aggiuntivi sono di aiuto.

    
risposta data 30.08.2011 - 00:19
fonte
1

Non sono sicuro se questo si applica o no, ma penso di avere un caso crash-and-burn per il tuo schema: ho posseduto due proprietà all'interno di un singolo codice postale.

    
risposta data 31.08.2011 - 02:02
fonte
1

Se hai bisogno di visualizzare grandi insiemi di dati geografici (grafici, mappe, ...), segnalarci sopra, e tc, non normalizzare i dati dell'indirizzo sarà un vero incubo per le prestazioni.

Il problema che sto cercando di superare nel mio attuale progetto è "cattivi dati" e "dati incompleti". Abbiamo trovato persone che vivono in Belgio con codice di avviamento postale: "CHINA" nel database legacy dei nostri clienti. CARO DIO.

Farlo correttamente richiederà un sacco di pulizia dei dati e dovrebbe consentire un modo flessibile di aggiungere nuove città / codici di avviamento postale + unire i codici di avviamento postale quando le città si uniscono. In tutto il mondo questo succede molto. A seconda della dimensione del tuo progetto e dell'ambito geografico, dovresti considerare se vale la pena guardare i dati reali che hai.

    
risposta data 21.06.2013 - 21:16
fonte
0

Sì, probabilmente.

Hai un caso aziendale specifico / motivo concettuale per separarli? Hai considerato l'impatto sull'applicazione di rendere le query più complesse, sia in termini di prestazioni che di manutenzione delle applicazioni? Qualcuno dovrà ora eseguire il debug di query SQL che ora presentano una serie di join, dove prima era una selezione semplice? (Non sto parlando semplicemente selezionando gli indirizzi, ma quando è necessario estrarre gli indirizzi insieme ad altri dati).

La normalizzazione riguarda l'archiviazione dell'efficienza dei dati. Ma ci sono altri fattori importanti nello sviluppo del software che spesso superano la necessità dell'efficienza massima nell'archiviazione.

    
risposta data 29.08.2011 - 23:28
fonte
0

La normalizzazione per motivi di normalizzazione è una cattiva idea. Quanto lontano hai preso?

Come altri hanno già detto, la normalizzazione dell'indirizzo potrebbe avere senso, ma probabilmente lo renderà più difficile lavorare con.

Per i codici postali, non vedo molto di un punto. Sono lunghe solo 5 cifre (9 con +4) e come tali possono essere rappresentate da un singolo campo intero a 32 bit. Il mio suggerimento sarebbe quello di continuare a farlo, e se si presenta la necessità di dividerlo in una tabella separata, basta usare il codice postale come PK e schiaffare un FK sulla colonna esistente. Questo ti dà il vantaggio della normalizzazione, senza implementare qualcosa prima che ne hai bisogno ( YAGNI )

    
risposta data 29.08.2011 - 23:28
fonte
0

La regola generale consiste nel chiedere se le modifiche consentiranno di utilizzare solo una query per recuperare i dati che in precedenza implicavano alcune manipolazioni nel software o almeno consentire una query più semplice. La risposta qui è no. In effetti, le tue modifiche renderanno più complesse le query esistenti più comuni.

Sei già in grado di recuperare un elenco di indirizzi per codice postale. L'unica ragione per separarli sarebbe se si utilizzano i codici di avviamento postale per un altro scopo rispetto ai record dei clienti, come ad esempio digitare un codice di avviamento postale per compilare automaticamente la città e lo stato. Anche in questo caso, la chiave più semplice per la tabella di codici di avviamento postale è il codice postale stesso.

    
risposta data 29.08.2011 - 23:54
fonte
0

Cavolo.

A livello relazionale, non esiste una "sovra normalizzazione" o "sotto la normalizzazione". Invece, ci sono specifiche formali per la prima forma normale, la seconda forma normale e così via.

Le etichette postali hanno linee. Gli indirizzi no.

Da un lato, il fatto di includere i codici ZIP nella propria tabella non migliora necessariamente l'integrità dei dati. Potrebbe limitare gli utenti alla scelta di un codice postale esistente, ma potrebbe anche consentire agli utenti di associare un codice ZIP Alabama a San Francisco, California. D'altra parte, un riferimento a una chiave esterna a una tabella di {city, state, ZIP} probabilmente migliorerà l'integrità dei dati in una tabella di indirizzi statunitensi.

I dati ripetuti in una colonna non violano nessuna forma normale. Per essere più specifici, una tabella di indirizzi con 3 milioni di righe potrebbe avere 400 indirizzi nel codice postale "90210". Avere 400 indirizzi che condividono lo stesso codice postale non viola alcun modulo normale.

Sostituire un numero ID per un codice postale non cambia il modulo normale e non migliora l'integrità dei dati. Idem per città e stati.

L'utilizzo dei numeri ID come chiavi sostitutive richiede l'unione. L'impostazione di un riferimento a chiave esterna a una tabella di {city, state, zip} non richiede un join. Le query sono esattamente le stesse dopo aver impostato il riferimento a chiave esterna; non hanno bisogno di cambiare affatto.

Ogni paese ha il proprio organo direttivo che stabilisce le regole per l'indirizzamento. Diversi organi di governo, diverse regole. Regole diverse, vincoli diversi. Contstraint diversi, domini diversi. Domini diversi, diverse tabelle .

    
risposta data 31.08.2011 - 12:56
fonte