2010-08-04 6 views
9

Tengo una columna en una tabla que almacenará un valor enum. P.ej. Grande, mediano, pequeño o los días de la semana. Esto se corresponderá con el texto que se muestra en una página web o la selección del usuario de una lista desplegable. ¿Cuál es el mejor diseño?buen diseño de la base de datos: valores enum: ints o strings?

Almacene los valores como un int y luego quizás tenga una tabla que tenga las enumeraciones/int cadena correspondiente.

Simplemente almacene los valores en la columna como una cadena, para hacer las consultas un poco más autoexplicativas.

En qué punto/cantidad de valores es mejor utilizar ints o strings.

Gracias.

+0

Una ventaja del uso de cadenas es que son más fáciles de leer si usted o alguien más tiene que trabajar directamente con la base de datos. Le ahorrará la molestia de unirse a las tablas que definen las entradas para que las consultas sean legibles por humanos. He visto implementaciones bastante grandes usando cadenas: el impacto en el rendimiento es insignificante. –

Respuesta

0

Vaya con su primer ejemplo. Digamos que creas una tabla de búsqueda: tamaños. Tiene las siguientes columnas: Id - clave principal + identidad Nombre - varchar/nvarchar

Habría tres filas de la tabla, pequeño, medio y grande, con valores de 1, 2, 3 si se les insertó en ese orden

Si tiene otra tabla que utiliza esos valores, puede usar el valor de identidad como la clave externa ... o podría crear una tercera columna que es un valor de mano corta para los tres valores. Tendría los valores S, M & L. En su lugar, podría usar eso como la clave foránea. Debería crear una restricción única en la columna.

En cuanto al menú desplegable, puede usar cualquiera de los dos como el valor detrás de las escenas.

También puede crear el valor S/M/L como la clave principal también.

Para su otra pregunta sobre cuándo es mejor utilizar los ints frente a las cadenas. Probablemente hay mucho debate sobre el tema. A muchas personas les gusta usar valores de identidad como sus claves principales. Otras personas dicen que es mejor usar una llave natural. Si no está utilizando una identidad como clave principal, entonces es importante asegurarse de tener un buen candidato para la clave principal (asegurándose de que siempre sea única y de que el valor no cambie).

2

Asumiendo que su RDBMS de elección no tiene un tipo ENUM (que se encarga de esto para usted), creo que la mejor manera de utilizar los identificadores en lugar de cadenas directamente cuando los valores se pueden cambiar (ya sea en el valor o en cantidad.)

Podría pensar que los días de la semana no cambiarán, pero ¿qué sucede si su aplicación necesita agregar soporte de internacionalización? (¿o una corporación multinacional malvada decide cambiarles el nombre después de tomar el control del mundo?)

Además, esa categorización Grande, Mediano y Pequeño probablemente esté cambiando después de un tiempo. La mayoría de los valores que crees que no pueden cambiar, pueden cambiar después de un tiempo.

Por lo tanto, principalmente para anticipar los motivos de cambio, creo que es mejor usar identificadores, solo necesita cambiar la tabla de traducción y todo funciona sin problemas. Para i18n, puede simplemente expandir la tabla de traducción y extraer los registros adecuados de forma automática.

Lo más probable (esto dependerá de varios factores) es que las inyecciones funcionen mejor, al menos en la cantidad de almacenamiento requerido. Pero no lo haría por motivos de rendimiento, lo haría por motivos de flexibilidad.

+0

No se ha encontrado antes, ¿qué RDBMS tiene soporte ENUM? Algo que me he perdido para –

+0

definido. MySQL lo tiene: http://dev.mysql.com/doc/refman/5.0/en/enum.html –

+0

Fantástico, recién estoy empezando a echar un vistazo a mySQL así que ' Lo mantendré atento. –

1

esta es una pregunta interesante.Definitivamente debe tener en cuenta los objetivos de rendimiento aquí. Si quieres ir por la velocidad, int es imprescindible. Una base de datos puede indexar enteros un poco mejor que Strings, aunque debo decir que no es una mala pérdida de rendimiento.

Por ejemplo, es la base de datos Oracle en sí misma, donde tienen el lujo de hacer enum de gran tamaño como cadenas en sus tablas del sistema. Cosas como USER_ALLOCATION_TYPE o cosas por el estilo son la norma. Es como usted dice, las cadenas pueden ser más "extensibles" y más legibles, pero en cualquier caso en el código terminará con:

Cadena final estática USER_ALLOCATION_TYPE = "USER_ALLOCATION_TYPE";

en lugar de

estático int USER_ALLOCATION_TYPE final = 5;

¡Ya sea que hagas esto terminarás con todos estos literales de cadena que solo duelen para que alguien vaya y extravíe un char! :)

En mi compañía usamos tablas con enteros claves primarias; todas las tablas tienen una clave primaria serial, porque incluso si no crees que la necesites, tarde o temprano te arrepentirás.

En el caso que está describiendo lo que hacemos es que tenemos una tabla con (PK Int, Cadena de descripción) y luego hacemos Vistas sobre las tablas maestras con combinaciones para obtener las descripciones, de esa manera podemos ver el unimos las descripciones de los campos si debemos y mantenemos el rendimiento.

Además, con una tabla de descripción separada puede tener información EXTRA sobre esos identificadores en los que nunca pensaría. Por ejemplo, digamos que un usuario puede tener acceso a algunos campos en el cuadro combinado si y solo si tienen dicha propiedad y así sucesivamente. Puede usar campos adicionales en la tabla de descripción para almacenar eso en lugar de un código ad-hoc.

Mis dos centavos.

0

Yo también estaría interesado en las ideas de las personas con respecto a esto, siempre he seguido la ruta de almacenamiento de la enumeración en una tabla de búsqueda y luego en cualquier tabla de datos que hiciera referencia a la enumeración, almacenaría la ID y usaría la relación FK . De cierta manera, todavía me gusta este enfoque, pero hay algo simple y llano acerca de poner el valor de la cadena directamente en la tabla.

Yendo puramente por tamaño, un int es 4 bytes, donde como la cadena es n btyes (donde n es el número de caracteres). El valor más corto en su búsqueda es de 5 caracteres, el más largo es de 6, por lo que el almacenamiento del valor real consumiría más espacio con el tiempo (si fuera un problema).

Según el rendimiento, no estoy seguro de si un índice en un int o en un varchar devolvería cualquier diferencia en la velocidad/optimización/tamaño del índice?

+0

Simple, simple y doloroso: hacer actualizaciones si los valores cambian y sus datos crecen en una cantidad respetable será una dolor. Mantener la consistencia entre esos cambios también podría convertirse en un dolor. Extender la enumeración para agregar un nuevo valor (si lo está aplicando) podría convertirse en un dolor.Y probablemente haya cosas más dolorosas en las que ni siquiera estoy pensando. –

Cuestiones relacionadas