2011-10-26 4 views
20

Devo implementare una normalizzazione del database di lettura (utilizzando le tabelle di join) o devo utilizzare il tipo ENUM per dati statici o dinamici?Normalizzazione del database MySQL

Ad esempio:

Ho una tabella con un USERuser_status. Devo creare una tabella una tabella status o creare una lista ENUM con gli stati?

Grazie G

risposta

25

IMHO, l'estensione enum rende molto più facile da incorporare semantica in una tabella e migliora anche l'efficienza:

  1. diminuendo il numero di join richiesto per una query
  2. riducendo il numero di tabelle aperte in il DBMS

l'unica nota stonata sono a conoscenza è

  1. la E Tipo di NUM non è implementata da altri DBMS
  2. se si sceglie di aggiungere valori aggiuntivi al set ENUM in un secondo momento, si sta applicando un aggiornamento DDL - che può richiedere molto tempo, con un grande tavolo

HTH

C.

+1

Test di Peformance: http://www.mysqlperformanceblog.com/2008/01/24/enum-fields-vs-varchar-vs-int-joined-table-what-is-faster/ –

+1

Ci sono altri problemi con 'ENUM '. Per prima cosa, tutte le colonne 'ENUM' possono prendere uno speciale valore" sconosciuto "della stringa vuota (oltre a' NULL' se consentito); inoltre, questo valore verrà utilizzato per qualsiasi assegnazione di un valore non valido a meno che non sia in uso una modalità SQL rigorosa. Ciò può comportare un'incoerenza non intenzionale del database; inoltre, se in realtà uno ha un valore di stringa vuota esplicito nella lista 'ENUM', ciò può portare a una tremenda confusione (dato che si deve esaminare il valore numerico per determinare quale" tipo "di stringa vuota è memorizzato). – eggyal

+1

Inoltre, la conversione implicita in valori numerici in contesti numerici può causare considerevole confusione, specialmente se si tenta di utilizzare stringhe che rappresentano numeri come valori ENUM. Il manuale fornisce un buon esempio di una lista 'ENUM'' ('0', '1', '2') ':" * Se memorizzi '2', viene interpretato come un valore di indice e diventa' '1 '(il valore con indice 2) Se memorizzi '' 2'', corrisponde ad un valore di enumerazione, quindi è memorizzato come' '2''. Se memorizzi '' 3'', non corrisponde ad alcun valore di enumerazione, quindi viene trattato come un indice e diventa ''2'' (il valore con indice 3). *" – eggyal

0

Dipende architettura e molti altri fattori.

Ad esempio, non è consentita la lettura/scrittura di dati tranne l'utilizzo di stored procedure. In questo caso puoi usare liberamente il datatype "tinyint". Se si consente la lettura/scrittura con query dirette, dovrebbe essere preferibile utilizzare il vincolo, ad esempio ENUM, per evitare stati impropri (se l'interfaccia utente o il back-end possono mettere questo stato "errato", ovviamente).

D'altra parte (ed è possibile) ci possono essere cambiamenti nel flusso di dati e forse sarà necessario aggiungere nuovi stati. In questo caso è necessario: 1) non eseguire nulla se si dispone di un tipo di dati statico; 2) cambia se hai ENUM.

Quindi ... la mia risposta è: dipende dalla vostra applicazione e dalle vostre esigenze.

+2

È possibile applicare corretti stati di restrizioni di chiave esterna come pure (utilizzando le tabelle InnoDB.) – Inca

+0

... e creare un altro tavolo. Penso che "l'eccessiva normalizzazione" (avere una tabella aggiuntiva per ogni stato) non sia un buon approccio in generale. – ravnur

+0

Puoi spiegare perché no? Non ci sono problemi con l'avere molti tavoli. (E consentono una maggiore flessibilità, come l'aggiunta di descrizioni modificabili a uno stato, o la disabilitazione di uno per i nuovi record mantenendolo per vecchi record.) – Inca

1

Un altra roba da considerarsi ...

un enum potrebbe essere aggiornato solo attraverso una modifica della struttura del database altrove una tabella collegata permette la creazione dinamica di record.