Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Server database change workflow best practices

The Background

My group has 4 SQL Server Databases:

  • Production
  • UAT
  • Test
  • Dev

I work in the Dev environment. When the time comes to promote the objects I've been working on (tables, views, functions, stored procs) I make a request of my manager, who promotes to Test. After testing, she submits a request to an Admin who promotes to UAT. After successful user testing, the same Admin promotes to Production.

The Problem

The entire process is awkward for a few reasons.

  1. Each person must manually track their changes. If I update, add, remove any objects I need to track them so that my promotion request contains everything I've done. In theory, if I miss something testing or UAT should catch it, but this isn't certain and it's a waste of the tester's time, anyway.
  2. Lots of changes I make are iterative and done in a GUI, which means there's no record of what changes I made, only the end result (at least as far as I know).
  3. We're in the fairly early stages of building out a data mart, so the majority of the changes made, at least count-wise, are minor things: changing the data type for a column, altering the names of tables as we crystallize what they'll be used for, tweaking functions and stored procs, etc.

The Question

People have been doing this kind of work for decades, so I imagine there have got to be a much better way to manage the process. What I would love is if I could run a diff between two databases to see how the structure was different, use that diff to generate a change script, use that change script as my promotion request. Is this possible? If not, are there any other ways to organize this process?

For the record, we're a 100% Microsoft shop, just now updating everything to SQL Server 2008, so any tools available in that package would be fair game.


I should clarify I'm not necessarily looking for diff tools. If that's the best way to sync our environments then it's fine, but if there's a better way I'm looking for that.

An example doing what I want really well are migrations in Ruby on Rails. Dead simple syntax, all changes are well documented automatically and by default, determining what migrations need to run is almost trivially easy. I'd love if there was something similar to this for SQL Server.

My ideal solution is 1) easy and 2) hard to mess up. Rails Migrations are both; everything I've done so far on SQL Server is neither.

like image 474
kubi Avatar asked May 18 '10 18:05

kubi


People also ask

Is it best practice to have auto shrink enabled on database?

Shrinking a database is not a good practice because it is very expensive operation in terms of I/O, CPU usage, locking and transaction log generation. Database auto shrink in SQL Server also causes your Indexes to be fragmented because it runs frequently.

Does enabling query store affect performance?

Query Store performance impact So far Microsoft has indicated that enabling the Query Store in SQL Server 2016 will result in a performance impact of 3-5% on average.


2 Answers

Within our team, we handle database changes like this:

  • We (re-)generate a script which creates the complete database and check it into version control together with the other changes. We have 4 files: tables, user defined functions and views, stored procedures, and permissions. This is completely automated - only a double-click is needed to generate the script.
  • If a developer has to make changes to the database, she does so on her local db.
  • For every change, we create update scripts. Those are easy to create: The developer regenerates the db script of his local db. All the changes are now easy to identify thanks to version control. Most changes (new tables, new views etc) can simply be copied to the update script, other changes (adding columns for example) need to be created manually.
  • The update script is tested either on our common dev database, or by rolling back the local db to the last backup - which was created before starting to change the database. If it passes, it's time to commit the changes.
  • The update scripts follow a naming convention so everybody knows in which order to execute them.

This works fairly well for us, but still needs some coordination if several developers modify heavily the same tables and views. This doesn't happen often though.

The important points are:

  • database structure is only modified by scripts, except for the local developer's db. This is important.
  • SQL scripts are versioned by source control - the db can be created as it was at any point in the past
  • database backups are created regularly - at least before making changes to the db
  • changes to the db can be done quickly - because the scripts for those changes are created relatively easily.

However, if you have a lot of long lasting development branches for your projects, this may not work well.

It is by far not a perfect solution, and some special precautions are to be taken. For example, if there are updates which may fail depending on the data present in a database, the update should be tested on a copy of the production database.

In contrast to rails migrations, we do not create scripts to reverse the changes of an update. But this isn't always possible anyway, at least in respect to the data (the content of a dropped column is lost even if you recreate the column).

like image 103
marapet Avatar answered Oct 14 '22 00:10

marapet


Version Control and your Database

The root of all things evil is making changes in the UI. SSMS is a DBA tool, not a developer one. Developers must use scripts to do any sort of changes to the database model/schema. Versioning your metadata and having upgrade script from every version N to version N+1 is the only way that is proven to work reliably. It is the solution SQL Server itself deploys to keep track of metadata changes (resource db changes).

Comparison tools like SQL Compare or vsdbcmd and .dbschema files from VS Database projects are just last resorts for shops that fail to do a proper versioned approach. They work in simple scenarios, but I see them all fail spectacularly in serious deployments. One just does not trust a tool to do a change to +5TB table if the tools tries to copy the data...

like image 22
Remus Rusanu Avatar answered Oct 14 '22 00:10

Remus Rusanu