views:

288

answers:

7

We have three developers and one tester all working against the same database. We change the schema of the database quite often, and every time we do it tends to have a ripple effect of headaches for everyone else.

Are there good practices in place for .NET oriented development against MS SQL Server 2008 for managing this? I am thinking something similar to Rails Migrations and each dev and tester has their own local database. Or is that overkill? It'd at least be nice to have separate test and dev databases, but currently manually keeping two databases in sync is probably worse than our current predicament.

LiquiBase seems promising, has anyone successfully used it in a similar environment? Or are there better approaches?

We are using SQL Server 2008, VS 2008 and .NET 3.5 if that matters at all.

+2  A: 

We don't use a tool per se, but we do keep all of our schema under source control and then have a script that will update or rebuild the databse from source. This way when changes are made we can all update and stay in synch. This just becomes part of the daily morning routine, takes about 5 minutes just like synching up your code. This isn't perfect but it works for us.

Oh and I forgot to add if you make changes to schema you are also responsible for writing the migration script if any is needed. This tends to be needed anyway when something gets to production.

Hope that helps.

Dan Blair
This is always how I have seen it done, and it tends to work nicely.
Justin Ethier
+4  A: 

We have scripts to generate DB from scratch and this is what is sitting in the source control. Each developer (20 of them) is using script to generate 2 databases on their workstations. One for “work” – manual testing with sample data in it (there is script to populate sample data). Another DB is empty and used in unit tests (open transaction – do unit test – roll back).

Unit test are mandatory in multi developer environment. Also we always build “old” database and apply schema changes on it. Each developer is changing schema by creating upgrade procedures (this is how we have rebuild and upgrade ready at the same time).

For performance testing we have “loaders” – C# code to simulate users and populate millions of records over night on developer workstations.

Vladimir Kojic
A: 

Sounds like you need a database diff tool to create and store your database changes...

Red Gate SQL Compare

Visual Studio Team Database Edition

kervin
+1  A: 

Visual Studio Team System Database Edition (aka "Data Dude") is worth looking into. It can track database diffs and generate scripts of the changes so you can prepare a test/prod environment prior to deployment etc. I think its features are also available in the Development edition (see previous link) and in VS 2010 will be more visible. Take a look at this blog post: First Experience with Visual Studio 2008 Database Edition, I love it!!!

That, along with TFS, gives you the ability to version control the SQL files and run them against the database.

Ahmad Mageed
A: 

I personally think it's best to have separate databases. All working against one database can cause a lot of pain and waste time.

For example, say I'm looking into a performance issue and I'm running some benchmark tests to test out some optimisations on the database - the only way you can do this reliably is if you are consistent with your tests. If someone else makes a change to the DB midway through, that could skew your findings.

Plus, if I'm in the middle of something and the DB changes without me knowing causing errors/unexpected behaviour for me, I could spend x amount of time just working through before finding out it's due to a change someone else has made.

Instead, I think it's much better to have your own dev/test databases which you can each be responsible for updating. Then have a Continuous Integration server that automatically pulls out the latest code from source control and builds it every x hours.

AdaTheDev
Disagree. Developers should work against one database that has roughtly the same number of records as prod. Our dbs are way too large for each devloper to have their own version on their pc. YOur mileage may differ, but I see it as a poorr practice.
HLGEM
@HLGEM - yes, you do need to have a local database available that has production-size data volumes. In my environment it costs nothing to simply switch between one of a number of databases with differing data volumes up to 100s of GB. Of course, running behavioural tests against such a large database is likely to be a bit painful and just unnecessarily slow down test durations. Plus, if all developers run tests at the same time against the same database, there'll be clashes and tests failing all over the place. I think it's v poor practice for a tester to run against the dev database.
AdaTheDev
@AdaTheDev: That assumes the devs have PROD scaled hardware, which will not be the case for larger websites/apps. Our main database has 8GB of RAM and 8 cores, and that's just a middle of the road sized PROD DB. I find that having an integration DB with a proportionate data size works well. Code that is checked in gets built via CI. Automated tests against the integration DB monitor for performance degradation.
Eric J.
@Eric J: whats different to your answer and AdaTheDevs original answer or are you just asserting his answer?
AutomatedTester
@AutomatedTester: My first point is that there's a great chance the developers won't have the same hardware as actually deployed in PROD. If you have substantially lesser hardware with the same data volume in PROD, the results won't be realistic. My second point is that we automate performance impact tests as part of the continuous integration process.
Eric J.
@AdaTheDevm devs need to run tests on their queries as well as testers do. There are many ways to write badly performing SQL that is not noticable until you run it on a production volumn of data. The dev should be rrunning that test, it is far too late to find this out by the time it gets to the tester for goodness sakes. ANd if there are clashes and tests failing all over the place when multiple devs run tests then there will be clashes and failures all over the place when the code goes to prod and has a prod number of users. Databases need to be designed for concurrent usage.
HLGEM
@HLGEM - you've completely misunderstood what I'm saying. I have **not** said devs do not need to run tests on their queries!!! Of course they do. What I'm saying is as a dev, I'm in a much better position to tell if what I'm changing is actually having any real effect, if I'm isolated in a separate DB - with a whole team of devs and testers using the DB at the same time the water gets cloudy. Please re-read, carefully, what I've said and not said.
AdaTheDev
@HLGEM - if you still don't see what I'm actually saying, maybe I'll write up a blog post to clear up the misunderstanding rather than bog this question down.
AdaTheDev
@AdaTheDe - And I'm saying that you are more likely to go down the wrong path that way and create SQL that won't work in prod wasting everyone's time.
HLGEM
@HLGEM - How is a dev any more likely to create SQL that won't work in prod when working against their own copy of a database as opposed to when they're working against an instance of the database that all dev and testers use? Yes a dev has to keep their db schema up to date. You seem to have taken the wrong impression from my point of view, so we should just agree to disagree :)
AdaTheDev
Because SQL that works fine on a small subset of test data on a dev box will often time out on prod against the full dataset. This is why often devs write junk like cursors and correlated subqueries becasue they don't see how poor their choices are.
HLGEM
@HLGEM - I wasn't suggesting anything different. You're talking about having realistic data volumes, similar to prod, to test against and I did say in my first comment that this is needed and that I have a range of different size databases locally to test against. Never suggested you should develop against a small db. That whole point bares no relation to whether each dev should have their own db or not IMHO as that's a "data volume" issue not a "single db for all, or one per dev" issue. And to clarify, a dev's db doesn't have to be on their machine, they can all sit on one dev db server.
AdaTheDev
+1  A: 

I'm in the "one development database" camp.

Unlike traditional OO source code, the database is often going to have tables supporting multiple users' features. When multiple developers are going to make similar changes, you can have them work it out in advance or try to sync two build scripts. The problem with build scripts and migrations is that most situations are non-trivial. Want to dis-allow NULLs in the DB? - you need to decide what the data should be defaulted to and if the data should be populated from elsewhere. Need to refactor to normalize a table into two? - you need to decide how to assign the keys. And then with two users making a change to the same table...

That's not saying that it shouldn't be under source control, because it should.

Ultimately as you have more developers and more communication channels, you are going to want your database changes going through a development DBA - this allows the changes to be coordinated and avoids a lot of the problems with communication channels in a team - it turns the communication channels into a star.

In addition, if you limit yourself programming against an explicit database services layer like views and stored procs, your application developers are going to be well insulated against database changes and refactoring.

After a certain time into development, database changes become pretty manageable, since the changes to the underlying base table schema are fewer (although views and stored procs may remain volatile).

Cade Roux