2011-07-18 10 views
5

Hay dos formas de almacenar tipos enum en la base de datos: como una cadena o como un entero.¿Vale la pena convertir las enumeraciones de cadena de la base de datos en enteros?

Guardando la enumeración (sex = {male,female}, account_type = {regular,pro,admin}, etc.) como cadenas hace que las cosas sean más legibles pero requiere más espacio que enteros.

Por otro lado, los enteros requieren mapear las enumeraciones dentro y fuera de la base de datos. Como beneficio, la distinción entre mayúsculas y minúsculas se maneja fuera de la base de datos con enteros.

¿Asumiendo que ambos están indexados, la conversión entera generalmente vale la pena? ¿Cuánto más rápido es la búsqueda con números enteros?

Ejemplo

Tal vez un ejemplo concreto podría ayudar a visualizar las cosas. Permite tomar el tipo de cuenta anterior con una base de datos de 100,000 usuarios.

cadena enum

Suponiendo 8 bits de longitud fija tipo CHAR

7*100000*8/8 = 700000 bytes 

Entero enum

Suponiendo 8 bits enteros TINYINT

100000*8/8 = 400000 bytes 

Parece que el tamaño es casi la mitad con enteros enteros. También necesita concider los índices.

Respuesta

3

La respuesta es, como era de esperar, depende.

Cuanto mayor es la base de datos, más significativo es el ahorro de espacio, no solo en el disco sino también en la red IO y el cálculo.

Personalmente, almacenaría enteros en lugar de valores textuales, a menos que haya un suministro directo de DB para enumeraciones (como lo hace MySQL).

1

Los ints tomarán menos memoria si el tamaño de la base de datos se convierte en un problema.

Depende de si devuelve valores de la base de datos directamente sin pasar por la capa de código (por ejemplo, alguna forma de traducción). Si es así, necesitaría los valores de cadena en la base de datos (sin embargo, podría almacenarlos como búsquedas en una tabla relacionada)

0

Siempre existe la cuestión de si el DB será examinado por humanos, en lugar de aplicaciones que hacen la conversión Si una persona está mirando la base de datos por algún motivo, el texto es mejor: este es especialmente el caso si hay administradores de bases de datos que no pueden acceder al código para ver la conversión enum.

Si el tamaño de los datos almacenados es más importante, la conversión a ints es una mejor idea. Pero para este espacio mejorado, pierdes legibilidad. Depende de cuál es el factor más importante.

Por supuesto, puede incluir SProcs o Vistas o similar para ver los datos enteros almacenados y convertirlos a valores de cadena, lo que tendría sentido si necesita un equilibrio entre los dos.

Pero como dijo Oded, no hay una respuesta simple. Cada situación será ligeramente diferente.

0

En realidad, lo que probablemente quiera hacer es crear una tabla de asignación en su base de datos, independientemente.
Esto se ocupa de una serie de cosas:
1) Asigne una columna Id como de costumbre, luego asigne claves externas a las columnas apropiadas. Esto evita que se inserten valores sin sentido. Esto también trata con problemas de normalización.
2) Con la tabla de asignación, puede usar vistas para construir selecciones solo de base de datos, que simplemente intercambian el valor de id para la cadena de texto requerida.
3) Con una tabla de asignación, también es más fácil tratar los problemas de internacionalización (nota: esto no significa necesariamente más simple, exactamente). Aquí es cómo iba a configurar las tablas para esto:

Gender_Mapping 
Id | Enum_Mapped_Value | DBA_Readable_Description 

Gender_Description 
Id | Gender_Mapping_Id | Language_Id | Language_Specific_Description 

Por cuestiones de recuperación, (Enum_Mapped_Value) y (Gender_Mapping_Id, Language_Id) debe ser única (o regresar único desde un punto de vista, por lo menos).
Enum_Mapped_Value debería ser un código de caracteres (¿quizás 5 caracteres?) Que se utiliza para asignar la enumeración a la base de datos. Haga no use el valor ordinal, o el nombre de la enumeración en sí - use un valor interno asignado por el constructor; De lo contrario, los desarrolladores futuros pueden reordenar las enumeraciones o cambiarles el nombre, pero es mucho más probable que los valores internos queden solos.
Language_Id debe mapear como una clave externa a una tabla Language_Mapping de algún tipo, si alguna vez tiene previsto tratar con más de un idioma.