Metodología de control de versión SQL

Hay varias preguntas sobre SO sobre el control de versiones para SQL y muchos resources en la web, pero no puedo encontrar algo que cubra lo que estoy tratando de hacer.

En primer lugar, 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:

  • El esquema de la database y la tabla de búsqueda están versionados
  • Se versionan los scripts DML para correcciones de datos a tablas más grandes
  • Se puede promocionar un server de la versión N a la versión N + X, donde X puede no ser siempre 1
  • El código no está duplicado dentro del sistema de control de versiones; por ejemplo, si agrego una columna a una tabla, no quiero tener que asegurarme de que el cambio esté tanto en un script de creación como en un script alter
  • El sistema necesita admitir múltiples clientes que se encuentran en distintas versiones para la aplicación (tratando de getlos todos en 1 o 2 lanzamientos, pero todavía no)

Algunas organizaciones mantienen scripts de cambios incrementales en su control de versiones y para get de la versión N a N + 3 tendrías que 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 time de lo necesario.

Algunas organizaciones simplemente mantendrán un script completo de compilation de bases de datos en cada nivel de versión y luego usarán una herramienta como SQL Compare para llevar una database 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 commands 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!

Luché con esto durante varios años antes de adoptar una estrategia que parece funcionar bastante bien. Puntos key en los que vivo:

  • La database no necesita ser versionada independientemente desde la aplicación
  • Todos los scripts de actualización de database deben ser idempotentes

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

Por supuesto, este método impone algunos requisitos en el layout de la database:

  • Todos los cambios de esquema se realizan a través de una secuencia de commands, no funciona la GUI.
  • Se debe tener especial cuidado para asegurar que todas las keys, restricciones, etc. sean nombradas para que puedan ser referencedas por un script de actualización posterior, si es necesario.
  • Todos los scripts 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 nonclustenetworking (Id); if not exists (select 1 from sysindexes where [name] = 'ix_registrations_created') create clustenetworking 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, puedo ejecutar toda la serie de scripts contra la database en cualquier estado y sé 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 build un instalador simple para hacer esto, y agregar los cambios de esquema al control de fuente no es un problema en absoluto.

Tienes un set bastante riguroso de requisitos, no estoy seguro de si encontrarás algo que ponga controles en todos los cuadros, especialmente los esquemas simultáneos múltiples y el control de versión inteligente.

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

Sí, estás pidiendo mucho, ¡pero todos son puntos realmente 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.networking-gate.com/products/SQL_Source_Control/index.htm

Para la próxima versión, estamos totalmente de acuerdo con los cambios de esquema y el soporte indirecto de datos estáticos a través de nuestra herramienta SQL Data Compare. Todos los cambios se guardan como scripts de creación, aunque cuando está actualizando o implementando en una database, 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 migration artesanal se construya para get entre dos versiones adyacentes, ya que no todo el "bash" 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 buildía "mágicamente" scripts de implementación a partir de dos versiones arbitrarias.

para este tipo de problema, use Visual Studio team system 2008 para controlar la versión de su database sql.

En tsf no hay. de característica avialbe como

  • Datacompare
  • Schemacompare
  • control de versión

sobre el control de la versión de la database: http://www.codinghorror.com/blog/2006/12/is-your-database-under-version-control.html para más detalles verifique: http://msdn.microsoft.com/en -us / library / ms364062 (VS.80) .aspx

Estamos utilizando SQL Examiner para mantener el esquema de la database 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é).

Aquí está la descripción del enfoque de SQL Examiner: Cómo hacer que su database esté bajo control de versiones

Pruebe DBSourceTools. ( http://dbsourcetools.codeplex.com )
Es de código abierto y está específicamente diseñado para crear una database completa (tablas, vistas, processs en el disco y luego volver a crear esa database a través de un destino de deployment).
Puede crear una secuencia de commands de todos los datos, o simplemente especificar las tablas para los datos de secuencia de commands.
Además, puede comprimir los resultados para su distribución.
Lo utilizamos para el control de origen de las bases de datos y para probar parches de actualización para nuevas versiones.
En el back-end está construido alnetworkingedor 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.