2011-12-30 13 views
5

Quando si memorizza la religione di un utente in una "Tabella utente", in modo che se si guarda in basso una colonna si vedrebbe "Cristiano" molte volte, "musulmano" molte volte, ecc. Considera un errore di una forma normale? Quale forma?Si considera un errore di modulo normale?

Il mio modo di vedere:

  • 1nF: Non ci sono colonne che si ripetono.

  • 2nf: Non esiste una chiave primaria concatenata, pertanto non è applicabile.

  • 3nf: Non esiste alcuna dipendenza da un attributo non chiave.

Memorizzazione religione utente in questo modo non sembra fallire qualsiasi forma normale, tuttavia sembra molto inefficiente. Commenti?

risposta

6

Il design supporta tutte le forme normali. Va bene che il tuo attributo ha un valore stringa. La dimensione del tipo di dati è irrilevante per la normalizzazione.

L'obiettivo della normalizzazione non è l'efficienza dello storage fisico: l'obiettivo è prevenire le anomalie. E per supportare l'efficienza logica , memorizzare un dato dato solo una volta. In questo caso, il fatto che l'utente su una determinata riga sia cristiano.

+0

Vorrei aver pensato di dirlo così. – Taymon

+0

Come vengono effettivamente impedite le anomalie di modifica dei dati senza alcun vincolo (CHECK o FOREIGN KEY) in questo modello? (Ignorare qualsiasi applicazione di codice client tramite un ORM o simile) – gbn

+0

Questo è un grande punto che si presenta. Potrebbe essere inserito un controllo, ma non ci sarebbe alcuna fonte di modifica dei dati. Potresti fare la stessa domanda riguardo a qualsiasi valore di dati atomici. Non credo sia sempre necessario prevenire le anomalie di modifica dei dati. Sentiti libero di non essere d'accordo. – user

4

Il principale svantaggio di memorizzare la colonna in questo modo è nello spazio di archiviazione in quanto il numero di righe si riduce.

Piuttosto che una colonna di caratteri, è possibile utilizzare un ENUM() se si dispone di un insieme fisso di scelte che raramente, se non mai, il cambiamento, e ancora evitare di creare una tabella aggiuntiva di opzioni religione a cui questo ha una chiave esterna . Tuttavia, se le scelte saranno fluide, le regole di normalizzazione preferirebbero che le scelte fossero collocate nella propria tabella con una chiave esterna nella tabella utente.

Ci sono altri vantaggi oltre allo spazio di archiviazione per tenerli in un'altra tabella. La loro modifica è un gioco da ragazzi. Per cambiare Christian a Christianity, si può fare un singolo cambiamento nella tabella religioni, piuttosto che fare il potenzialmente costoso (se hai un sacco di righe e di religione non è indicizzato)

UPDATE users SET religion='Christianity' WHERE religion='Christian' 

... si può fare la molto più semplice e meno costoso

UPDATE religions SET name='Christianity' WHERE id=123 

Naturalmente, è anche far rispettare l'integrità dei dati digitando su una tabella religioni. Diventa impossibile inserire un valore non valido come lo Christain errato.

+1

Grande intuizione, ma la domanda è valida. Dici "modo denormalizzato". Quale errore di forma normale si applica qui? 1nf, 2nf o 3nf? – user

+1

@ user1122200 Penso che non sia strettamente una violazione di nessuno dei primi 3 NF, ma si ridurrà in modo inefficiente. –

+0

Questo è quello che sto chiedendo. Non sembra affatto un errore di forma normale. Non mi preoccupo del ridimensionamento, solo della forma normale. Sembra brutto e inefficiente immagazzinarlo in quel modo, ma sarebbe correttamente normalizzato. – user

1

Suppongo che ci sia un elenco di religioni valide; se hai appena inserito l'utente nella propria stringa, devi archiviarlo nella tabella utente e questo è tutto.

Assumiamo che le religioni siano memorizzate nella propria tabella. Se stai seguendo pratiche consolidate, questa tabella avrà una chiave primaria che è un numero intero e tutti i riferimenti alle voci nella tabella in altre tabelle (come la tabella utente) saranno chiavi esterne. Il metodo stringa di memorizzazione della religione non viola alcuna forma normale (dal momento che il nome di una religione è una chiave candidata per la tabella delle religioni), ma viola la pratica di non utilizzare le stringhe come chiavi.

(Questa è una differenza interessante tra la teoria e la pratica dell'algebra relazionale In teoria, una stringa non è diversa da un numero intero, sono entrambi valori matematici atomici.In pratica, le stringhe hanno un sacco di spese generali che portano programmatori di non usarli come chiavi.)

Ovviamente esistono altri modi (come ENUM per alcuni RDBMS) di memorizzare un elenco di valori possibili, ognuno con i propri vantaggi e svantaggi.

+0

"ma viola la pratica di non usare stringhe come chiavi" La stringa non sarebbe la chiave. Se questi fossero spostati in una tabella separata, creerei un ReligionID che è numerico – user

+0

Il punto principale qui è l'efficienza. Aggiungere una tabella aggiuntiva significherebbe un join aggiuntivo, che va bene, ma non quando questa strategia viene utilizzata per più attributi. Ciò potrebbe portare a più join solo per visualizzare le informazioni su un utente. Troppi join. E se questo metodo non viola una forma normale, non vedo alcun motivo per aggiungere una tabella aggiuntiva. – user

0

Le tue forme normali sono un po 'fastidiose. La seconda forma normale è che il resto della riga dipende da "l'intera chiave". La terza forma normale è che il resto della riga dipende da "nient'altro che la chiave". (Quindi aiutami Codd).

No, la situazione descritta non viola nessuna delle prime tre forme normali. (Potrebbe violare il sesto, a seconda di altri fattori).

+0

Le forme normali come indicato vanno bene. La tua versione ripropone la stessa cosa. "L'intera chiave" si riferisce a entrambe le parti di una chiave primaria concatenata. "Nient'altro che la chiave" si riferisce ad un attributo nonkey che dipende da un altro attributo nonkey. – user

+0

Ah, scusate, pensavo volesse dire che la seconda forma normale ha messo fuori legge le chiavi primarie composte. Colpa mia. Non ho sentito la "chiave primaria concatenata" come una frase, quindi ho solo intuito il suo significato. –

0

Ci sono alcuni svantaggi con questo approccio (rispetto all'utilizzo di una chiave esterna) che è necessario assicurarsi che stai bene. 1 - spreca spazio di archiviazione. 2 - più lento per la query per religione 3 - qualcuno potrebbe inserire dati che non corrispondono, ad esempio inserire manualmente "Jedi" o qualcosa che potresti non considerare corretto 4 - non c'è modo di avere un elenco di possibili religioni (es., se non ci sono nessuno di una certa religione nella tua tabella, ad esempio, Zoroastrian) ma vuoi comunque che sia una valida possibilità 5 - la maiuscola non corretta potrebbe causare problemi 6 - lo spazio attorno alla stringa potrebbe causare problemi

Il professionista principale con questa tecnica è che i dati sono più veloci da estrarre (non si unisce a un tavolo) ed è anche più veloce da leggere per un essere umano.

+0

Stavo pensando di usare un enum mySQL come suggerito qui, o un vincolo CHECK in SQL. Ciò eliminerebbe gli errori di dati (capitalizzazione, ortografia, ecc.). Come pensi che questo metodo rifiuti lo spazio di archiviazione e sia più lento? – user

Problemi correlati