2010-05-05 11 views
12

Hay varias preguntas sobre SO sobre el control de versiones para SQL y muchos recursos en la web, pero no puedo encontrar algo que cubra lo que intento hacer.Metodología de control de versión SQL

Primero, estoy hablando de una metodología aquí. Estoy familiarizado con las diversas aplicaciones de control de código fuente y estoy familiarizado con herramientas como SQL Compare de Red Gate, etc. y sé cómo escribir una aplicación para verificar las cosas dentro y fuera de mi sistema de control de fuente automáticamente. Si hay una herramienta que sería particularmente útil para proporcionar una metodología completamente nueva o que tiene una funcionalidad útil e inusual, entonces genial, pero para las tareas mencionadas anteriormente ya estoy configurado.

Los requisitos que estoy tratando de cumplir son: datos

  • el esquema de base de datos y tabla de consulta se versionan
  • secuencias de comandos DML para correcciones de datos a las tablas más grandes están versionados
  • Un servidor se puede promocionar de la versión N a la versión N + X, donde X no siempre puede ser 1
  • El código no está duplicado en el sistema de control de versiones; por ejemplo, si agrego una columna a una tabla, no quiero tener para asegurarse de que el cambio esté en un script de creación y un alter scr ipt
  • El sistema tiene que soportar múltiples clientes que se encuentran en distintas versiones de la aplicación (tratando de llegar a todos ellos hasta dentro de 1 o 2 lanzamientos, pero no todavía)

Algunas organizaciones mantienen guiones cambio incremental en su control de versiones y para obtener de la versión N a N + 3, debería ejecutar scripts para N-> N + 1, luego N + 1-> N + 2, luego N + 2-> N + 3. Algunos de estos scripts pueden ser repetitivos (por ejemplo, se agrega una columna pero luego se modifica para cambiar el tipo de datos). Estamos tratando de evitar esa repetitividad ya que algunos de los clientes DB pueden ser muy grandes, por lo que estos cambios pueden llevar más tiempo de lo necesario.

Algunas organizaciones simplemente mantendrán un script de compilación de base de datos completo en cada nivel de versión y luego usarán una herramienta como SQL Compare para llevar una base de datos a una de esas versiones. El problema aquí es que entremezclar scripts de DML puede ser un problema. Imagine un escenario donde agrego una columna, uso una secuencia de comandos DML para llenar dicha columna, luego, en una versión posterior, se cambia el nombre de la columna.

Quizás hay alguna solución híbrida? Tal vez solo estoy pidiendo demasiado? Sin embargo, cualquier idea o sugerencia sería muy apreciada.

Si los moderadores piensan que esto sería más apropiado como wiki de la comunidad, házmelo saber.

Gracias!

+2

No sé si vio esta, pero obtuve algunas respuestas razonables: http://stackoverflow.com/questions/2401229/database-structure-and-source-control-best-practice – Paddy

+1

¿Esto ayuda? ? http://msmvps.com/blogs/deborahk/archive/2010/05/02/vs-2010-database-project-an-introduction.aspx Tenga en cuenta que hay más enlaces en la parte inferior del artículo. –

+0

@Paddy - Gracias por el enlace. pdc tenía una buena solución que coincidía con una que estábamos considerando, pero las tareas de creación de guiones se subcontratan a la India (no es mi elección) y la experiencia allí es limitada, por lo que algunos de los códigos más complejos pueden ser un problema. Sin embargo, todavía está sobre la mesa por el momento. –

Respuesta

4

Luché con esto durante varios años antes de adoptar recientemente una estrategia que parece funcionar bastante bien. Los puntos clave que vivo:

  • La base de datos no tiene por qué ser versionado independientemente de la aplicación
  • Todos los scripts de actualización de bases de datos deben ser idempotent

Como resultado, ya no crea ningún tipo de tablas de versiones. Simplemente agrego cambios a una secuencia numerada de archivos .sql que pueden aplicarse en cualquier momento dado sin corromper la base de datos. Si hace las cosas más fáciles, escribiré una pantalla de instalación simple para la aplicación que permita a los administradores ejecutar estos scripts cuando lo deseen.

Por supuesto, este método impone unos requisitos sobre el diseño de bases de datos:

  • Todos los cambios de esquema se realizan a través de la escritura - no hay trabajo GUI.
  • Se debe tener especial cuidado para asegurar que todas las claves, restricciones, etc. se denominen de modo que puedan ser referenciadas por una secuencia de comandos de actualización posterior, si es necesario.
  • Todas las secuencias de comandos de actualización deben verificar las condiciones existentes.

Ejemplos de un proyecto reciente:

001.sql:

if object_id(N'dbo.Registrations') is null 
begin 
    create table dbo.Registrations 
    (
     [Id]     uniqueidentifier not null, 
     [SourceA]    nvarchar(50)  null, 
     [SourceB]    nvarchar(50)  null, 
     [Title]     nvarchar(50)  not null, 
     [Occupation]   nvarchar(50)  not null, 
     [EmailAddress]   nvarchar(100) not null, 
     [FirstName]    nvarchar(50)  not null, 
     [LastName]    nvarchar(50)  not null, 
     [ClinicName]   nvarchar(200) not null, 
     [ClinicAddress]   nvarchar(50)  not null, 
     [ClinicCity]   nvarchar(50)  not null, 
     [ClinicState]   nchar(2)   not null, 
     [ClinicPostal]   nvarchar(10)  not null, 
     [ClinicPhoneNumber]  nvarchar(10)  not null, 
     [ClinicPhoneExtension] nvarchar(10)  not null, 
     [ClinicFaxNumber]  nvarchar(10)  not null, 
     [NumberOfVets]   int    not null, 
     [IpAddress]    nvarchar(20)  not null, 
     [MailOptIn]    bit    not null, 
     [EmailOptIn]   bit    not null, 
     [Created]    datetime   not null, 
     [Modified]    datetime   not null, 
     [Deleted]    datetime   null 
    ); 
end 

if not exists(select 1 from information_schema.table_constraints where constraint_name = 'pk_registrations') 
    alter table dbo.Registrations add 
     constraint pk_registrations primary key nonclustered (Id); 

if not exists (select 1 from sysindexes where [name] = 'ix_registrations_created') 
    create clustered index ix_registrations_created 
     on dbo.Registrations(Created); 

if not exists (select 1 from sysindexes where [name] = 'ix_registrations_email') 
    create index ix_registrations_email 
     on dbo.Registrations(EmailAddress); 

if not exists (select 1 from sysindexes where [name] = 'ix_registrations_email') 
    create index ix_registrations_name_and_clinic 
     on dbo.Registrations (FirstName, 
           LastName, 
           ClinicName); 

002.sql

/********************************************************************** 
    The original schema allowed null for these columns, but we don't want 
    that, so update existing nulls and change the columns to disallow 
    null values 
*********************************************************************/ 

update dbo.Registrations set SourceA = '' where SourceA is null; 
update dbo.Registrations set SourceB = '' where SourceB is null; 
alter table dbo.Registrations alter column SourceA nvarchar(50) not null; 
alter table dbo.Registrations alter column SourceB nvarchar(50) not null; 

/********************************************************************** 
    The client wanted to modify the signup form to include a fax opt-in 
*********************************************************************/ 

if not exists 
(
    select 1 
     from information_schema.columns 
    where table_schema = 'dbo' 
     and table_name = 'Registrations' 
     and column_name = 'FaxOptIn' 
) 
alter table dbo.Registrations 
    add FaxOptIn bit null 
     constraint df_registrations_faxoptin default 0; 

003.sql, 004.sql, etc ...

En cualquier momento dado puedo ejecutar toda la serie de scripts contra el datab ase en cualquier estado y saber que las cosas se actualizarán inmediatamente con la versión actual de la aplicación. Debido a que todo está escrito, es mucho más fácil construir un instalador simple para hacer esto, y agregar los cambios de esquema al control de fuente no es un problema en absoluto.

+0

Gracias. Esto es similar a lo que "pdc" publicó en el enlace de Paddy. Es lo que he intentado vender el día anterior.Algunas de las personas aquí todavía están atadas a la idea de una base de datos modelo con metadatos adicionales y luego usando una herramienta de comparación junto con adicional, pero tal vez pueda influir en ellos. De hecho, mi enfoque aún mantiene las secuencias de comandos para un solo objeto en un archivo tanto como sea posible y, a medida que ocurren nuevos cambios, van en ese archivo en lugar de agregar constantemente nuevas secuencias de comandos. Ordenar entre versiones es el único desafío y creo que también tengo una solución para eso. –

3

Tienes bastante rigurosa conjunto de requisitos, no estoy seguro de si encontrará algo que ponga cheques en todas las casillas, espe cialmente los múltiples esquemas concurrentes y el control inteligente de la versión.

La herramienta más prometedora que he leído sobre este tipo de ajustes es Liquibase.
Éstos son algunos enlaces adicionales:

+0

Gracias por la sugerencia. Sí, definitivamente una lista difícil de requisitos, pero tengo esperanzas :) Veré qué puede hacer LiquiBase. –

2

Sí, usted está pidiendo mucho, pero todos son puntos muy pertinentes! Aquí en Red Gate nos estamos moviendo hacia una solución completa de desarrollo de bases de datos con nuestra extensión SQL Source Control SSMS y enfrentamos desafíos similares.

http://www.red-gate.com/products/SQL_Source_Control/index.htm

Para el próximo lanzamiento estamos apoyando plenamente los cambios de esquema, y ​​el apoyo a los datos estáticos indirectamente a través de nuestros datos SQL herramienta de comparación. Todos los cambios se guardan como scripts de creación, aunque cuando está actualizando o implementando en una base de datos, la herramienta se asegurará de que los cambios se apliquen adecuadamente como ALTER o CREATE.

El requisito más desafiante que aún no tiene una solución simple es la administración e implementación de la versión, que usted describe muy claramente. Si realiza cambios complejos en el esquema y los datos, puede ser inevitable que un script de migración artesanal se construya para obtener entre dos versiones adyacentes, ya que no todo el "intento" siempre se guarda junto con una versión más nueva. Los renombrados de columna son un buen ejemplo. La solución podría ser que se diseñe un sistema que guarde la intención, o si es demasiado complejo, le permite al usuario proporcionar un script personalizado para realizar el cambio complejo. Algún tipo de marco de gestión de versiones gestionaría estos y construiría "mágicamente" scripts de implementación a partir de dos versiones arbitrarias.

1

Estamos utilizando SQL Examiner para mantener el esquema de la base de datos bajo control de versión. También probé el VS2010, pero en mi opinión el enfoque VS es demasiado complejo para proyectos pequeños y medianos. Con SQL Examiner trabajo principalmente con SSMS y uso SQL Examiner para realizar actualizaciones de check-in a SVN (también se admiten TFS y SourceSafe, pero nunca lo intenté).

He aquí la descripción del enfoque de SQL examinador: How to get your database under version control

+0

Gracias por la sugerencia. Desafortunadamente, eso solo funciona al obtener scripts en su sistema de control de origen. Mi problema es en el momento de la implementación, automatizando eso en muchos clientes que tienen versiones diferentes del software. –

+0

SQL Examiner compara scripts de base de datos almacenados en el SVN con una base de datos de destino y produce un script de migración de esquema. Además, puede comparar la versión 10 en SVN con la versión 12 en SVN y generar secuencias de comandos para migrar el esquema de la versión 10 a la versión 12. – SQLDev

0

DBSourceTools intento. (http://dbsourcetools.codeplex.com)
Es de código abierto, y está específicamente diseñado para crear una base de datos completa (tablas, vistas, procesos en disco) y luego volver a crear esa base de datos a través de un destino de despliegue.
Puede crear una secuencia de comandos de todos los datos o simplemente especificar las tablas para los datos de secuencia de comandos.
Además, puede comprimir los resultados para su distribución.
Lo usamos para control de origen de bases de datos y para probar parches de actualización para nuevas versiones.
En el back-end está construido alrededor de SMO, y por lo tanto es compatible con SQL 2000, 2005 y 2008.
DBDiff está integrado, para permitir comparaciones de esquema.
Diviértete, - Nathan.