2011-11-26 20 views
6

Necesito la solución más limpia y eficiente para mi caso. Estoy tratando de almacenar Marks of student en una base de datos MySQL. Un estudiante puede ser "AUSENTE" o "CASO DE COPIA", quiero almacenar dicha información también en DB.Almacenamiento de entradas en la base de datos MySQL

Pensé en asignar códigos para el caso anterior como -1 para ABSENT, -2 para COPY CASE, etc. Estos códigos se almacenarán solo en la columna de Marks.

Más que nunca, mientras los leía con una consulta de selección, debería obtener sus valores de visualización, es decir, ABSENT, COPY CASE, etc.

¿Se puede lograr todo esto en el extremo DB solamente?

¿O necesito implementar estas cosas solo en el nivel de aplicación?

¿Hay alguna API disponible para Java para dicha funcionalidad?

Respuesta

4

¿qué hay de almacenar su (versión String) name() a DB y la creación de nuevo mientras que la lectura de DB usando valueOf()

1

Si las representaciones de cadena de enumeración son bastante cadena pesada, y la base de datos es grande (cheques contra estas enumeraciones son frecuente), probablemente asignaría cada enumeración a una constante entera (no, no a ordinal(), sino a su propio valor entero personalizado) y tendré métodos en la enumeración para obtener y crear una enumeración a partir de estos valores. De esta forma, podrás almacenar las enumeraciones de manera bastante eficiente.

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

Sólo una nota que, aunque estoy de acuerdo con que el uso de Sanjay [tipos numéricos] (http://dev.mysql.com/doc/ refman/5.0/es/integer-types.html) la representación de la enumeración es generalmente más eficiente que usar [tipos de cadena] (http://dev.mysql.com/doc/refman/5.0/en/char.html) (rendimiento y espacio), el tipo Enum es una excepción, usará un bit de 16 bit sin signo (corto) internamente para almacenar valores de manera eficiente, y nunca tuve problemas de rendimiento en absoluto. –

0

MySQL tiene su propio ENUM type. Y como @Jigar señalado, puede usar Enum.getName para obtener una cadena de Java que represente la enumeración de persistencia, recuperar el campo de la base de datos como una cadena y usar Enum.valueOf para volver a cargar la constante enum.

También puede utilizar Enum.ordinal() + 1 para obtener un número entero de persistencia (MySQL también admite el uso de índices enteros directamente con el tipo ENUM) y emitir una consulta como:

SELECT enum_col-1 FROM tbl_name; 

para recuperar el ordinal de la espalda (que recuperará - 1 para filas con valores enum no válidos).

Plus MyEnumType value = MyEnumType.values()[ordinal] para convertirlo a Java enum type.

De todos modos, creo que la solución basada en String es más limpia y más elegante, más segura a largo plazo (si alguna vez necesita cambiar el orden de Enum en java o agregar nuevos valores de enum en el medio del unos, te agradecerás por ir con la estrategia basada en String para empezar).

6

MySQL soporta las enumeraciones:

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

en Java, se puede tratar esta columna como una columna de tipo de cadena, pero en la base de datos, los valores se almacenan de manera eficiente, y tratando de almacenar un valor que no figura en la enumeración dará como resultado un error.

+1

El segundo requisito puede satisfacerse mediante integridad referencial. –

1

Pensé en almacenar códigos para el caso anterior como -1 para ABSENT, -2 para COPY CASE, etc. Estos códigos se almacenarán en la columna Marks solamente.

prefiero prefiero tener una columna separada, dicen status que mantiene valores como ABSENT, COPY CASE y un valor por defecto como APPEARED

y la columna de marcas se quedaría separada.

En la capa vista, se podría hacer algo como

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

Esto es definitivamente mejor que el almacenamiento de ambas marcas y el estado del examen en la misma columna. Y no tendrá (incluso accidentalmente) ningún resultado incorrecto en las consultas que encuentran, por ejemplo, 'AVG (marca)' –

Cuestiones relacionadas