2011-11-26 19 views
6

Ho bisogno della soluzione più pulita ed efficiente per il mio caso. Sto cercando di memorizzare Marks of student in un DB MySQL. Uno studente può essere "ASSENTE" o "CASO DI COPIA", voglio memorizzare tali informazioni anche in DB.Memorizzazione di enum nel database MySQL

Ho pensato di assegnare i codici per il caso precedente come -1 per ABSENT, -2 per COPY CASE, ecc. Questi codici saranno memorizzati solo nella colonna Marks.

Più mai, mentre la loro lettura con una query di selezione, dovrei avere i loro valori di visualizzazione cioè ABSENT, COPY CASE, ecc solo.

Tutti questi possono essere raggiunti solo alla fine DB?

Oppure devo implementare queste cose solo a livello di applicazione?

Esistono API disponibili per Java per tale funzionalità?

risposta

4

come circa la memorizzazione suo name() (versione String) per DB e la creazione di nuovo durante la lettura da DB usando valueOf()

1

Se le rappresentazioni di stringa enum sono abbastanza stringa pesanti, e il database è di grandi dimensioni (controlli nei confronti di queste enumerazioni sono frequente), probabilmente mapperei ogni enum a una costante intera (no, non lo ordinal(), ma il proprio valore intero personalizzato) e ho metodi sull'enumerazione per ottenere e creare un enum da questi valori. In questo modo, sarai in grado di memorizzare le enumerazioni in modo abbastanza efficiente.

public enum Status { 

    ABSENT(1), COPY_PASTE(2); 

    int value; 

    private Status(int value) { 
     this.value = value; 
    } 

    public int getValue() { 
     return this.value; 
    } 

    public static Status ofStatusCode(int value) { 
     // retrieve status from status code 
    } 

} 
+0

Solo una nota che, anche se sono d'accordo con Sanjay che l'utilizzo di [i tipi numerici] (http://dev.mysql.com/doc/ refman/5.0/it/integer-types.html) la rappresentazione per l'enum è generalmente più efficiente dell'uso di [tipi di stringhe] (http://dev.mysql.com/doc/refman/5.0/en/char.html) (prestazioni e spazio), il tipo Enum è un'eccezione, utilizzerà internamente un bit 16 bit (corto) per memorizzare i valori in modo efficiente e non ho mai avuto problemi di prestazioni. –

0

MySQL dispone di un proprio ENUM type. E come sottolineato da @Jigar, puoi usare Enum.getName per ottenere una stringa Java che rappresenta l'enum per la persistenza, recuperare il campo dal database come una stringa e usare Enum.valueOf per caricare la costante enum.

È inoltre possibile utilizzare Enum.ordinal() + 1 per ottenere un numero intero per la persistenza (MySQL anche supporta l'utilizzo di indici interi direttamente con il tipo ENUM) ed emettere una query come:

SELECT enum_col-1 FROM tbl_name; 

per recuperare l'ordinale posteriore (si recupera - 1 per le righe con valori enum non validi).

Plus MyEnumType value = MyEnumType.values()[ordinal] per riconvertirlo in tipo enum Java.

In ogni caso, penso che la soluzione basata su String sia più pulita e più elegante, oltre che più sicura a lungo termine (se è necessario modificare l'ordine di Enum java o aggiungere nuovi valori enum al centro dell'attuale quelli, ti ringrazierai per aver iniziato con la strategia basata su String per cominciare).

6

MySQL supporta enumerazioni:

CREATE TABLE students (name varchar(64), mark ENUM('ABSENT','COPY CASE')); 
INSERT INTO students VALUES ('john', 'COPY CASE'); 

in Java, è possibile trattare questa colonna come una colonna di tipo stringa, ma nel database, i valori sono memorizzati in modo efficiente, e cercando di memorizzare un valore non contenuto nella enum provocherà un errore.

+1

Il secondo requisito può essere soddisfatto dall'integrità referenziale. –

1

Ho pensato di memorizzare i codici per il caso precedente come -1 per ABSENT, -2 per COPY CASE, ecc. Questi codici saranno memorizzati solo nella colonna Marks.

Preferirei preferisco avere una colonna separata, dicono status che detiene valori quali ABSENT, COPY CASE e un valore predefinito, come APPEARED

E la colonna marchi sarebbe rimasto separato.

Nello strato di vista, si potrebbe fare qualcosa di simile

 
if(status is 'APPEARED') 
show marks field 
else 
show status field 
+1

Questo è sicuramente meglio che memorizzare entrambi i marchi e lo stato degli esami nella stessa colonna. E non avrai (nemmeno accidentalmente) risultati errati nelle query che trovano ad esempio 'AVG (mark)' –

Problemi correlati