Come prevenire i record orfani nelle tabelle di dettaglio del database normalizzato?

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

  •  19-08-2019
  •  | 
  •  

Domanda

Devo mantenere un vecchio database che non è correttamente normalizzato. Ad esempio, esiste una tabella di progetto che è cresciuta (o forse a fungo) per avere 5 o più colonne di date diverse, per le diverse pietre miliari del progetto dall'ordinamento alla data di consegna. Ci sono anche diverse tabelle ognuna con colonne per indirizzi, indirizzi di posta elettronica o collegamenti web.

Vorrei normalizzare la struttura, creare tabelle per indirizzi, date programmate e simili, e le tabelle necessarie per consentire relazioni 1: N (indirizzo per cliente, data di scadenza per progetto e così via).

Al momento non sono del tutto sicuro di come gestire le modifiche ai dati nelle tabelle dei dettagli. Considerare ad esempio la modifica di un indirizzo di consegna del cliente. La modifica dei dati nella tabella degli indirizzi è fuori discussione, poiché più di un record (possibilmente in più di una tabella) potrebbe fare riferimento a quel record. L'aggiunta di un nuovo record di indirizzo potrebbe lasciare orfano il vecchio record se nessun'altra riga ha una relazione con una chiave esterna.

Ho pensato ai seguenti modi per gestirlo:

  • Aggiungi un nuovo record di dettagli e controlla in un trigger di aggiornamento della tabella principale se il vecchio record di dettagli deve essere eliminato. Ciò richiederebbe la conoscenza di tutte le tabelle che hanno relazioni con la tabella dei dettagli, in tutte o in uno sproc. Non mi piace questa perdita di separazione. Comprenderebbe inoltre più tabelle nella transazione attiva.

  • Consenti al trigger di eliminare il vecchio record di dettagli e rilevare eventuali errori. Questo sembra sbagliato.

  • Vivi con il record orfano e fai in modo che un'attività di manutenzione periodica ripulisca tutte le tabelle dei dettagli.

Qual è il modo preferito di gestire le modifiche ai dati nelle tabelle dei dettagli collegate a più tabelle principali? Qualche consiglio per leggere su questo?

È stato utile?

Soluzione

Parte del problema potrebbe essere il progetto originale dello schema: le chiavi esterne indicano la direzione sbagliata, trattando indirizzi, numeri di telefono, ecc. come master anziché come dettaglio. Questo può essere utile quando vuoi aggiornare tutti gli usi di un determinato indirizzo in una volta, ma nella mia esperienza si trasforma sempre in troppi casi eccezionali difficili, ad esempio una persona in una posizione si sposta, quindi devi interrompere il loro collegamento contro un intero spostamento della casa o dell'ufficio in modo da aggiornare il record esistente. Se provi a nascondere questo dettaglio all'utente nella schermata CRUD, finirai con una situazione in cui semplicemente non fa quello che vuoi.

Se è fatto in questo modo solo per comprimere valori duplicati, si tratta effettivamente di una denormalizzazione del database: la semplice esistenza della riga dell'indirizzo non ha senso. L'unica differenza è che, a differenza della maggior parte delle denormalizzazioni, tenta di ottenere efficienza spaziale anziché velocità. La creazione di una tabella di collegamenti a quel punto sta semplicemente aggravando il problema.

Se vuoi, ad esempio, più indirizzi per contatto, trasforma gli indirizzi in una tabella di dettagli con una chiave esterna che punta di nuovo al contatto principale e non preoccuparti di valori di indirizzo duplicati perché sono solo valori . Altrimenti, trasforma Address in un'entità reale: aggiungi un campo di titolo o descrizione e una schermata CRUD in modo che possa stare da solo come entità.

Altri suggerimenti

Vivi con il record orfano e fai in modo che un'attività di manutenzione periodica ripulisca tutte le tabelle dei dettagli.

Penso che tu stia sfocando i casi di eliminazione e aggiornamento.

Se si dispone del client a e del client b, ed entrambi utilizzano lo stesso indirizzo, che verrebbe riflesso dai record in una tabella relazionale (ad esempio ClientAddresses, sebbene se si memorizzano indirizzi per più entità, sono sicuro che sarà più complesso di così)

Penso che se due client condividono e indirizzano e non è corretto per il client a, ciò sarebbe errato anche per il client b (ovvero errore di immissione dei dati), ma se si è sicuri di non voler modificare il client il fatto per le informazioni di indirizzo di base, rimuovere il record di associazione (eliminare da ClientAddresses) e aggiungere un nuovo indirizzo. Quando si esegue l'eliminazione dalla tabella relazionale (presumibilmente da una procedura memorizzata), verificare se vi sono altri record che si riferiscono al record dell'indirizzo che non è associato, se non eliminare dalla tabella di base.

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