Archive for February, 2007

This post is going to be longer than it needs to be. If you want to skip the backstory, just jump down to the section labeled How To Build XNA Games With Regular Visual Studio.

I originally started college as an Electrical Engineering major. That didn’t happen because I had affection for EE, I just happened to be good at understanding that sort of stuff and I figured the degree would get me a good paying job.

Then my mom bought a 486 DX2/66 and installed X-Wing from LucasArts. I was enthralled by the game and what computers were becoming capable of doing. About a year later I had to take an intro to programming class as part of my base curriculum as an Electrical Engineering major, and I was hooked. I instantly “got” programming. While people in my class floundered to understand the concept of a fixed array I was trying to figure out how to make Tie Fighters appear on my screen and blow up. I switched my major immediately to Computer Science.

A couple years later I tried to recreate the isometric engine from Diablo with (at the time) the latest version of DirectX (6). I was mostly interested in learning the API and graphical programming, but building that engine also taught me a lot about isometric games, 2D sprites, drawing algorithms, optimization and things like the “A-Star” algorithm (which I used for pathfinding so my little barbarian could walk around the screen).

I desperately wanted to be a game programmer. But life happens, and we make choices based on things that are really important to us. I knew what it would take to be a game developer; I’d have to move to a bigger city, my wife would have to leave her family and the job she liked, and I’d have to start at the bottom and work my way to the top. I wasn’t certain my marriage would survive such a thing; my wife is very attached to her family and our living location. With everything else that goes on in life it just wasn’t the kind of decision I could make. And so my career as a game developer died quickly and with little fanfair.

XNA Appears….

A week ago I learned that Microsoft has released a new framework called XNA. It’s designed to make developing video games for the PC and XBox 360 easier, especially for “hobbiest” developers. I’ve spent the past week examining XNA and working through some very good tutorials on the internet. XNA is a neat thing. It has completely renewed my interest in game programming.

There’s just one problem: Currently, the XNA Game Studio Express only works with Microsoft’s Visual Studio Express. You cannot write XNA Games on Visual Studio Standard, Pro or Team System. Joe Nalewabau of the XNA team explains the reasons for this decision.

This bothered me on a few levels.

My biggest gripe is that you can’t install a lot of 3rd party tools with Visual Studio Express, like ReSharper. I can’t imagine any professional developer today who wouldn’t have a tool like ReSharper plugged into their IDE. I was blown away when I read Dave Weller’s blog, the Game Developer Community Manager for Microsoft, and found out he only has Visual Studio Express installed on his machine.

I’ve had ReSharper installed for several months now at work, and like the wheel, television and the internet, I simply can’t live without it. Writing code without ReSharper is like trying to watch TV without a remote control, or trying to drive a vehicle without power steering, or trying to plan a cross-country trip withoutYahoo Maps. Sure, you can do all of those things given enough time, patience and Advil, but why?

The other major gripe I had was that I didn’t know this before I went out and spent $250 on Visual Studio Standard edition. As soon as I found out Visual Studio Express wouldn’t handle ReSharper I had to go get a real IDE. It arrived today in a nice Amazon.com box (side note: can Christmas compete anymore? I get more thrill from the Amazon.com boxes that arrive at my house than I do from Rudolph wrapping…) But it wouldn’t open or compile my XNA game.

But that doesn’t mean you can’t make it work.

How To Build XNA Games With Regular Visual Studio



The culprit here is the .XNB file. For every piece of “content” you need to load in your game, you need a corresponding .XNB file. When you compile a XNA game with Visual Studio Express, the .XNB file is created. Without it your game will throw an exception when you try and run it. Compiling with any other version of Visual Studio won’t do the trick, so we have to generate those files in another way.

First thing you have to do is install Visual Studio Express. Yes, you still have to install it on your machine, mostly because XNA utilizes some aspect of the .NET Framework that deploys with the Express edition of VS. But that doesn’t mean you have to be handicapped by that IDE.

Next thing you need to do is download the XNA ContentBuilder, a project on CodePlex. It comes in source or msi installer versions. The XNA Content Builder is what we’ll use to make our .XNB files.

Go ahead and create a Windows project in Visual Studio Standard, Pro, or whatever version you enjoy. Reference the XNA libraries in your project (Microsoft.Xna.Framework & Microsoft.Xna.Framework.Game). Write your XNA game code. Riemer’s XNA Tutorials are a good place to start.

After you’ve added the necessary content files to your game project, open the XNA ContentBuilder application and set the Intermediate, Output and Root directories to point to the correct directories of your game build (hint: the Root and Output directories should probably point to your bin/Debug directory). Then use the “Add” button to add the content files to the XNA ContentBuilder project. Hit the “Build” icon on the toolbar and the XNA ContentBuilder application will build a .XNB file for each content file added.

Bingo – you’re good to go.

Go back to Visual Studio Excellent Edition (whichever version you’re using) and build/run your game. It should work.

The whole process is painless and will only take a few minutes. If you’re like me and can’t stand the thought of having to code with an inferior IDE like Visual Studio Express, have no fear. You can still write XNA code with your powerful Godmode IDE thanks to the nice folks who wrote the XNA ContentBuilder project on Codeplex.

Happy game building!

Brad Wilson and James Newkirk posted a few thoughts today, and a question, concerning code coverage. Brad specifically asks:

Are you on an agile team? Do you do code coverage? What does it mean to your team?

We use code coverage, but not at a regular interval like I’d like us to. Part of the problem is that we still can’t get CruiseControl.Net to work. After a couple of weeks fussing around we finally managed to get it to work with Vault, but now that it correctly gets the latest source code from Vault we can’t get it to fire off the build. Go figure.

That said, we do try and make ourselves aware of our code coverage.

I like James’s analogy to a barometer. He says:

The answer lies in a metric that can be used to predict the weather, barometric pressure. Today, weather.com says the barometric pressure in Seattle is 29.66”Hg and falling. More important than the absolute measurement is the trend: it tells you that the overcast and drizzling rain outside is going to get worse, not better. The two pieces of information – value and trend – are used to predict what will happen next. The same can be said for code coverage. You can determine the relative health of your tests by using the value and the trend to determine the appropriate action. That’s the important bit: code coverage gives you relative measurements against itself, not an absolute measurement against a target value.

I agree. Somewhat.

While people may look at code coverage as a metric, I look at it more as a tool. I like to use code coverage as a way to help me ensure that I’m writing proper unit tests. When I look at the analysis for a class under test and find a method uncovered, or an else statement uncovered, that prods me to think of a unit test to exercise that code. And that prodding – that process of thinking about how to test something – is the real value of code coverage (at least to me). Because nine times out of ten, that process causes me to rethink that particular line of code, or that method. It makes me question. Do I really need that else statement? Is there a refactoring I can do to get rid of it? Is there a better way to write that method? Is this a method that doesn’t belong in this class to begin with?

I like tools, techniques and coworkers that make me question my code writing abilities. I like it when a tool makes me question my design. Code coverage is a great way to initiate that process, and to me that’s its greatest benefit.

When it comes to actual coverage numbers, I prefer to shoot for 100%. But I have to qualify that: 100% for classes that matter. James brings up the same point when he writes:

It is inevitable that code is written which isn’t covered by a unit test. A few examples of acceptable code without tests might include: web service wrappers generated by Visual Studio, views in a Model-View-Presenter system, and code for which failure is only possible because the underlying platform fails (like helper methods that pass default values into more complex .NET CLR methods).

I don’t really care about a number like 75% code coverage for the entire solution file. That doesn’t tell me anything useful. I care about 100% for a class that matters. I expect presenters and use case classes (workitems, etc.) – classes that do business logic work – to be tested thoroughly and have 100% coverage. If they don’t, then there has to be an explanation, and usually it’s because someone forgot to write a test, or because the design is bad and needs refactoring.

So to answer Brad’s question: What does it mean to our team? It is another “entity” watching our backs, ensuring that we’re doing all we can to write the best code we can. It’s like calling pair programming “real time code review”. Code coverage for us is a way to guide us, to let us know that we’re really thoroughly testing the important classes in our architecture, and we feel secure in knowing we’ve covered all our bases.

It’s another pair of eyes, in a way. And I like that.



For a long time I thought this behavior was unique to my computer. But a few days ago a coworker informed me that his version of Visual Studio is doing the same thing. It seems that over time, for whatever unexplained reason, the toolbox icons start to go whacky.

What’s weird is that the icons for the Infragistics controls don’t have this problem. Same goes for a few other folders in the toolbox. But the Common Controls and some other control sections are affected.

The icons change every few weeks and I haven’t been able to determine a trigger yet. Anyone else had this prroblem?


Note: The code has been updated. You should download the Version 2 code here. Links on this website have been changed to point to the new code.

CabSample_v2.zip

Note: I’ve included the complete source code in the zip file attached to this post. It is a complete, working CAB application built with the SCSF. Full source for the DialogBox class and the PopupBox class are included. The unit tests are written with NUnit 2.2.8.

There are two modules: (A) MessageBoxModule and (B) PopupBoxModule.

The MessageBoxModule makes use of a standard MessageBox for one feature and a standard Windows Form dialog for another feature. When you run the unit tests you’ll be interrupted by MessageBox and DialogBox popups.

The PopupBoxModule makes use of my custom PopupBox class (which mimics a MessageBox) and a custom DialogBox class for CAB. When you run the unit tests for this module no popup windows will appear, yet the tests will pass and the data will be correct.

The MessageBox can be a handy little device in a Windows Forms application. It’s cousin, the Dialog box, can be even more handy. There are a lot of occassions when you need to prompt the user for a yes/no type of answer, or notify them of some important event, or get some trivial piece of data from them before proceeding.

Unfortunately, the MessageBox and Dialog box are nightmares when it comes to unit testing. You don’t want to trigger a MessageBox popup when you’re trying to run automated unit tests against your Presenters, or you end up with this situation:

This problem only becomes compounded when you consider that in the Component UI Application Block you typically use a WindowWorkspace to show Dialogs. This is a much different way for showing popup windows than the typical Windows Form methodology which involves creating a Form control and calling ShowDialog() on it. The WindowWorkspace doesn’t return a DialogResult, for one thing. For another, you’re using a UserControl instead of a full-fledged Form control.

So how can we get the functionality that we’re used to using with classic Windows Forms technology and still utilize the CAB framework, all the while appeasing our desire to utilize Dependency Injection so that we can easily mock objects and input for use in automated testing?

I’ll show you my solution.

Injecting A DialogBox

The first thing to understand is what we’re trying to accomplish: We want to be able to inject a MessageBox into a Presenter or other WorkItem. The reason we want to inject the MessageBox is twofold: (1) so we can control the input and output of the MessageBox object in a unit testing scenario and (2) so we can prevent it from being displayed when the calling code executes. Preventing the MessageBox/DialogBox from appearing when it is called is the key to making things work in a unit testing environment like NUnit.

There’s one other glaring problem when attempting to emulate a MessageBox/DialogBox in CAB: There is no DialogResult when you use a WindowWorkspace.

Making the MessageBox or DialogBox close is easy enough if you’re using the Smart Client Software Factory; you can just call Presenter.OnViewClose() and the framework will handle the rest. The WindowWorkspace will close itself and the SmartPart. But that actually causes the Workspace to attempt to Dispose() of the SmartPart, which is not what you want in a Dialog scenario. What you really want to accomplish is a two-step process: First verify that the user has selected a specific button (OK/Cancel or the like) which is typically done with the DialogResult, and then fetch output off the Dialog object. To do that you need a Dialog that hangs around after the WindowWorkspace has closed itself. This means hiding the MessageBox or DialogBox instead of having the Workspace close it.

But how do we have a Dialog tell the Workspace to hide it? That’s where our DialogBox base class comes in.

The DialogBox Base Class

The first part of the solution is the DialogBox base class. It is an abstract class derived from a UserControl and implements an ISmartPartInfoProvider interface. This base class is responsible for the difficult part of this solution: handling button clicking and setting a DialogResult.

Normally, when you create a Dialog object in .NET you use as a Windows Form, create your buttons and set the DialogResult property on those buttons. Then, when a user clicks on one of those buttons the DialogResult for the Form gets set.

Our base class, DialogBox, does the same thing when you make a call to the InitializeClickHandlers(). It loops through the Controls of the subclass and looks for Button objects. When it finds one, it wires up an EventHandler to that Button’s Click() event. This is what the DialogBox base class will use to help send a message to the WindowWorkspace that a Dialog button has been clicked and the WindowWorkspace needs to Hide() the Dialog UserControl.

The WindowWorkspace

The next step is to augment the WindowWorkspace. The Smart Client Software Factory provides a subclassed version of the standard WindowWorkspace which has a couple enhancements to it. We’re going to add some code to the Show() method and include one additional method:


code in Show():
if (smartPart is DialogBox)
{
    DialogBox box = (DialogBox)smartPart;
    box.OnDialogButtonClick
        += new DialogBox.DialogClose(DialogClose);
    box.InitDialog();
}

add this method:
private void DialogClose(Control c)
{
    OnHide(c);
}


The Subclassed DialogBox

Once we’ve altered the WindowWorkspace and built our base DialogBox class, it’s time to actually use it. We start by creating a new UserControl and having it subclass from DialogBox instead of UserControl. Add buttons and controls, making sure each button has a DialogResult property set.



In the code for the dialog we have to make a couple alterations:


    [SmartPart]
    public partial class StringFetchDialog : DialogBox
    {
        public StringFetchDialog()
        {
            InitializeComponent();
            InitializeClickHandlers(this);
        }

        public string String
        {
            get { return _stringTextBox.Text; }
            set { _stringTextBox.Text = value; }
        }

        public override void InitDialog()
        {
            base.InitDialog();

            _stringTextBox.Text = string.Empty;
        }

    }

Notice the bolded lines of text. InitializeClickHandlers is a base class method that is used to wire-up the Click event for any button on your Dialog. This saves you from having to perform the DialogResult logic on every Dialog you make. The other thing we’ve done is override the DialogBox’s InitDialog() method. This method gets called by our altered WindowWorkspace when it shows a Dialog. You should perform any initializating on your Dialog in this method. In this case we’re setting the TextBox value to String.Empty so that each subsequent time the dialog is shown you do not have the previous text still in the field.

Now our dialog is ready to use.

Presenter Injection

Typically you’ll have some Presenter object or WorkItem that needs to interact with the user in some modal way. Your DialogBox is a dependency that your Presenter is relying on, so you need to provide your Presenter with a DialogBox either through constructor-based injection or property-based injection. Here is a snapshot of the Presenter code:


private IStringService _service;
private PopupBox _popupBox;
private StringFetchDialog _dialog;

[InjectionConstructor]
public PopupBoxViewPresenter(
[ServiceDependency] IStringService service,
[Dependency(Name = SmartPartNames.PopupBox)] PopupBox popupBox,
[Dependency(Name = SmartPartNames.StringFetchDialog)]
   StringFetchDialog dialog)
{
    _service = service;
    _popupBox = popupBox;
    _dialog = dialog;
}

Take note of the use of the [Dependency] attribute here with a strong name on the StringFetchDialog. By default, ObjectBuilder will look for a StringFetchDialog with the same name in the hierarchy of WorkItems. If it cannot find one it will create a new one, much as if you had specified:


[Dependency(NotPresentBehavior = NotPresentBehavior.CreateNew)].

This behavior works to our advantage.

In our unit testing class we will build a new StringFetchDialog and add it to our TestableRootWorkItem prior to adding the Presenter under test. This will cause the Presenter to get a reference to our prebuilt StringFetchDialog which we can manipulate for testing purposes. However, in the real WorkItem we will not create a StringFetchDialog. Instead, we’ll let the ObjectBuilder do it for us when it can’t find it.

The Unit Test SetUp


[SetUp]
public void SetUp()
{
    _workItem = new TestableRootWorkItem();

    _dialog = _workItem.SmartParts.AddNew
        (SmartPartNames.StringFetchDialog);


This is the beginning of our SetUp method in our TestFixture. Notice how we’re adding a new StringFetchDialog and maintaining a reference to it locally in the TestFixture. This allows us to do the following in a test:


[Test]
public void AddString_UserSelectsOK_AddsStringToView()
{
    _dialog.String = "Enchant";
    _dialog.DialogResult = DialogResult.OK;
    _presenter.AddString();

    Assert.AreEqual(1, _view.AddNameValues.Count);
    Assert.AreEqual("Enchant", _view.AddNameValues[0]);

}

Here we set the expected DialogResult and data properties. Our presenter has been injected with this dialog so whatever values we set it will make use of. This allows us to control the state of the DialogBox for testing. The question you may be asking now is, “How do you prevent it from being shown during a unit test?”

Preventing Dialog Display During Unit Testing

There’s two parts to this solution. The first part is to create a MockWorkspace that does nothing when Show() is called. We can do this by implementing the IWorkspace interface.


class MockWorkspace : IWorkspace
{
    public void Show(object smartPart)
    {
    }

    public void Show(object smartPart, ISmartPartInfo smartPartInfo)
    {
    }
}

The second part is to use this Workspace instead of a real Workspace in our TestableRootWorkItem:


[SetUp]
public void SetUp()
{
    _workItem = new TestableRootWorkItem();
    _workItem.Workspaces.AddNew
        (WorkspaceNames.PopupBoxWorkspace);
    _workItem.Workspaces.AddNew
        (WorkspaceNames.DialogBoxWorkspace);


Now when we run our unit tests the StringFetchDialog will not popup on the screen. This is the behavior we’re after.

Using The Dialog In A Presenter

So we have a DialogBox that works with CAB and doesn’t popup when we unit test. How do we actually call this code?

First, I’ll show you the Windows Forms way, which we’re all pretty familiar with:


StringFetchDialog dialog = new StringFetchDialog();
if(dialog.ShowDialog() == DialogResult.OK)
{
     _service.AddString(dialog.String);
}

The new way isn’t much different:


WorkItem.Workspaces[WorkspaceNames.DialogBoxWorkspace].Show(_dialog);

if (_dialog.DialogResult == DialogResult.OK)
{
    _service.AddString(_dialog.String);
}

The main difference is that we don’t have to new-up a Dialog each time we want to use it. Instead, our Presenter has been injected with a StringFetchDialog already, and we juse reuse it each time we need to query the user. Instead of making a call to ShowDialog() we ask the Workspace to show it.

The PopupBox

The other thing I’ve written is the PopupBox class, which is a special implementation of the DialogBox base class designed to mimic the behavior and usage of the standard MessageBox class. The main difference between it and a MessageBox is that the PopupBox is not static. Like the StringFetchDialog it is an instantiated class that is injected into the Presenter. Since it’s a fairly common control it may be best to add it at the Shell level, so all WorkItems have access to it.

MessageBox Way

In the sample project I use a MessageBox to query the user to determine if they really want to change the background color of the form. The calling code looks like so:


DialogResult result =
    MessageBox.Show(
    "Do you want to change the background color of this form?",
    "MessageBox",
    MessageBoxButtons.YesNo,
    MessageBoxIcon.Question);

   if (result == DialogResult.Yes)
       View.UpdateBackgroundColor(true);
   else
       View.UpdateBackgroundColor(false);

The CAB-friendly version looks very simliar:


_popupBox.Initialize(
    "Do you want to change the background color of this form?",
    "Change Background Color",
    MessageBoxButtons.YesNo,
    MessageBoxIcon.Question);

    WorkItem.Workspaces[WorkspaceNames.PopupBoxWorkspace]
        .Show(_popupBox);

    if (_popupBox.DialogResult == DialogResult.Yes)
        View.UpdateBackgroundColor(true);
    else
        View.UpdateBackgroundColor(false);

Instead of making a call to MessageBox.Show() you make a call to PopupBox.Initialize(), passing in the parameters you want to format the box correctly.

Note: The MessageBox class has several overrides and many parameters you can pass to customize the box when showing it. I’ve only provided overloads for the four most common parameters: text, caption, buttons and icon.

These two classes are contained in the Infrastructure.Library project of the CabSample application attached to this post. To use these objects in your own project you can just copy and paste them. You’ll also need to adjust the WindowWorkspace accordingly, or copy the class from my file.

With these two objects in hand, the PopupBox and DialogBox, you can get around one of the major hurdles in unit testing CAB applications. Prior to having these objects I would have to skip any subroutine that used a MessageBox or DialogBox. That’s disappointing, because I like to have 100% code coverage in the classes I’m testing. I especially like to be able to simulate user input for Dialog situations. Now I can do that.

Enjoy.

CabSample_v2.zip

A couple days ago Jeremy Miller, who might have the best .NET blog on the internet, wrote about the evil of composite keys in database design. Jeremy asks an honest question at the end: why are composite keys so prevalent in legacy databases?

The answer is pretty simple and relatively boring: database developers with educational backgrounds in Relational Calculus and Relational Algebra were just designing databases properly according to the standards and guidelines set forth by E.F. Codd. The issue Jeremy brings up isn’t really “why use composite keys?” but “why does writing persistence code with composite keys have to suck?” This is especially relevant today as more and more development gets done with O/R mappers, and O/R mappers seem to be written with an expectation that your database contains auto-incremented primary key values.

All of this brings forth the really important issue (in my eyes), and that is this: a lot of database developers are charged with designing databases and they don’t understand the difference between a primary key and a surrogate key, and they don’t understand what criteria you use to actually choose a primary key.

A perfect example of this is captured in an article written by Josh Berkus, a lead developer on PostgreSQL. In the article he transcribes a couple of chats he had with database developers who were querying him for solutions to their problems.

agliodbs: What’s the key for “sessions”?
newbie2: it has an “id” column
agliodbs: Yes, but what’s the real key? Which columns determine a unique row?
newbie2: I told you, the “id” column. It’s a primary key and everything.
agliodbs: That’s not going to help you identify duplicate sessions. You need another key … a unique constraint on real data columns, not just an “id” column.
newbie2: no I don’t
agliodbs: Good luck with your problem then.

Josh continues on with the article, describing why this ignorance seems so pervasive:

Inevitably, practices which are “necessary evils” tend to become “pervasive evils” in the hands of the untrained and the lazy. Not realizing that ID columns are a pragmatic compromise with application performance, application developers with a shallow grounding in RDBMSes are enshrining numeric IDs as part of the logical and theoretical model of their applications. Worse yet, even RDBMS book authors are instructing their readers to “always include an ID column,” suturing this misunderstanding into the body of industry knowledge like a badly wired cybernetic implant.

That explains a lot. You see, I’ve ran into the same thing in my career – I’ve had discussions with developers who tell me that they’ve been instructed to always include the id field first when designing tables because it is the primary key. I couldn’t understand what responsible database person or author would instruct a person to do such a thing. Then I read Josh’s article and it became clear: you don’t have to be responsible to write a book, you just have to be good enough with words to get published. The accuracy of the information isn’t what determines whether your book gets out or not.

That’s disappointing. Our job as a software developers is already tough enough; we spend our days solving problems, learning new technology and trying to make our customers happy. To top it off, we have to deal with people feeding us misinformation at a technical level. That can’t be good.

So What Is A Surrogate Key?

To get back to the issue, a surrogate key is essentially a placeholder for the real primary key.

Every table has to have a primary key; a combination of attributes (columns) that determine uniqueness. Databases are all about storing data reliably, and that means keeping duplicate data out of a table. There shouldn’t be two Dave Smith’s in your database if you only have one working for you (you wouldn’t want him collecting two paychecks would you?)

To avoid a table containing duplicate entries we turn to the primary key. A primary key can actually be one of many candidate keys. A table may have one or more candidate keys, each of which can uniquely identify a tuple (row) in the table.

Take, for instance, the case of a movie table. It contains movie names, year released, and director name.

Movie Director Year
Star Wars Episode 1 : The Phantom Menace George Lucas 1999
Star Wars Episode 2 : The Clone Wars George Lucas 2003
Psycho Alfred Hitchcock 1960
Psycho Gus Van Sant 1998

Movie name by itself is not a good candiate key, because as we can see, Alfred Hitchcock and Gus Van Sant each directed a version of “Psycho”. However, movie name + director name is a decent candidate key because we can be fairly sure that no director is going to direct the same movie twice. Another, possibly better candidate key is movie name + year released, since we can be fairly certain that no movie with the same name will be released in the same year. A third candidate key would be all three fields, and provides the best assurance of uniqueness.

However, the difficulty of working with a primary key composed from the natural attributes of the table is that it can be cumbersome to write persistence code. Also, composite primary keys make for large foreign keys in releated tables, since all of those attributes have to be copied.

The solution then is a “surrogate key” – a numeric key (here called “ID”), typically auto incremented, that can be used as a placeholder to the real key, providing us with a table that looks like so:

ID Movie Director Year
1 Star Wars Episode 1 : The Phantom Menace George Lucas 1999
2 Star Wars Episode 2 : The Clone Wars George Lucas 2003
3 Psycho Alfred Hitchcock 1960
4 Psycho Gus Van Sant 1998

The problem with a surrogate key is that some developers actually start to think that the surrogate is the primary key. They insert this value before determining the candidate keys and before they know if their table structure needs to be altered to include, or exclude, attributes (a sign that a table isn’t well designed is when there are no obvious candidate keys – that means there’s not enough information in the table to determine uniqueness).

All of this brings me back to one comment on Jeremy’s blog post:

Life is so much easier with surrogate keys. You can always make unique constraints where it’s necessary.

I have to ding Jeremy a couple of points for that comment. What he should have said was: Life is so much easier with surrogate keys. But you must always make unique constraints on your primary key before adding a surrogate.

Surrogate keys don’t exist by themselves; they require the presence of a real primary key in order to be useful. Without unique constraints the other attributes in the table provide no help in determining uniqueness.