Some developers love working with relational databases, and other developers can't stand to touch them. Either way - if your application uses a database, you have to treat the database with some respect. The database is as much a part of an application as the code and the models inside the software.
Here are three rules I've learned to live by over the years of working with relational databases.
1. Never use a shared database server for development work.
The convenience of a shared database is tempting. All developers point their workstations to a single database server where they can test and make schema changes. The shared server functions as an authoritative source for the database schema, and schema changes appear immediately to all team members. The shared database also serves as a central repository for test data.
Like many conveniences in software development, a shared database is a tar pit waiting to fossilize a project. Developers overwrite each other's changes. The changes I make on the server break the code on your development machine. Remote development is slow and difficult.
Avoid using a shared database at all costs, as they ultimately waste time and help produce bugs.
2. Always Have a Single, Authoritative Source For Your Schema
Ideally, this single source will be your source control repository (see rule #3). Consider the following conversation:
Developer 1: It's time to push the app into testing. Do we copy the database from Jack's machine, or Jill's machine?
Developer 2: Ummmmmmmm, I don't remember which one is up to date.
Developer 1: We're screwed.
Everyone should know where the official schema resides, and have a frictionless experience in getting a fresh database setup. I should be able to walk up to a computer, get the latest from source control, build, and run a simple tool to setup the database (in many scenarios, the build process can even setup a database if none exists, so the process is one step shorter).
How you put your database into source control depends on your situation and preferences. Any decent O/R mapping tool should be able to create a database given the mappings you've defined in a project. You can also script out the database as a set of one or more files full of SQL DDL commands. I generally prefer to keep database views and programmatic features (including functions, triggers, and stored procedures) as separate files - but more on this in a later post.
There are plenty of tools to help. Leon Bambrick has a long list (albeit one year old list) of tools and articles that can help, while Jeff Atwood gushes over the virtues of Visual Studio for Database Professionals.
3. Always Version Your Database
There are many ways to version databases, but the common goal is to propagate changes from development, to test, and ultimately to production in a controlled and consistent manner. A second goal is to have the ability to recreate a database at any point in time. This second goal is particularly important if you are shipping software to clients. If someone finds a bug in build 20070612.1 of your application, you must be able to recreate the application as it appeared in that build - database and all.
In a future post, I'll describe an approach I've used for database versioning that has worked well for many years of commercial development.
In the meantime, if you are looking for more database rule, then Adam Cogan and SSW maintain an excellent list.
Recently, I received a package from my local power company - Alleghany Energy. The package contained two 13-watt carbon fluorescent lamps (CFLs). In the Unites States, various organizations are trying to encourage people to replace their incandescent light bulbs with CFLs to save energy. In fact, recent U.S. legislation will effectively prevent the sale of incandescent bulbs after the year 2014 (unless the bulbs somehow become a lot more efficient by then).
Since the package didn't come with an invoice inside, I assumed my power company was giving away free bulbs. After all, Home Depot gave away 1 million bulbs during last year's Earth Day, so why shouldn't my utility company give away a few, too?
I was wrong.
It was quite a shock to Alleghany's customers when we found out we were being charged almost $12 for these two bulbs as part of the "Maryland Compact Fluorescent Light Energy Efficiency Program".
Outrage ensued. The outrage wasn't so much over the cost of the bulbs as it was about unmet expectations. We expected free bulbs because we weren't told about the cost. Alleghany Energy was either being sneaky, or was incompetent at communicating with their customers. If the power company was upfront about their plans, the story might have a different ending. Instead, there were rumblings about class action lawsuits and legal charges for unsolicited merchandise.
In the end, the power company decided to refund all charges and eat the 2.5 million dollars it cost to send light bulbs to 220,000 customers.
Moral of the story – communicate with the customer. This is why contemporary software development processes like Agile and XP have such a focus on customer communication. Unmet expectations make for angry customers and bad business.
Tafiti is a search visualization application built with Silverlight 1.0 and the Windows Live APIs. The Tafiti code is hosted on CodePlex under the Microsoft Public License (MS-PL), as announced by Marc Mercuri last month.
Tafiti highlights some of the pain inherent in Silverlight 1.0 development, too. Most notably the pain felt from a total absence of any infrastructure needed to build these reusable controls. Tafiti provides this infrastructure for inself. For example, a generate UniqueNames method:
I did a couple user group presentations this month on the new ASP.NET MVC framework. This post is a follow-up with all the links I promised to publish.
My first presentation of the year went to the Central Maryland Association of .NET Professionals in Columbia, MD. The turnout at the meeting was tremendous – I'd say well over 100 people were in attendance. It didn't hurt that G Andrew Duthie was giving away free copies of Visual Studio 2008 as part of the Microsoft Installfest, and the catered food was a lot better than the typical pizza-in-cardboard user group fare.
Best of all, I walked out of the meeting with a new 8 GB Zune 2 (thanks to a winning raffle ticket). Many people tried to tell me that it's not fair for the speaker to win the grand prize raffle, but I pretended not to hear them and then slipped out quietly before the mob turned ugly.
My second presentation went to the BaltoMSDN group in Hunt Valley, MD. Imagine going to a wine tasting and having a technical presentation break out. That's what BaltoMSDN is like, because they have their meetings in a private room at the Greystone Grill. Bacon wrapped sea scallops and Belgian beer on draft go well with code, I must say.
Let's see what the saving are for late adopters...
There is enough headroom now to pick up an extra 2GB of RAM and still put out less than $1500. I call this configuration the Ultimate Developer Rig +2***.
* Price includes mail-in rebate
** Drive is now deactivate, but comparable 500GB drives are still ~$120.00
*** Not to be confused with the Ultimate Rod of Dexterity +2 by you D&D nerds.
Igor emailed me for my thoughts about his SMTP server built with Windows Workflow. A link for the source code is at the bottom of his post. As Igor points out, WF is well suited to solve more than just business problems, and I think his project is an excellent and practical demonstration of building state machines in WF.
Matt Winkler is looking for feedback on refactoring workflows. Personally, I'd like to see some additional renaming support at the property and activity level that can auto-magically patch up declarative activity bindings.
Many moons ago I wrote a post on unit testing custom activities in WF. I've stuck to this approach over the last year, and I'm still looking for something better. A couple new posts on the topic have come up recently. YooT – Unit Testing custom Workflow Activities. Damir Dobric – Unit Testing: How to create activity type from XOML. Andreas Erben's – Unit Testing: Simple approach to Activity testing and improving the XOML loader.