Good Habits

Coding naked.

Me, circa 1992. This is not the most embarrassing picture of that time period.

Me, circa 1992. This is not the most embarrassing picture of me from that time period.

True story: when I was in college, I was the lead singer (if you can call it that) for a goth rock Christian rave band called Sandi’s Nightmare.  I had zero musical talent, and relied solely on the strengths of my band-mate (Brad; you still rock); however, while my singing ability was dubious at best, I was pretty theatrical.  We had a total of 3 awesome shows before we moved on to other things, but it was a lot of fun while it lasted.  Our biggest hit was a cover of Lust Control’s Dancing Naked, a fantastic little number about David’s celebration of the ark returning; his passion and excitement overwhelmed his embarrassment.

I promise, I’m not making this stuff up; it was pretty edgy for the Bible belt of  Northeast Louisiana in the early 90’s.  I mean, I had an earring and everything.   The point of this post (besides reveling in my musical abilities and tastes of 25 years ago) is that sometimes we just need to be naked.

Let me explain; I made choices that in hindsight are difficult to defend (like my haircut). However, there was a reason for the choice at the time, and even though it may not have been the greatest idea, I’ve learned something from every experience I had.  While there are things that I would do differently if given the choice and knowledge I have today, I don’t regret many things.  That’s what the metaphor of nakedness is all about; being open and honest about not only your successes, but your choices along the way.  You can’t change the past, but you can learn from it.

Becoming a Naked Developer

I’ve spent most of my professional career as a SQL developer working for one company (13 years in November);  I was the first developer hired by that company, and my job was to build an integration platform transforming syslog data into reports, all on a shoestring budget.  I strung something together in a couple of weeks, and in the first month, I took a process that normally took two weeks to do by hand down to a day; my boss threatened to kiss me (I was flattered, but declined).

Was it pretty (the code, not the boss)?  No.  Was it successful?  Yes.

Fast forward a couple of years to 2004: I’m a member of small team building a solution to analyze more data than I’ve ever seen in my life (terabytes of data from firewalls and Windows machines); we had to import and semantically normalize data in near-real-time.  We built a solution using DTS, and then moved it to .NET and MSMQ.

Was it pretty? No.  Was it successful?  Yes.  Part of that code is still being used today, and my company has thrived off of it.  We were acquired by a larger company 8 years ago, and we’ve kept moving forward.

Every few years, we’d talk about doing a rewrite, and we’d bring in some outside expertise to evaluate what we’ve done and help us come up with a migration plan.  Some consultant would come in, look at what we did, and shake their heads at us.  Each time, we (the remaining original developers) would attend meeting after meeting as our code was dissected and judged; we sat naked (metaphorically) in front of a team of experts who told us everything that was wrong with the choices that we made.  At the end of each visit, we’d regroup and complain about the agony of judgement. In all honesty, we would have done things differently, given our current experience (and modern technology).  However, the simple truth is: we won the day.  We continue to win the day.

During some of these initial code reviews, the consultants were jerks.  They’d spend a lot of time bemoaning how horrid everything was; I’d be embarrassed and try to explain what I would have done differently if only I had the time.  The consultants would eventually propose some complex solution that would cost hundreds of thousands of dollars to implement.  Our company would consider the offer, stick it in a file somewhere, and we’d keep on keeping on.   Clunky code that works is better than expensive code with the same outcome.

Over time, I learned to live with the embarrassment (as you can tell from this post); I started listening to what the consultants would say and could quickly figure out which ones had good advice, and which ones were there to just be seagulls.  People that focused on solving the immediate problems were much easier to talk to than the people who wanted to rip out everything and start over.  Don’t get me wrong; sometimes you need to start over, but there is  a cost associated with that decision.  It’s usually much easier to start where you are, rather than trying to reinvent the wheel.

What’s my point?

First and foremost, don’t dwell on your past mistakes.  If you can honestly say that you built something that worked within the constraints of the time period, no matter how clunky or silly it seems now, then it was the right decision.  Working software works.  Laugh at it, learn from it, and let it go; repair what you can, when you can, but keep moving forward.

Second, learn to code naked.  Whatever it is that you’re trying to do at the moment, share it.  Open yourself up to code review, to criticism; exposure brings experience.  Granted, you’ll meet some seagulls along the way, but eventually, you’ll figure out who’s there to help you grow as a developer.  Foster those relationships.

Third, encourage people to grow; recognize that the same grace you desire for your coding mistakes is applicable to others as well.  Be kind, be gentle, but be honest; seek to understand why they made the design choices they did, and be sensitive to the fact that if it works, it works.  Sometimes we get caught up on trying to figure out the right way to do something, and ultimately end up doing nothing because it’s too difficult to implement it according to the textbook.

Life is too short to not enjoy what you do; try to share that joy without embarrassment.

THIS is the most embarrassing picture of me from that time period.  I thought being an actor was the best way to meet girls… Yes, those are tights I am wearing…

 

 

 

What’s your mantra?

I worked really hard to line up the window so I could get that nice illumination look.I’ve been busy lately making the shift from “hands-on engineer” to “hands-off manager”; it’s been tough, because I’m not accustomed to stepping away from a problem and letting someone else figure it out.  Even though I’ve got an education background, and have been (inconsistently) involved in technical communities helping other people solve problems, I’ve never had to balance the responsibility of making sure that a job gets done with the responsibility of allowing someone to “learn from their mistakes”.  It’s harder than I thought.

As part of my management training, however, I’ve been focusing on laying out principles and guidelines rather than specifics; for example, instead of saying something like:

We need to make sure that John Smith has limited access to that database; can you do that for me?

I’m trying to say something like:

Our databases need to be secure, and that includes differentiation in access based on job roles.  Can you verify that all accounts are set up using that model?  If there are exceptions, can you document why?

The idea is that a) I need to trust that the people that work for me know how to do their jobs, and b) I need them to start aligning their practices with the principles that I think should drive our work.  I realize that last statement sounds a bit tyrannical, but in reality, I trust my team to help me develop those principles.  However, it’s my job to provide the direction, and their job to keep the boat afloat.

As part of this exercise, I’ve begun to realize that I’ve had a worldview for several years that I’ve always fallen back on when it comes to solving problems.  I’ve never thought of it as a mantra before, but the truth is that the following statement sums up my approach to most problems.

Simple is best.

When I encounter a challenge, and am forced to figure out a solution, I always fall back on the thought that a simple solution is usually the best one.  When I’m face with deciding between option A and option B, I’m usually going to lean toward the one with the fewest moving parts, even if it doesn’t address every possible outcome.  I’m a big fan of things like the 80/20 rule, and Occam’s Razor; it’s far easier for me to tackle problems in bite-sized chunks.  It’s the first principle by which I evaluate any solution that my team presents; if it’s not simple, it’s not manageable in my opinion.

Not everyone I work with is oriented toward simplicity; one of my best friends (I’ve worked with him for 9 years) often chooses beautiful and thoroughly complex solutions to problems.  I don’t know if could express what his mantra is, but I’d bet it would involve something about slicing and dicing problems into small pieces.   I also work with another guy who loses me in jargon in every discussion; he’s very passionate about writing code that covers every scenario, even if it takes 6 months to a year to do so.  I have a tough time thinking like that.

Mantra’s can be positive or negative.  For example, two of my former managers had different mantras that they relied on; one manager used to say:

Never make a person do what a computer can do for them. 

That helped guide us when making a decision on work priorities; if you’ve got someone cutting-and-pasting information from your application so that they can send an email, and they have to do that on a consistent basis, then you probably need to write some sort of hook into your application to let them use their email program from your app.  If you’re hiring staff because of the uptick in workload, then you should probably figure out ways to reduce the amount of work using computing power.

The other manager (different company; different time in my career) used to chant:

Whoa, whoa, whoa; that’ll delay the project.

which made us all think that that the project was more important than actual details.  It was a joke; the slightest interruption or shift in perspective would tip the entire apple cart.  His inflexibility was legendary, and ultimately led to the loss of his entire staff (before he was eventually sent packing).

What’s your mantra? Do your teammates or employees know it? Does it contribute to the work effort, or has it become a tired joke among your colleagues?

Three Myths about Agile Development

I recently attended Microsoft Tech Ed in Atlanta, and while there wasn’t much new being announced about SQL Server (I had heard about many of the features for Denali at PASS Summit 2010), I did find myself drawn to several sessions regarding Agile principles and development.  My shop has been using the Scrum method for about 2 years now, and it was nice to have a refresher.  I also participated in (and overheard) a lot of conversations about Agile methods, and it made me realize two very important things:

  1. Many people who claimed to be using Agile methods had never read the Agile Manifesto, and
  2. There are several misconceptions in play regarding Agile development.

The point of this blog post is dual-fold; first I want to encourage you to read the Agile Manifesto.  If you’ve read it before, read it again.  And then, read it a third time (it’s short, so easy to read).  Done that?  Good, because here’s the crux of my argument:

If you want to do Agile development, you must adhere to the principles of the Agile Manifesto.

It’s simple, really; you shouldn’t claim to be a SQL Server developer if you’ve never written a T-SQL statement.  You can’t call yourself a cubist if you haven’t studied the works of Picasso.  You shouldn’t claim to be doing Agile development if you don’t adhere to the principles of the Agile Manifesto.

And, that leads us to the second part of this post; I believe that lots of us think we’re adhering to the methods and principles of Agile development, but there are at least three basic myths about Agile development which keep development teams from being as agile as they can be; here’s my take on them:

Myth 1: Daily meetings with business people are an impediment to rapid development.

I actually got into a fervent discussion with gentleman at TechEd about this subject during a Birds of the Feather Session on Scrum.  he claimed to be a Scrum Master for 6 teams (including several overseas), and that he barred business people from entering into the daily standup in order to keep them from dragging the meeting astray.  I think that’s wrong, and here’s why (from the Agile Manifesto principles):

Business people and developers must work together daily throughout the project.

While it’s true that the daily standup in Scrum need not be the daily interaction, it makes sense that business people LISTEN (but not INTERACT) in that meeting in order to understand on what issues the development team is working, and how those issues interplay with each other (Note: scrum calls this the chicken and the pig; business people need to know what’s going on across the development team, but shouldn’t be involved at this point.  However, the daily standup can spur additional conversations).   If your development team chooses to have a daily standup without business people, your team members MUST interact with business people in order to handle changing requirements; they must also communicate at that time what the priorities of the development organization are, and why this particular project is not progressing because some other project takes priority.

Agile development depends on the interaction between developers and business people; to isolate half of the team from the other half of the team will cause disruption to the process.  That leads us to our second myth:

Myth 2: Your development team can be agile in a vacuum.

I call this the Agile-Waterfall mindset; your business organization is separate from your development team.  Your developers are practicing some form of Agile development, but the organization is used to handing off a set of requirements to the developers, and then having them return a product at periodic intervals.  Think of this as the complement to Myth 1; Business people aren’t deemed to be an impediment, but the organization hasn’t endorsed agile development throughout.  Daily meetings with developers aren’t deemed to be a priority by the business people; the organization has developed a culture of handing off responsibilities, and expecting them to be fulfilled without daily guidance.

By definition, you can not have an agile team without input from both developers and business people.   If you want to respond to changing requirements (as frustrating as that can be to developers), you must have input from business people as soon as those requirements change.  Again, you need to handle prioritization, as changing requirements do not necessarily merit immediate priority.

Myth 3: Self-organizing teams self-manage efficiently.

A couple of great principles from the Agile Manifesto deal with communication:

The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.

The best architectures, requirements, and designs emerge from self-organizing teams.

While I believe in the wisdom of these two principles, I don’t want to de-emphasize the need for good, basic software design principles.  Most enterprise development consists of intertwined projects and resources; in order to minimize maintenance issues, adherence to consistent programming standards is a must.  Developers have different naming standards, procedural methodology, and architectural perspectives; a good team has a playbook that ALL members of the development team (regardless of what project team they serve) follow. If you have one database developer that makes heavy use of schemas, and another one that doesn’t, maintaining each other’s code requires some additional effort on their parts.  Furthermore, when teams are self-formed of roughly equally-experienced developers, resolution of architectural decisions can be difficult.

Development teams need an enforcer; a good manager goes a long way toward resolving interpersonal conflicts before they get started.  Just because teams communicate well (and good communication includes conflict), it does not necessarily mean that those same teams will develop quality code in an efficient manner.  Good teams need good direction.

Summing Up.

If you’ve made it this far, I hope I’ve given you some food for thought, as well as encouraged you to go back and revisit the Agile Manifesto, as well as your own organizational processes.  Let me sum up with a final thought from the Agile Manifesto:

At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behavior accordingly.

Good Habits To Adopt: Enforcing the natural primary key

I’ve been reading Aaron Bertrand’s great series of blog posts on bad habits to kick, and have been thinking to myself: what are some good habits that SQL Server developers should implement?    I spend most of my day griping about bad design from vendors, yet I hardly ever take the time to document what should be done instead.  This post is my first attempt to do so, and it’s based on the following assumptions:

  • Good habits are going to be a lot more controversial than bad habits, and
  • SQL Server doesn’t enforce many of these good habits for you.

The first point refers to the fact that some of the choices that I make are not necessarily the best way to do things, and they may not satisfy the need of every application.  I’m a firm believer that there is an exception to every rule, but my goal is to at least define what the rules are (and again, these rules are my own creation and someone may have better rules).  The second point refers to the fact that SQL Server enforces the rules of SQL, but leaves some of that enforcement open to interpretation.  For example, the relational model defined by SQL assumes that tables are related, but SQL Server doesn’t require that you define a FOREIGN KEY (or even a PRIMARY KEY).

So here’s my first good habit:

When defining a surrogate primary key for a table, you should enforce the natural primary key with the use of a UNIQUE constraint.

To really understand this, you have to start with defining what a surrogate primary key is versus a natural primary key.  You can search for a variety of definitions, but I’ll use the following:

  • Primary Key: a non-nullable attribute (or combination of attributes) that can be used to uniquely identify a specific instance of an entity.  When used within SQL, a primary key can be mapped to a column (or columns) in a table, and the value of the key uniquely identifies a row.
  • Natural Primary Key: a primary key that is not auto-generated by the database or application.  The key is comprised of attributes that are associated with an entity, and the value of those attributes is defined by some authority beyond the scope of the database or application.  For example, a Social Security number is a “arbitrarily” assigned number that belongs to a specific citizen of the United States; most databases that use the Social Security number do not create the number, but rather use it as a reference to a particular US citizen.
  • Surrogate Primary Key: a primary key that is auto-generated by the database or application to specifically identify the row in the table representing the collection of entities.  Surrogate keys have no meaning outside of the database and have no relationship to the other attributes in the table.  An ID of 1 simply identifies a row in a table; a row representing a person, a squid, or an automobile may all have an id of 1, depending on what table the surrogate key the data lives in.

Sidebar: as I was writing this, Pinal Dave post the following to his blog: http://blog.sqlauthority.com/2009/10/22/sql-server-difference-between-candidate-keys-and-primary-key-2/ 

Most novices recognize that every table needs a primary key, and surrogate keys offer some benefits that natural keys do not, including:

  • Immutability: the ability of a key to stay constant over time.  A natural primary key (such as a person’s name) may change, but a surrogate key does not.
  • Simplicity of relational JOINS: surrogate keys can remain as a singular column for each table they represent.  For example, a complete invoice may need to be represented by a ClientID, an InvoiceID, and the LineID’s for the lines on that invoice.  Joining on the natural keys may require the Client Name and Address, the Invoice Number, and the Line Number. 

However, surrogate keys have one major weakness; they do NOT enforce the unique validity of each row.  If you use an IDENTITY function in SQL Server to auto-generate your surrogate PRIMARY KEY, and you insert Stuart Ainsworth into your table of Employees, and you accidentally run your INSERT script again, you’ve just double-inserted Stuart Ainsworth.  While there are certainly multiple people with my name, I’m the only one at my company.  However, my application never noticed it.

Using a UNIQUE CONSTRAINT on the columns holding the natural key information avoids this problem; you get the benefits of a surrogate key AND the unique validation of a natural primary key.   The hard part is, of course, identifying the appropriate natural primary key to enforce.  However, this exercise should NOT be overlooked when designing a database.