Aprender de las cosas más pequeñas

Estoy trabajando en el etiquetado de entradas para Almanah y por pequeña que pueda parecer implementar esta mejora, he aprendido algo sobre cuestiones que uno da por supuesto durante el desarrollo y he disfrutado con ello.

Lo primero al comenzar esta mejora fue plantear el esquema de la base de datos. Para Almanah empleamos una base de datos SQLite muy sencilla, con una única tabla para guardar las entradas, la cual tiene una clave primaria formada por tres campos: año, mes y día.

Sin muchas vueltas la primera solución que me vino a la cabeza es crear dos nuevas tablas, una para las etiquetas (con dos campos, etiqueta y un entero como clave primaria) y otra para la relación entre entrada y etiqueta (los tres enteros de clave de la entrada y al clave de la etiqueta). Sencillo, ¿no? Siempre he trabajado de esta manera de forma automática. Pues resulta que al compartir con Philip (el creador de Almanah) algunas cuestiones sobre lo que estaba realizando, entre ellas el esquema, me planteó porqué no usar una única tabla, con las claves de la entrada y un campo más de tipo texto para la etiqueta.

Pensé, “eso debe ser muy ineficiente porque buscar por una cadena en lugar de por un entero para buscar las entradas de una etiqueta dada debe costar mucho”, pero ¿porqué? ¿cuáles eran las ventajas reales y los inconvenientes de emplear una u otra forma? Así que nos pusimos a investigar un poco.

Después de las primeras búsquedas en StackOverflow mi propuesta de dos tablas parecía que se llevaba la palma, pero un poco más de indagación y empezamos a ver pruebas de carga con búsquedas en campos de tipo entero y tipo texto y las diferencias eran minúsculas para un volumen de datos medio, al rededor de un millón. Y por último encontré esta respuesta en StackOverflow que me pareció condensaba lo que yo estaba planteando y me hacía cambiar el punto de vista: lo importante no es el tipo, sino el volumen de lo que almacenas y el patrón de acceso. ¿Alguien más no está cansado de oír que una llave principal es mejor y más rápida siendo un entero? Pues desacte de esa idea, porque hay factores que influyen, la respuesta correcta a que tipo de clave primaria usar es: depende. Lo primero es tener claro su uso, su tamaño (de longitud), si se querrá modificar, …

Para confirmar todo esto realicé mis propias pruebas con los dos esquemas empleando unas 3000 entradas y 3 etiquetas por entrada. Pensé que estos datos serían reales y permitirían conocer el comportamiento para una situación posible, es decir, un usuario que emplease Almanah de manera intensiva y tras varios años. Los resultados fueron indiferentes, la velocidad de acceso era inferior a 0.06 segundos.

Por último, me pregunté si SQLite ofrecía algo de material al respecto. Pese a que la web da una sensación de anticuada, cuenta con documentación técnica muy completa y encontré muy interesante el siguiente enlace sobre planificación de queries porque me dí cuenta de como maneja SQLite las entradas, las claves y la importancia de los indices (siempre teniendo en cuanta las queries que se emplearán). También me resultó de mucha utilidad el documento sobre los tipos de datos, sobre todo el punto 3 sobre comparación porque la comparación entre enteros se realiza antes con una llamada a atof (convirtiéndolo en un número de coma flotante). Interesante, ¿verdad

La conclusión de todo esto es que siempre hay que ser crítico y poner en duda todo lo que te llevas entre manos, todas tus ideas dadas por supuestas y analizar hasta el fondo el porqué de las ideas. La recompensa por ello es muy gratificante y siempre sales ganando.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s