Estrategias del desarrollo e implementación de bases de datos (VB)

por Scott Mitchell

Al implementar una aplicación controlada por datos por primera vez, puede copiar ciegamente la base de datos en el entorno de desarrollo en el entorno de producción. Pero realizar una copia oculta en las implementaciones posteriores sobrescribirá los datos introducidos en la base de datos de producción. En su lugar, la implementación de una base de datos implica aplicar los cambios realizados a la base de datos de desarrollo desde la última implementación en la base de datos de producción. En este tutorial se examinan estos desafíos y se ofrecen diversas estrategias para ayudar con la crónica y la aplicación de los cambios realizados en la base de datos desde la última implementación.

Introducción

Como se explicó en los tutoriales anteriores, la implementación de una aplicación de ASP.NET implica copiar el contenido pertinente del entorno de desarrollo al entorno de producción. La implementación no es un evento único, sino algo que sucede cada vez que se publica una nueva versión del software o cuando se han identificado y solucionado errores o problemas de seguridad. Al copiar páginas ASP.NET, imágenes, archivos JavaScript y otros archivos de este tipo en el entorno de producción, no es necesario preocuparse por cómo se han cambiado estos archivos desde la última implementación. Puede copiar ciegamente el archivo en producción, sobrescribir el contenido existente. Por desgracia, esta simplicidad no se extiende a la implementación de la base de datos.

Al implementar una aplicación controlada por datos por primera vez, puede copiar ciegamente la base de datos en el entorno de desarrollo en el entorno de producción. Pero realizar una copia oculta en las implementaciones posteriores sobrescribirá los datos introducidos en la base de datos de producción. En su lugar, la implementación de una base de datos implica aplicar los cambios realizados a la base de datos de desarrollo desde la última implementación en la base de datos de producción. En este tutorial se examinan estos desafíos y se ofrecen diversas estrategias para ayudar con la crónica y la aplicación de los cambios realizados en la base de datos desde la última implementación.

Los desafíos de implementar una base de datos

Antes de implementar una aplicación controlada por datos por primera vez, solo hay una base de datos, es decir, la base de datos en el entorno de desarrollo, por lo que al implementar una aplicación controlada por datos por primera vez puede copiar ciegamente la base de datos en el entorno de desarrollo en el entorno de producción. Pero una vez implementada la aplicación, hay dos copias de la base de datos: una en desarrollo y otra en producción.

Entre las implementaciones, las bases de datos de desarrollo y producción pueden dejar de estar sincronizadas. Aunque el esquema de la base de datos de producción permanece sin cambios, el esquema de la base de datos de desarrollo puede cambiar a medida que se agregan nuevas características. Puede agregar o quitar columnas, tablas, vistas o procedimientos almacenados. También puede haber datos importantes que se agregan a la base de datos de desarrollo. Muchas aplicaciones controladas por datos incluyen tablas de búsqueda rellenadas con datos codificados de forma rígida y específicos de la aplicación que no son editables por el usuario. Por ejemplo, un sitio web de subastas podría tener una lista desplegable con opciones que describen la condición del artículo que se está subastando: Nuevo, Como Nuevo, Bueno y Regular. En lugar de codificar de forma rígida estas opciones directamente en la lista desplegable, suele ser mejor colocarlas en una tabla de base de datos. Si, durante el desarrollo, se agrega una nueva condición denominada Pobre a la tabla, al implementar la aplicación, este mismo registro debe agregarse a la tabla de búsqueda de la base de datos de producción.

Lo ideal sería copiar la base de datos de desarrollo a producción. Pero tenga en cuenta que después de haber implementado la aplicación y reanudado el desarrollo, la base de datos de producción se rellena con datos reales de los usuarios reales. Por lo tanto, si simplemente copiara la base de datos de desarrollo a producción en la siguiente implementación, sobrescribiría la base de datos de producción y perdería sus datos existentes. El resultado neto es que la implementación de la base de datos se reduce a la aplicación de los cambios realizados en la base de datos de desarrollo desde la última implementación.

Dado que la implementación de una base de datos implica aplicar los cambios en el esquema y, posiblemente, los datos desde la última implementación, se debe mantener un historial de cambios (o determinarse en tiempo de implementación) para que esos cambios se puedan aplicar en producción. Hay una variedad de técnicas para administrar y aplicar cambios en el modelo de datos.

Definición de la línea base

Para mantener los cambios en la base de datos de la aplicación, debe tener algún estado inicial, una línea base a la que se aplican los cambios. En un extremo, el estado inicial podría ser una base de datos vacía sin tablas, vistas ni procedimientos almacenados. Esta línea de base da como resultado un registro de cambios grande porque debe incluir la creación de todas las tablas, vistas y procedimientos almacenados de la base de datos junto con los cambios realizados después de la implementación inicial. En el otro extremo del espectro, podría establecer la línea base como la versión de la base de datos que se implementa inicialmente en el entorno de producción. Esta opción da como resultado un registro de cambios mucho menor porque solo incluye los cambios realizados en la base de datos después de la primera implementación. Este es el enfoque que yo prefiero. Y, por supuesto, puede elegir un enfoque más intermedio, definiendo la línea base como algún punto entre la creación inicial de la base de datos y cuándo se implementa por primera vez la base de datos.

Una vez que haya elegido una línea base, considere la posibilidad de generar un script SQL que se pueda ejecutar para volver a crear la versión de línea base. Este script permite volver a crear rápidamente la versión de línea base de la base de datos. Esta funcionalidad es especialmente útil en proyectos más grandes, donde puede haber varios desarrolladores trabajando en el proyecto o entornos adicionales, como pruebas o ensayo, que necesitan cada uno su propia copia de la base de datos.

Hay una variedad de herramientas a su disposición para generar un script SQL de la versión de línea de base. En SQL Server Management Studio (SSMS), puede hacer clic con el botón derecho en la base de datos, ir al submenú Tareas y elegir la opción Generar scripts. Esto inicia el Asistente de Script, al que puede pedir que genere un archivo que contenga los comandos SQL para crear los objetos de su base de datos. Otra opción es el Asistente para publicación de bases de datos, que puede generar los comandos SQL para no solo crear el esquema de la base de datos, sino también los datos de las tablas de base de datos. El Asistente para publicación de bases de datos se examinó con detalle en el tutorial Implementación de una base de datos. Independientemente de la herramienta que use, al final debe tener un archivo de script que pueda usar para volver a crear la versión de línea base de la base de datos, si es necesario.

Documentación de los cambios de la base de datos en prosa

La manera más sencilla de mantener un registro de cambios en el modelo de datos durante la fase de desarrollo es registrar los cambios en prosa. Por ejemplo, si durante el desarrollo de una aplicación ya implementada, agregue una nueva columna a la tabla Employees, quite una columna de la tabla Orders y agregue una nueva tabla (ProductCategories), se mantendría un archivo de texto o un documento de Microsoft Word con el siguiente historial:

Fecha del cambio Detalles del cambio
03/02/2009: Se agregó la columna DepartmentID (int, NOT NULL) a la tabla Employees. Se agregó una restricción de clave externa de Departments.DepartmentID a Employees.DepartmentID.
05/02/2009: Se quitó la columna TotalWeight de la tabla Orders. Datos ya capturados en registros asociados OrderDetails.
12/02/2009: Creó la tabla ProductCategories. Hay tres columnas: ProductCategoryID (int, IDENTITY, NOT NULL), CategoryName (nvarchar(50), NOT NULL) y Active (bit, NOT NULL). Se agregó una restricción de clave principal a ProductCategoryID y un valor predeterminado de 1 a Active.

Hay una serie de inconvenientes para este enfoque. Para empezar, no hay esperanza de automatización. Cada vez que estos cambios se deben aplicar a una base de datos (por ejemplo, cuando se implementa la aplicación), un desarrollador debe implementar manualmente cada cambio, de uno en uno. Además, si necesita reconstruir una versión concreta de la base de datos a partir de la línea de base mediante el registro de cambios, hacerlo llevará cada vez más tiempo a medida que crezca el tamaño del registro. Otro inconveniente de este método es que la claridad y el nivel de detalle de cada entrada del registro de cambios se deja en manos de la persona que registra el cambio. En un equipo con varios desarrolladores, algunos pueden hacer entradas más detalladas, más legibles o más precisas que otros. Además, es posible que se produzcan erratas y otros errores humanos en la introducción de datos.

La principal ventaja de documentar los cambios en la base de datos en prosa es la simplicidad. No es necesario familiarizarse con la sintaxis SQL para crear y modificar objetos de base de datos. En su lugar, puede registrar los cambios en prosa e implementarlos a través de la interfaz gráfica de usuario de SQL Server Management Studio.

Es cierto que mantener el registro de cambios en prosa no es muy sofisticado y no funcionará bien con determinados proyectos, como los de gran envergadura, los que tienen cambios frecuentes en el modelo de datos o los que implican a varios desarrolladores. Pero he visto que este enfoque funciona bastante bien en proyectos pequeños, de una sola persona, que solo tienen cambios ocasionales en el modelo de datos y en los que el desarrollador en solitario no tiene grandes conocimientos de la sintaxis SQL para crear y alterar objetos de base de datos.

Nota:

Aunque, técnicamente, la información del registro de cambios sólo es necesaria hasta el momento de la implementación, recomiendo mantener un historial de los cambios. Pero en lugar de mantener un único archivo de registro de cambios cada vez mayor, considere la posibilidad de tener un archivo de registro de cambios diferente para cada versión de la base de datos. Normalmente, querrá versionar la base de datos cada vez que se implemente. Si se mantiene un registro de los cambios, se puede, partiendo de la línea de base, recrear cualquier versión de la base de datos ejecutando los scripts del registro de cambios empezando por la versión 1 y continuando hasta llegar a la versión que se necesita recrear.

Grabación de las instrucciones de cambio de SQL

El principal inconveniente de mantener el registro de cambios en prosa es la falta de automatización. Lo ideal sería que implementar los cambios en la base de datos de producción en el momento de la implementación fuera tan sencillo como pulsar un botón para ejecutar un script, en lugar de tener que ejecutar manualmente una lista de instrucciones. Esta automatización es posible mediante el mantenimiento de un registro de cambios que contiene los comandos SQL que se usan para modificar el modelo de datos.

La sintaxis SQL incluye varias instrucciones para crear y modificar varios objetos de base de datos. Por ejemplo, la instrucción CREATE TABLE, cuando se ejecuta, crea una nueva tabla con las columnas y restricciones especificadas. La instrucción ALTER TABLE modifica una tabla existente, agregando, quitando o modificando sus columnas o restricciones. También hay instrucciones para crear, modificar y quitar índices, vistas, funciones definidas por el usuario, procedimientos almacenados, desencadenadores y otros objetos de base de datos.

Volviendo al ejemplo anterior, imagen que durante el desarrollo de una aplicación ya implementada agrega una nueva columna a la tabla Employees, quita una columna de la tabla Orders y agrega una nueva tabla (ProductCategories). Estas acciones generarían un archivo de registro de cambios con los siguientes comandos SQL:

-- Add the DepartmentID column 

ALTER TABLE [Employees] ADD [DepartmentID] 
int NOT NULL 

-- Add a foreign key constraint between Departments.DepartmentID and Employees.DepartmentID
ALTER TABLE [Employees] ADD 
CONSTRAINT [FK_Departments_DepartmentID]
      FOREIGN 
KEY ([DepartmentID]) 
      REFERENCES 
[Departments] ([DepartmentID]) 

-- Remove TotalWeight column from Orders
ALTER TABLE [Orders] DROP COLUMN 
[TotalWeight] 

-- Create the ProductCategories table

CREATE TABLE [ProductCategories]
(
      [ProductCategoryID] 
int IDENTITY(1,1) NOT NULL,
      [CategoryName] 
nvarchar(50) NOT NULL,
      [Active] 
bit NOT NULL CONSTRAINT [DF_ProductCategories_Active]  DEFAULT 
((1)),
      CONSTRAINT 
[PK_ProductCategories] PRIMARY KEY CLUSTERED ( [ProductCategoryID])
)

Insertar estos cambios en la base de datos de producción en el momento de la implementación es una operación de un solo clic: abra SQL Server Management Studio, conéctese a la base de datos de producción, abra la ventana Nueva consulta, pegue el contenido del registro de cambios y haga clic en Ejecutar para ejecutar el script.

Uso de una herramienta de comparación para sincronizar los modelos de datos

Documentar los cambios de la base de datos en prosa es fácil, pero aplicar los cambios requiere que un desarrollador realice cada cambio en la base de datos de producción de uno en uno; documentar los comandos SQL de cambio hace que aplicar esos cambios en la base de datos de producción sea tan fácil y rápido como pulsar un botón, pero requiere aprender y dominar las sentencias SQL y la sintaxis para crear y alterar objetos de la base de datos. Las herramientas de comparación de bases de datos toman lo mejor de ambos enfoques y descartan lo peor.

Una herramienta de comparación de bases de datos compara el esquema o los datos de dos bases de datos y muestra un informe de resumen que muestra cómo difieren las bases de datos. A continuación, con sólo pulsar un botón, podrá generar los comandos SQL para sincronizar uno o varios objetos de la base de datos. En pocas palabras, puede utilizar una herramienta de comparación de bases de datos para comparar las bases de datos de desarrollo y producción en el momento de la implementación, generando un archivo que contenga los comandos SQL que, cuando se ejecuten, aplicarán los cambios al esquema de la base de datos de producción para que refleje el esquema de la base de datos de desarrollo.

Hay una variedad de herramientas de comparación de bases de datos de terceros que ofrecen muchos proveedores diferentes. Un ejemplo de este tipo es SQL Compare, de Red Gate Software. Veamos el proceso de uso de SQL Compare para comparar y sincronizar los esquemas de bases de datos de desarrollo y producción.

Nota:

En el momento de escribir la versión actual de SQL Compare era la versión 7.1, y la edición estándar costaba 395 dólares. Puede continuar descargando una evaluación gratuita de 14 días.

Cuando se inicia SQL Compare, se abre el cuadro de diálogo Proyectos de comparación, que muestra los proyectos de SQL Compare guardados. Cree un nuevo proyecto. Esto inicia el Asistente para configuración del proyecto, que solicita información sobre las bases de datos que se van a comparar (véase la ilustración 1). Escriba la información de las bases de datos del entorno de desarrollo y producción.

Compare the Development and Production Databases

Ilustración 1: comparar las bases de datos de desarrollo y producción (haga clic para ver la imagen a tamaño completo)

Nota:

Si la base de datos del entorno de desarrollo es un archivo de base de datos de SQL Express Edition en la carpeta App_Data del sitio web, deberá registrar la base de datos en el servidor de bases de datos de SQL Server Express para seleccionarla en el cuadro de diálogo que se muestra en la ilustración 1. La manera más fácil de lograrlo es abrir SQL Server Management Studio (SSMS), conectarse al servidor de base de datos de SQL Server Express y adjuntar la base de datos. Si no tiene SSMS instalado en su equipo, puede descargar e instalar el programa gratuito SQL Server Management Studio.

Además de seleccionar las bases de datos que se van a comparar, también puede especificar una variedad de opciones de comparación en la pestaña Opciones. Una opción que puede activar es "Omitir nombres de restricción e índice". Recuerde que en el tutorial anterior agregamos los objetos de base de datos de servicios de aplicación a las bases de datos de desarrollo y producción. Si usó la herramienta aspnet_regsql.exe para crear estos objetos en la base de datos de producción, verá que la clave principal y los nombres de restricción únicos difieren entre las bases de datos de desarrollo y producción. Por lo tanto, SQL Compare marcará todas las tablas de servicios de aplicación como diferentes. Puede dejar desactivada la opción "Omitir nombres de restricción e índice" y sincronizar los nombres de restricción, o indicar a SQL Compare que omita estas diferencias.

Después de seleccionar las bases de datos que se van a comparar (y revisar las opciones de comparación), haga clic en el botón Comparar para comenzar la comparación. En los próximos segundos, SQL Compare examina los esquemas de las dos bases de datos y genera un informe de cómo difieren. He realizado algunas modificaciones en la base de datos de desarrollo para mostrar cómo se indican estas discrepancias en la interfaz de comparación de SQL. Como muestra la ilustración 2, he añadido una columna BirthDate a la tabla Authors, he eliminado la columna ISBN de la tabla Books y he añadido una nueva tabla, Ratings, que tiene por objeto permitir a los usuarios que visitan el sitio calificar los libros reseñados.

Nota:

Los cambios del modelo de datos realizados en este tutorial se realizaron para ilustrar el uso de una herramienta de comparación de bases de datos. No encontrará estos cambios en la base de datos en tutoriales futuros.

SQL Compare Lists the Differences Between the Development and Production Databases

Ilustración 2: comparación de SQL muestra las diferencias entre las bases de datos de desarrollo y producción (haga clic para ver la imagen a tamaño completo)

SQL Compare desglosa los objetos de base de datos en grupos, mostrando rápidamente qué objetos existen en ambas bases de datos, pero son diferentes, qué objetos existen en una base de datos, pero no en la otra, y qué objetos son idénticos. Como puede ver, hay dos objetos que existen en ambas bases de datos, pero son diferentes: la tabla Authors, que tenía una columna agregada y la tabla Books, que tenía una quitada. Hay un objeto que solo existe en la base de datos de desarrollo, es decir, la tabla recién creada Ratings. Y hay 117 objetos idénticos en ambas bases de datos.

Al seleccionar un objeto de base de datos se muestra la ventana Diferencias de SQL, que muestra cómo difieren estos objetos. En la ventana Diferencias de SQL, que se muestra en la parte inferior de la ilustración 2, se resalta que la tabla Authors de la base de datos de desarrollo tiene la columna BirthDate, que no se encuentra en la tabla Authors de la base de datos de producción.

Después de revisar las diferencias y seleccionar los objetos que desea sincronizar, el siguiente paso es generar los comandos SQL necesarios para actualizar el esquema de la base de datos de producción para que coincida con la base de datos de desarrollo. Esto se logra mediante el Asistente para sincronización. El Asistente para sincronización confirma qué objetos sincronizar y resume el plan de acción (véase la ilustración 3). Puede sincronizar las bases de datos inmediatamente o generar un script con los comandos SQL que se pueden ejecutar en su tiempo libre.

Use the Synchronization Wizard to Synchronize Your Databases Schemas

Ilustración 3: usar el Asistente para sincronización para sincronizar los esquemas de bases de datos (haga clic para ver la imagen a tamaño completo)

Las herramientas de comparación de bases de datos como SQL Compare de Red Gate Software hacen que aplicar los cambios del esquema de la base de datos de desarrollo a la base de datos de producción sea tan fácil como apuntar y hacer clic.

Nota:

SQL Compare compara y sincroniza los esquemas de dos bases de datos. Desafortunadamente, no compara ni sincroniza los datos dentro de dos tablas de bases de datos. Red Gate Software ofrece un producto denominado SQL Data Compare que compara y sincroniza los datos entre dos bases de datos, pero es un producto independiente de SQL Compare y cuesta otros 395 dólares.

Desconexión de la aplicación durante la implementación

Como hemos visto a lo largo de estos tutoriales, la implementación es un proceso que implica varios pasos: copiar las páginas ASP.NET, las páginas maestras, los archivos CSS, los archivos JavaScript, las imágenes y otros contenidos necesarios del entorno de desarrollo al entorno de producción; copiar la información de configuración específica del entorno de producción, si es necesario; y aplicar los cambios en el modelo de datos desde la última implementación. En función del número de archivos y la complejidad de los cambios de la base de datos, estos pasos pueden tardar entre unos segundos y varios minutos en completarse. Durante esta ventana, la aplicación web está en flujo y los usuarios que visitan el sitio pueden experimentar errores o un comportamiento inesperado.

Al implementar un sitio web, lo mejor es dejar la aplicación web "desconectada" hasta que se haya completado la implementación. Desconectar la aplicación (y recuperarla una vez finalizado el proceso de implementación) es tan fácil como cargar un archivo y eliminarlo. A partir de ASP.NET 2.0, la mera presencia de un archivo denominado app_offline.htm en el directorio raíz de la aplicación hace que todo el sitio web quede "desconectado". Cualquier solicitud a una página ASP.NET en ese sitio se responde automáticamente con el contenido del archivo app_offline.htm. Una vez eliminado ese archivo, la aplicación vuelve a estar en línea.

Desconectar una aplicación durante la implementación es tan simple como cargar un archivo app_offline.htm en el directorio raíz del entorno de producción antes de comenzar el proceso de implementación y, a continuación, eliminarlo (o cambiarle el nombre a otra cosa) una vez completada la implementación. Para más información sobre esta técnica, consulte el artículo de John Peterson: Desconectar una aplicación ASP.NET.

Resumen

El principal desafío en la implementación de una aplicación controlada por datos se centra en la implementación de la base de datos. Como hay dos versiones de la base de datos -una en el entorno de desarrollo y otra en el de producción-, los esquemas de estas dos bases de datos pueden desincronizarse a medida que se añaden nuevas funciones en el entorno de desarrollo. Además, como la base de datos de producción se rellena con datos reales de usuarios reales, no se puede sobrescribir la base de datos de producción con la base de datos de desarrollo modificada, como ocurre al implementar los archivos que componen la aplicación (las páginas ASP.NET, los archivos de imagen, etc.). En cambio, implementar una base de datos implica implementar en la base de datos de producción el conjunto preciso de cambios realizados en la base de datos de desarrollo desde la última implementación.

En este tutorial se examinaron tres técnicas para mantener y aplicar un registro de cambios de base de datos. El enfoque más sencillo es registrar los cambios en prosa. Aunque esta táctica hace que la implementación de estos cambios en la base de datos de producción sea un proceso manual, no requiere conocimiento de los comandos SQL para crear y modificar objetos de base de datos. Un enfoque más sofisticado, y mucho más aceptable en proyectos grandes o con varios desarrolladores, consiste en registrar los cambios como una serie de comandos SQL. Esto reduce considerablemente la implementación de estos cambios en la base de datos de destino. Lo mejor de ambos enfoques se puede lograr mediante una herramienta de comparación de bases de datos, como SQL Compare, de Red Gate Software.

Este tutorial concluye nuestro enfoque en la implementación de una aplicación controlada por datos. El siguiente conjunto de tutoriales examina cómo responder a errores en el entorno de producción. Veremos cómo mostrar una página de error descriptivo en lugar de la Yellow Screen of Death. Y veremos cómo registrar los detalles del error y cómo avisarle cuando se produzcan estos errores.

¡Feliz programación!