En la pasada entrada hablamos sobre el paquete data.kanji e hicimos un esbozo general sobre como estaba organizado. En esta entrada, hablaremos de la base de datos usada para almacenar los datos sobre kanjis, la base de datos de objetos Neodatis, lo cual nos servirá de prólogo para entrar de lleno en las motivaciones de diseño que han dado lugar a la organización actual del paquete data.kanji.
Cuando empecé a pensar en como iba a hacer funcionar todo lo que había pensado para JavaDiKt, lo primero que pensé fue en como almacenar los datos de manera rápida, eficiente y sencilla. Lo primero que consideré fue en recuperar los datos sobre la marcha directamente desde un archivo XML, pero pronto me di cuenta de que el acceso secuencial típico de este tipo de archivos significaba problemas a la hora de hacer búsquedas complejas como las que pretendía.
Después medite la posibilidad de usar alguna base de datos ligera tipo SQL, que pudiese incluirse dentro del mismo programa (es decir, que no necesitase un programa externo). Investigando encontré SQLite, y seguidamente un port para Java. Esta era la solución idónea, pero para mi suponía un hándicap importantísimo, pues si lo que se sé de SQL es poco, lo que sé de modelado de datos SQL es aún menos, eso sin contar la batería de adaptadores y parseadores que tendría que desarrollar.
Estaba ya resignado a tener que empollarme un manual de SQL cuando por casualidad encontré bicheando por Internet algo llamado bases de datos de objetos. Éstas se caracterizan por:
- Permiten almacenar y recuperar objetos de cualquier tipo siempre de manera íntegra, es decir, almacenas un objeto con todos sus atributos y lo recuperas en el mismo estado en el que fue almacenado.
- La base de datos viene modelada según los tipos de clases a las que pertenecen los objetos que están almacenados en ella. Esto quiere decir, por ejemplo, que al almacenar un objeto crearas un nuevo tipo tabla con el nombre de su clase como nombre de la tabla y los atributos de dicha clase como dominios, añadiendo nuevos datos a esa tabla cada vez que añades un objeto de la misma clase.
- Los objetos almacenados en otro objeto como campos o en contenedores formarán tablas nuevas en la base de datos, pudiendo realizar entonces consultas sobre estos objetos sin tener que referirse al objeto que los contenía.
- Cada query solo podrá contener expresiones referentes a un tipo de clase. Esto significa que solo podrá extraerse de la base de datos un tipo de objeto a la vez.
- Cada base de datos es fuertemente dependiente del lenguaje para el que está diseñado y depende en gran medida de las propiedades de éste, como herencia, tipos, genéricos,…etc. Por tanto, las querys son construidas usando métodos, estilos y técnicas propias del lenguaje de programación elegido.
Tengo que decir que me impresionó la sencillez y elegancia del invento, que solucionaba todos mis problemas. De una tacada me ahorraba tanto el modelado de datos usando el mismo modelado de clases del programa, como la construcción de adaptadores recuperando los objetos directamente de la base de datos.
Buscando entonces algo parecido para Java me topé con Neodatis, una base de datos de este estilo y de software libre, con una documentación adecuada y un desarrollo lo suficientemente maduro, y decidí tras una serie de pruebas que era viable su uso.
Además de todo lo dicho anteriormente, Neodatis incluye además algunas características interesantes extras como la posibilidad de construir índices de un campo en concreto de una clase para acelerar las búsquedas de objetos, elaboración de queries muy intuitiva, elección de codificación, exportación/importación XML o una api de desarrollo de constructores de queries.
Sin embargo, Neodatis también presenta algunos problemas importantes.Después de las pruebas, he comprobado que:
- La mezcla de herencia y tipos genéricos en una misma clase genera problemas a la hora de recuperar objetos de dicha clase.
- La única consulta posible sobre contenedores que sean campos de una clase es contains. Esto quiere decir que si, por ejemplo, tenemos una lista de números dentro de un objeto de tipo grupo de números, podremos recuperar todos los objetos de tipo grupo de números que contengan al número 5, pero no a todos los que contengan números menores que 5.
Además para tipos como los mapas ni siquiera esto será posible - Todos los métodos de la base de datos usan técnicas de reflexión y consultas en tiempo de ejecución sobre los tipos de datos, lo que significa que no existe seguridad en los tipos en ningún momento.
- Hasta donde he podido probar, no es posible acceder a la base de datos usando distintos hilos. Solo un proceso puede manejarla a la vez.
- Las consultas sobre igualdad de objetos se basan en la igualdad de atributos entre las dos clases y no en el método
equalsde cada clase.
Y con esto terminamos la entrada de hoy. En la próxima, veremos como todos estos factores han sido fundamentales a la hora de definir la estructura del paquete data.kanji.
