Development

Finding a Better Way

June 9th, 2009

In my last post, I touched on the fact that Agile introduces a certain process overhead to the equation. This overhead is an investment. Given time to mature, it reaps great rewards. But what happens when it doesn’t get to reach a state maturity? What happens when the project’s lifespan was never destined to reach that tipping point?

Let’s first assume we’re dealing with a client who is open to stepping outside their comfort zone and adopting a new engagement framework with you. Let’s assume they’re willing to make themselves available for regular planning sessions and demo/review periods. Let us also assume that they’re willing to be held accountable for their role in the project’s completion. Let’s assume our client meets all these requirements, what do you do when the cost of educating the client on the methodologies, the processes, and the language of Agile is greater than the reward of putting those tools to work? Continue Reading

Our Process is Broken.

June 5th, 2009

I’m about to enter my 11th year in the business of web design, development and strategy. It boggles my mind to think about it. What is even more perplexing, is that with the exception of the last 2-3 months, the process I (and most of the industry) have employed is in need of dramatic overhaul. In the last few months I’ve been introduced to Agile, which has lessened the suck to a degree.

The Agile movement has some dedicated supporters. Hell, they even have a manifesto. So, I’m likely to get some opposition over this next statement: Agile doesn’t work for small creative agencies.

Continue Reading

Counting Comments: Why I didn’t use COUNT(*)

October 3rd, 2008

When developing this blog, one decision I had to make was how I wanted to retrieve the number of comments per post to be displayed on the blog index page. This is a specific example, but this is an issue that is raised in many web applications, whenever you need to display how many sub-elements there are per item (eg. threads per forum, replies per message, posts per category, etc.). It’s also an example where conventional wisdom is wrong.

For the sake of this article, let’s say our tables look like this:


posts
---------------
id INT
title VARCHAR
body TEXT

comments
---------------
id INT
post_id INT
comment TEXT

The obvious answer is to query the posts table for the post data, join the comments table and count the comments where the post_id matches. Well, that will get you your answer…eventually. Aggregate functions in MySQL, especially COUNT(*) work very well when you’re only returning the COUNT(*) value, and when you’re only querying one MyISAM table. If you’re querying multiple tables, or using InnoDB tables then you will run into some pretty nasty performance issues. So, in this case, it’s not the best approach.

“Well then,” you say, “why don’t we just query for post data, then run our results through a loop to query for the comment counts?” Well, you could do that, but it’s not a solution that scales well. Let’s pretend for the moment that we’re not using caching in anyway, and let’s assume there are ten posts per page. That means in order to get the comment count for each post we would have to run one query to get our post data, and 10 subsequent COUNT(*) queries on the comments table to get the comment counts for each post. That’s 11 queries in total, which is hardly an efficient use of our resources. It means that each time the page loads we’re making 11 queries just for our post results ? on a high traffic site that’s a huge drain on our MySQL server.

In an ideal world, we’d like to make one query, on one table, and get our results. No complicated joins, aggregate functions, or excessive querying. This can be achieved very simply by setting up our data in a way that makes sense for us to retrieve it. What if our posts table looked like this:


posts
---------------
id INT
title VARCHAR
body TEXT
comment_count INT

Well, if the comment count was part of the posts table then a simple query to the posts table would get us all the information we need wouldn’t it? How can this be achieved? When comments are stored to the database all we need to do, in addition to inserting our comment data is to simply increment the value in the comment_count column in the posts table. This means an extra query is involved in adding a comment, but MySQL handles SET column_name = column_name + 1 very quickly and efficiently, and we make this additional query just once when the comment is written, but we reap the savings on every page load.

So, yes, we are storing a little extra data, and making an extra query, but storage space is cheap, and the savings on the reads are greater than the costs on the writes.

Next time you’re faced with a similar scenario, look at how you can structure your tables to make your reads easier because in the real world while writing the a the fanciest query conceivable may be gratifying, but it just doesn’t scale.

The Value of Proper Hosting

October 3rd, 2008

If you are at all serious about your site, you need proper hosting. This could be a “you get what you pay for” conversation, but I think it’s more important to discuss the hidden factors, which many non-web professionals are likely unaware of.

Let’s start with the basics. What is web hosting? Web hosting is a service, which provides you with disk space and a network connection on a web server on which to serve your site to the masses over the Internet. Most web hosting packages consist of space to store your website (including a database), as well as email service. Right off the bat you should be realizing that your choice of hosting providers influences two essential components of your business — your website and your email.

The obvious side effects of a poor hosting provider are that your website or your email could be inaccessible more often than with a good provider, but you don’t need me to tell you that. What I’m going to talk about today are the less obvious side effects that you’re not likely to think about.

  1. Poor hosting makes life miserable for your web developer. It really does and you should care that your web developer is miserable because a happy web developer is more likely to do the little stuff for free, or at discount, because it’s painless for them. When they’re miserable, I can assure you, it will take longer to do things, and they will be sure to bill you for every last second of their misery. To be clear, it doesn’t take longer simply because they aren’t happy, the reality is that with lower tier hosting providers, pages load more slowly, websites require more tuning, and it just generally takes longer to complete routine tasks.
  2. Poor hosting makes your customer miserable. We’ve all been to websites that are slow, or riddled with errors, and we know what it does to us — it sends us packing to another site! In a world where we’ve all become accustomed to instant access to information, your customers aren’t going to wait around for your lousy web hosting to serve your site. Amazon.com for example noticed that for every 100 millisecond increase in page load time they would lose 1% in sales (Kohavi and Longbotham 2007).
  3. Poor hosting companies tend to have equally poor support. This means that when your site does go down (as it’s more inclined to do on a poor host), it’s going to stay down longer because the support team usually smaller and over capacity dealing with a greater volume of issues/complaints.

I could go on and on, but I think you’re getting the picture. Pay a few extra bucks a month for proper hosting and reap the rewards ten fold. We tend to recommend Media Temple to our clients, but ask your web developer who they recommend, and take their advice to heart.

PHP5 on Media Temple Grid-Server

September 24th, 2008

I just recently switched a bunch of sites over to Media Temple, and was dismayed to see that by default the sites run PHP4. Since many of my projects require PHP5 I set out to figure out how to get these sites running. A fair amount of digging through the Media Temple knowlege-base revealed the answer.

  1. Create a .htaccess file in the root of the site
  2. Add the following snippet of code and save:
    
    Action php5-script /gs-bin/php-5.1.6-6
    AddHandler php5-script .php
    

Update: MediaTemple GS is now running PHP 5.2.6. To enable it, use this snippet instead:


Action php5-script /gs-bin/php-5.2.6-1
AddHandler php5-script .php