Posso decomporre senza perdita questa tabella?


10

Mi sono imbattuto in un problema di progettazione di database che è fuori dalla mia portata e il mio guru DBA non è andato a fuoco.

In sostanza, ho una tabella con la seguente chiave primaria (PK per brevità):

child_id   integer
parent_id  integer
date       datetime

child_ide parent_idsono chiavi esterne delle tabelle entità. La stessa tabella "figlio" contiene anche una chiave esterna per la tabella "padre", e lo, ognuno fa child_idsempre riferimento allo stesso parent_idprevisto dalla tabella sopra. In effetti, risulta che c'è un po 'di codice in più per mantenere i due in sincronia.

Il che rende questo novizio entusiasta della normalizzazione dire "Dovrei rimuovere la ridondanza invece!"

Mi decompongo come segue:

Table_1 PK:
child_id   integer
date       datetime

Table_2 PK:
parent_id  integer
date       datetime

Table_3: (already exists)
child_id   integer PRIMARY KEY
parent_id  integer FOREIGN KEY

Ed ecco, quando mi unisco a questi ragazzi in modo naturale, riprendo il tavolo originale. È la mia comprensione che rende questo 5NF.

Tuttavia, ora mi rendo conto che esiste una regola aziendale nascosta.

Normalmente, le date associate a un dato child_iddevono essere un sottoinsieme delle date associate al corrispondente parent_id. Puoi vedere che la prima tabella applica questa regola.

La mia decomposizione non impone la regola, perché puoi aggiungere liberamente alla Tabella 1 fino a quando le date non diventano troppo grandi.

Il che mi porta qui, con le seguenti domande:

  1. Questa decomposizione è 5NF? Mentre direi che consente anomalie di inserimento, sembra anche seguire l'esempio Wiki, che a sua volta segue questa guida . La frase (sottolineatura mia) "possiamo ricostruire tutti i fatti reali da una forma normalizzata composta da tre tipi di record separati" mi dà una pausa speciale, dal momento che, indipendentemente dalla quantità di immondizia in cui pompare Table_1, l'unione naturale la ignora ancora.

  2. Supponendo che questa decomposizione non mi piaccia (non mi piace). Riconosco liberamente che la soluzione pratica è lasciare la tabella e il codice così come sono. Ma, in teoria, c'è un modo per scomporre e / o aggiungere vincoli in modo tale che mi allontani dal primo tavolo e preservi le mie regole aziendali?


1
Quali sono le chiavi nella tua tabella originale? Quali dipendenze dovrebbe satsify? Sembra che tu stia dicendo che child_id-> parent_id, nel qual caso child_id e parent_id non possono essere entrambi parte della stessa chiave in quella tabella.
nvogel,

1
@trevor: Hai mai recensito le risposte qui? Visto l'ultima volta 19 minuti dopo aver chiesto. Le risposte arrivarono dopo.
gbn

Risposte:


9

La normalizzazione si basa su dipendenze funzionali. Le dipendenze funzionali hanno a che fare con la semantica; hanno a che fare con il significato dei dati . Quando si semplifica un problema del mondo reale al livello di "parent_id, child_id, date" e non si includono dati di esempio, si limita davvero la quantità di aiuto che un progettista di database coscienzioso può fornire.

Il fatto che tu abbia una chiave {child_id, parent_id, date} in una tabella e che tu abbia (sembra) una coppia unica {child_id, parent_id} nella tabella figlio non significa necessariamente che una parte della combinazione sia ridondante . Potrebbe significare che nella tabella che ha {child_id, parent_id, date} come chiave primaria, la coppia di attributi {child_id, parent_id} dovrebbe fare riferimento in primo luogo alla tabella figlio.

In tal caso, potresti usare FOREIGN KEY (child_id, parent_id) REFERENCES child (child_id, parent_id). Per fare ciò, è necessario un vincolo UNIQUE sulla coppia di colonne (child_id, parent_id) nella tabella "child", che non dovrebbe essere un problema se child_id è la sua chiave primaria.

Ma non c'è modo di dirlo senza sapere cosa significano i dati, e tu sei l'unico in questo thread che lo sa. (Ma saremo felici di farti spiegare a noi.)

Per quanto riguarda la tabella originale, sembra che tu stia dicendo che child_id -> parent_id. In tal caso, perché parent_id è nella tabella originale in primo luogo? Perché la chiave non è solo (child_id, date), con un riferimento di chiave esterna alla tabella "child"? Mi sembra che il tipo di ridondanza di cui stai parlando possa essere risolto rilasciando la colonna "parent_id".

DDL SQL e dati di esempio sotto forma di istruzioni INSERT ci aiutano ad aiutarti. Le istruzioni DDL e INSERT sono più precise delle descrizioni.


1
+2 per il promemoria "dipendenza funzionale"
jcolebrand

3

Prova questo...

  • Aggiungi un vincolo univoco a (child_id,parent_id)nella tabella figlio
  • La tabella corrente (PK,FK:child_id, PK,FK:parent_id, PK:date)rimane così com'è, l'FK è su 2 colonne per il nuovo vincolo univoco

o

  • Rimuovere l'FK dalla tabella figlio corrente
  • Crea una nuova tabella (PK,FK:child_id, FK:parent_id)1: 1 con figlio
  • La tabella corrente (PK,FK: child_id, PK,FK: parent_id, PK:date)rimane così com'è. ma l'FK si trova su 2 colonne nella nuova tabella

Se non altro, potrebbe ispirarti ...

Se ho capito bene, rimuoverà ridondanza e codice ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.