È un buon modo per modellare le informazioni sull'indirizzo in un database relazionale?

StackOverflow https://stackoverflow.com/questions/307027

  •  08-07-2019
  •  | 
  •  

Domanda

Mi chiedo se questo è un buon design. Ho un numero di tabelle che richiedono informazioni sull'indirizzo (ad es. Via, codice postale / CAP, paese, fax, e-mail). A volte lo stesso indirizzo verrà ripetuto più volte. Ad esempio, un indirizzo può essere memorizzato contro un fornitore e quindi su ciascun ordine di acquisto inviato a loro. Il fornitore può quindi cambiare il proprio indirizzo e tutti gli ordini di acquisto successivi devono avere il nuovo indirizzo. È più complicato di così, ma questo è un requisito di esempio.

Opzione 1 Inserisci tutte le colonne degli indirizzi come attributi nelle varie tabelle. Copia i dettagli dal fornitore all'OP al momento della creazione. Memorizza potenzialmente più copie di

Opzione 2 Creare una tabella di indirizzi separata. Avere una chiave esterna dal fornitore e le tabelle degli ordini di acquisto nella tabella degli indirizzi. Consenti solo l'inserimento e l'eliminazione nella tabella degli indirizzi poiché gli aggiornamenti potrebbero cambiare più del previsto. Quindi avrei alcune attività pianificate che eliminano qualsiasi riga dalla tabella degli indirizzi a cui non fa più riferimento nulla, quindi non sono state lasciate righe. Forse hanno anche un vincolo univoco su tutte le colonne non pk nella tabella degli indirizzi per bloccare anche i duplicati.

Sono incline all'opzione 2. Esiste un modo migliore?

MODIFICA: devo conservare l'indirizzo sull'ordine di acquisto come era quando è stato inviato. Inoltre, è un po 'più complicato che ho suggerito in quanto potrebbe esserci un indirizzo di consegna e un indirizzo di fatturazione (ci sono anche un sacco di altre tabelle che contengono informazioni sull'indirizzo).

Dopo un po ', eliminerò i vecchi ordini di acquisto in blocco in base alla loro data. È dopo questo che volevo che la spazzatura raccogliesse tutti i record di indirizzi a cui non fa più riferimento nulla (altrimenti mi sembra di creare una perdita).

È stato utile?

Soluzione

Lo uso davvero come una delle mie domande per l'intervista. Di seguito è un buon punto di partenza:

Addresses
---------
AddressId (PK)
Street1
... (etc)

e

AddressTypes
------------
AddressTypeId
AddressTypeName

e

UserAddresses (substitute "Company", "Account", whatever for Users)
-------------
UserId
AddressTypeId
AddressId

In questo modo, i tuoi indirizzi sono totalmente inconsapevoli di come vengono utilizzati e anche le tue entità (Utenti, Account) non conoscono direttamente nulla degli indirizzi. Dipende tutto dalle tabelle di collegamento che crei (UserAddresses in questo caso, ma puoi fare tutto ciò che si adatta al tuo modello).

Un consiglio alquanto contraddittorio per un database potenzialmente grande: vai avanti e metti un "primario" indirizzo direttamente sulle tue entità (nella tabella Utenti in questo caso) insieme a un "HasMoreAddresses" campo. Sembra complicato rispetto al semplice utilizzo del design pulito sopra, ma può semplificare la codifica per i casi d'uso tipici e la denormalizzazione può fare una grande differenza per le prestazioni.

Altri suggerimenti

Opzione 2, senza dubbio.

Alcune cose importanti da tenere a mente: è un aspetto importante del design indicare agli utenti quando gli indirizzi sono collegati tra loro. Cioè l'indirizzo dell'azienda è uguale all'indirizzo di spedizione; se vogliono cambiare l'indirizzo di spedizione, vogliono cambiare anche l'indirizzo aziendale o vogliono specificare un nuovo bacino di carico? Questo tipo di cose e la capacità di presentare agli utenti queste informazioni e di cambiare le cose con questo tipo di granularità è MOLTO importante. Anche questo è importante per gli aggiornamenti; dare all'utente la granularità di "dividere" inserimenti. Non che questo tipo di interfaccia utente sia facile da progettare; in realtà, è una cagna. Ma è davvero importante da fare; qualcosa di meno farà quasi sicuramente frustrare e infastidire i tuoi utenti.

Inoltre; Consiglio vivamente di conservare i vecchi dati dell'indirizzo; non eseguire un processo per ripulirlo. A meno che non si disponga di un database MOLTO occupato, il software del database sarà in grado di gestire i dati in eccesso. Veramente. Un errore comune che vedo sui database è il tentativo di ottimizzare le informazioni; vuoi ottimizzare le tue query, ma NON vuoi ottimizzare i tuoi dati non utilizzati. (Ancora una volta, se l'attività del database è MOLTO ALTA, potrebbe essere necessario avere qualcosa che lo fa, ma è quasi una certezza che il database funzionerà bene con ancora dati in eccesso nelle tabelle.) Nella maggior parte dei casi, è in realtà più vantaggioso semplicemente per far crescere il tuo database piuttosto che tentare di ottimizzarlo. (La cancellazione di dati sporadici dalle tue tabelle non causerà una riduzione significativa delle dimensioni del tuo database e, quando lo fa ... beh, la reindicizzazione che le cause possono essere un gigantesco drenaggio nel database.)

Penso di essere d'accordo con JohnFx ..

Un'altra cosa sugli indirizzi di posta (lumaca), dal momento che vuoi includere il paese presumo che tu voglia spedire / spedire a livello internazionale, ti preghiamo di mantenere il campo dell'indirizzo per lo più testo libero. È davvero fastidioso dover inventare un codice postale di 5 cifre quando la Norvegia non ha codici postali, abbiamo numeri postali di 4 cifre.

I migliori campi sarebbero:

  • Nome / Azienda
  • Indirizzo (area di testo multilinea)
  • Paese

Questo dovrebbe essere piuttosto globale, se il sistema postale degli Stati Uniti richiede codici postali in un formato specifico, quindi includi anche quello ma rendilo facoltativo a meno che gli Stati Uniti non siano selezionati come paese. Tutti sanno come formattare l'indirizzo nel proprio paese, quindi finché si mantengono le interruzioni di riga dovrebbe essere a posto ...

Vuoi tenere un registro storico di quale indirizzo era originariamente nell'ordine di acquisto?

In caso affermativo, andare con l'opzione 1, altrimenti memorizzarlo nella tabella dei fornitori e collegare ciascun ordine di acquisto al fornitore.

A proposito: un segno sicuro di una cattiva progettazione del DB è la necessità di un lavoro automatizzato per mantenere i dati "ripuliti". o in sincronia. L'opzione 2 è probabilmente una cattiva idea da parte di tale misura

Perché una delle righe della tabella degli indirizzi non viene utilizzata? Sicuramente verrebbero comunque indicati dall'ordine di acquisto che li ha utilizzati?

Mi sembra che fermare i duplicati dovrebbe essere la priorità, annullando così la necessità di una pulizia.

Nel caso di ordini, non si vorrebbe mai aggiornare l'indirizzo poiché l'indirizzo della persona (o dell'azienda) è cambiato se l'ordine è stato inviato. Hai registrato il record di dove è stato effettivamente inviato l'ordine se c'è un problema con l'ordine.

La tabella degli indirizzi è una buona idea. Crea un vincolo univoco su di esso in modo che la stessa entità non possa avere indirizzi duplicati. Potresti comunque ottenerli poiché gli utenti potrebbero aggiungerne un altro invece di cercarli e se ortografano le cose in modo leggermente diverso (St. invece di Street) il vincolo unico non lo impedirà. Copia i dati al momento della creazione dell'ordine nell'ordine. Questo è un caso in cui desideri i record multipli perché hai bisogno di un record storico di ciò che hai inviato dove. Consentire solo inserimenti ed eliminazioni alla tabella non ha senso per me in quanto non sono più sicuri degli aggiornamenti e comportano più lavoro per il database. Un aggiornamento viene eseguito in una chiamata al database. Se un indirizzo cambia nella tua idea, devi prima eliminare il vecchio indirizzo e quindi inserire quello nuovo. Non solo più chiamate al database, ma doppia possibilità di commettere un errore di codice.

Ho visto tutti i sistemi che utilizzano l'opzione 1 entrare nei guai della qualità dei dati. Dopo 5 anni il 30% di tutti gli indirizzi non sarà più attuale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top