Andrés
•
30 June 2024
Hubo un momento en mis aplicaciones en el que dejé de persistir los campos que iba a definir como enum en campos int
y comencé a hacerlo en strings
. Tomé esta decisión porque, en varias ocasiones, me pidieron un volcado de la base de datos para su análisis, y cada vez que se encontraban con un campo status
(o cualquier otro usando enum
) con valores como 0, 1 o 2 me terminaban preguntando sobre su significado. Por lo que, en vez de usar valores numéricos que carecen de sentido y contexto, los cambié directamente por un string
que en sí mismo tiene sentido y da contexto.
Pero hace unos días volví a revisar la documentación y encontré una frase que me hizo cuestionarme esto:
Finally it’s also possible to use a string column to persist the enumerated value. Note that this will likely lead to slower database queries
¡Usarlo terminaría en consultas más lentas a la base de datos!
Así que, como buen programador, preocupado de la eficiencia y el rendimiento de mis aplicaciones 🤓, me cuestioné lo que estaba haciendo y, antes de realizar algún cambio, quise comprobar esto. Creé una aplicación simple en Rails conectada a MySQL con dos modelos, uno con un enum persistido en int
y otro persistido como varchar
con 100,000 registros cada uno. Cerré todas las aplicaciones que podían molestar y ejecuté un benchmark:
user system total real
String Enum Count: 0.477732 0.052428 0.530160 ( 21.794783)
Integer Enum Count: 0.374897 0.030260 0.405157 ( 21.639400)
String Enum Paginated Index: 0.351621 0.017249 0.368870 ( 0.639043)
Integer Enum Paginated Index: 0.317277 0.022936 0.340213 ( 0.524883)
String Enum Single Record Fetch: 0.294010 0.031218 0.325228 ( 0.489015)
Integer Enum Single Record Fetch: 0.297743 0.015502 0.313245 ( 0.497845)
Todos los resultados fueron muy parecidos, las variaciones de tiempo en las 1,000 ejecuciones de consultas simples fueron pequeñas. Si entiendo bien, podríamos tomar el caso de las consultas count
. Tuvieron una diferencia de 0.155383s, o sea, 0.1ms de ventaja para int
por consulta aproximadamente. Pero para un select
con limit(1)
ganó el string
. Entonces me pregunto, ¿realmente un enum
persistido como string
terminará en consultas más lentas?
Bueno, sea más lento o no, creo que en el común de las aplicaciones terminará con diferencias de milisegundos que no serán tan importantes. Por lo que mi razón inicial de comenzar a usar enums
persistidos como strings
se mantiene como lo más importante. Y no soy el único que tiene una razón para hacerlo, estas dos preguntas en Stack Overflow también buscaban algo similar hace varios años ya:
¿Qué opinas tú? ¿Sabías que un enum
puede persistirse como string
?