lunes, 8 de septiembre de 2014

La importancia de "perder" el tiempo en realizar un correcto analisis de base de datos

Hello world,

Hace tiempo que no escribo en este blog, que en su día pensé utilizar para explicar mis experiencias en el mundillo del desarrollo de aplicaciones y también como sitio donde compartir conocimiento con otros developers del mundo .NET y principalmente WEB.

El primer post de la nueva etapa va orientado a la importancia que tiene en un proyecto el realizar un buen análisis de la estructura de nuestra base de datos, tablas, naming de campos, claves, índices, etc…

La base de datos, hablando en términos de construcción, son los cimientos de la casa, si no tenemos unos buenos cimientos la casa se puede venir abajo, y tampoco vamos a empezar a construir el tejado sin haber hecho previamente los cimientos. Lo más sencillo para todo developer cuando tiene que crear una base de datos es ponerse a "picar" los create table sin haber realizado un profundo análisis de necesidades, lo cual provoca que en un corto plazo de tiempo tengas que cambiar la base de datos, desencadenando una serie de daños colaterales como pueden ser tener que cambiar las consultas, el modelo de datos de tu arquitectura, etc. Está claro, que la base de datos es una de las partes más vivas en la primera parte de desarrollo un proyecto, y que con el tiempo ésta va cambiando porque surgen nuevas necesidades, o cosas que en primer momento pensaste hacer de una cierta manera y cuando te pones a implementarlas te das cuenta que estabas equivocado.

Otro de los puntos clave en el análisis es ver las tablas que realmente necesitamos para nuestra aplicación. Tendemos a querer meter tablas para todo, muchas veces con un simple Id-Descripción que después consumimos desde una sola tabla, pero que cuando queremos obtener los datos tenemos que hace costosas joins en nuestras consultas. Este punto daría para hablar largo y tendido, ya que si somos "políticamente correctos" meteríamos tablas relacionales para todo, pero que después funcionalmente lo único que provocarían sería un desarrollo de la aplicación más lento y costoso. Así que como en todo, los extremos no son buenos, es decir, ni una tabla con 1000 campos donde está  toda la información, ni 1000 tablas con un solo campo.

El punto más dispar que me he encontrado en mi carrera profesional, es el naming de las tablas y de los campos de la base de datos. He encontrado de todo, pero principalmente 2 modelos:
  1. El equipo de desarrollo decide una nomenclatura para los campos.
  2. Se  ponen los nombres de lo que hace referencia cada cosa, siempre siguiendo unos patrones predefinidos.
El punto 1 está muy bien siempre y cuando la rotación en el equipo sea nula(algo muy difícil por no decir imposible), ya que todo el mundo estará familiarizado con dicha nomenclatura, pero desde mi punto de vista puede tener varios inconvenientes: uno seria la rotación de miembros, ya que a la que se incorporaran nuevos componentes, estos tendrían un tiempo de adaptación a esta nomenclatura. Esto podría solucionarse documentando todos y cada uno de los campos y tablas de la base de datos, pero el proyecto tendría que asumir un coste adicional para crear dicha documentación. Pero no todo es malo, esta manera de hacer los naming en la base de datos es buena si un "tercero" accede a nuestra base de datos, ya que este no sabría a qué hace referencia cada campo (tema complicado ya que se "supone" que los servidores donde se alojan las bases de datos de las aplicaciones "deben" proporcionarnos la seguridad de que nadie puede acceder a ellos. Pero esta es la teoría...).

El punto 2 facilita la compresión de nuestra base de datos, ya que de un simple vistazo se puede identificar cada campo. Pero como dije arriba, siempre hay que seguir unos patrones, y un idioma. No puede ser que haya campos que sean en inglés, otros en castellano, etc. Por ejemplo en cada tabla que tengamos un "ID", éste debe llamarse de la misma forma, no en unos sitios "id" a secas, en otros "Idxxxx", "xxxxId", etc. También otra buena práctica es poner en los campos que sean "foreing key" el nombre de la tabla a la que hace referencia. Por ejemplo si tenemos 2 tablas “Country” y "Currency", el nombre del campo foreing key de la tabla Country debería de ser CountryId.

Otro tema al cual no le solemos prestar mucha atención es los tipos de datos de los campos. Aquí hay que tener varias cosas en cuenta:
1.     Si necesitamos 10 caracteres para almacenar un valor, NO ES NECESARIO utilizar un varchar(MAX). El impacto en el rendimiento es significante si sólo hay un campo de ese tipo, pero puede convertirse en un problema cuando TODOS son así.
  1. Campos índices: SQL Server nos proporciona el tipo "autonumérico", el cual nos facilita el trabajo a los desarrolladores, pero tiene 2 inconvenientes. Uno que ese ID no es único en nuestra base de datos, con lo que no podríamos decir que un Id identifica un objeto concreto, y en cuanto al rendimiento, es más rápido para la inserción, pero más lento para la lectura (en  esto último tengo mis dudas), con lo que la solución para los campos ID es crearlo del tipo uniqueidentifier. 
Una vez tengamos nuestra base de datos creada, hay otros aspectos que debemos tener muy en cuenta si queremos ganar rendimiento en nuestra futura aplicación. El principal  es crear índices en nuestras tablas (no voy a entrar en como crearlos, ya q no es el objetivo de este post), ya que con esto se puede ganar muchísimo tiempo al realizar las consultas. Esto es algo que a primera vista piensas que no tiene por qué influir en el tiempo que emplea el motor de base de datos en devolvernos la consulta, pero en realidad tener unos buenos índices creados sobre nuestras tablas puede marcar la diferencia de tu aplicación respecto a otras. Y otro de los puntos donde se puede mejorar el rendimiento es en la manea de crear nuestra programación en la base de datos. Por ejemplo, en los "procedimientos almacenados" todos acostumbramos a crearlos como una query  que hace lo que tenga que hacer y listo, pero si en vez de hacerlo así creamos la query como un string y la ejecutamos con un sp_executesql, esto hace que la primera vez que se ejecute el procedimiento almacenado sí que pueda ser más lento, pero las siguientes ejecuciones irá mucho más rápido ya que la query se quedará cacheada en el plan de ejecución del motos de base de datos. Esto último es muy útil cuando por ejemplo tenemos que ejecutar un procedimiento almacenado varias veces. 

En conclusión, se podría decir que una de las principales cosas que hacen que un proyecto vaya bien o vaya mal es el tiempo invertido en el análisis y creación de la base de datos. Una estructuración clara y simple de la base de datos hace que nuestra arquitectura de proyecto sea más simple, con lo que será más fácil de desarrollar y sobre todo de mantener en un futuro.

 

No hay comentarios: