Matthew Vince2011-08-08T12:53:46-05:00http://matthewvince.com/Matthew Vincematt@matthewvince.comSorting IP Addresses in MySQL2011-08-04T00:00:00-05:00http://matthewvince.com/2011/08/04/sorting-ip-addresses-in-mysql<h2 id='so_you_want_to_store_ipv4_addresses_in_mysql'>So you want to store IPv4 addresses in MySQL?</h2>
<p>That’s great! So you reach for the obvious: <code>varchar(15)</code>. This works pretty well for most web use cases (ex: event logging). The problem comes if you want to accurately sort the IP addresses. Let’s say we have the following records:</p>
<div class='highlight'><pre><code class='sql'><span class='o'>|</span> <span class='n'>ip_address</span> <span class='o'>|</span>
<span class='o'>+</span><span class='c1'>--------------+</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>2</span> <span class='o'>|</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>1</span> <span class='o'>|</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>13</span> <span class='o'>|</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>3</span> <span class='o'>|</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>22</span> <span class='o'>|</span>
</code></pre>
</div>
<p>And we run the following statement and notice what happens:</p>
<div class='highlight'><pre><code class='sql'><span class='k'>SELECT</span> <span class='o'>*</span> <span class='k'>FROM</span> <span class='n'>ip_addresses</span> <span class='k'>ORDER</span> <span class='k'>BY</span> <span class='n'>ip_address</span><span class='p'>;</span>
<span class='o'>|</span> <span class='n'>ip_address</span> <span class='o'>|</span>
<span class='o'>+</span><span class='c1'>--------------+</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>1</span> <span class='o'>|</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>13</span> <span class='o'>|</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>2</span> <span class='o'>|</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>22</span> <span class='o'>|</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>3</span> <span class='o'>|</span>
</code></pre>
</div>
<p>That’s not really what we wanted, but why? MySQL is doing a standard string compare to order the results. We need to sort on the numeric representation, but how? We could write some complicated conversion function, but there’s something much more helpful found in the <a href='http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-aton'>MySQL manual: INET_ATON</a>.</p>
<blockquote>
<p>Given the dotted-quad representation of an IPv4 network address as a string, returns an integer that represents the numeric value of the address in network byte order (big endian).</p>
</blockquote>
<p>This is exactly what we need. Using this function in an <code>ORDER BY</code> clause will sort our IPv4 in perfect numerical order:</p>
<div class='highlight'><pre><code class='sql'><span class='k'>SELECT</span> <span class='o'>*</span> <span class='k'>FROM</span> <span class='n'>ip_addresses</span> <span class='k'>ORDER</span> <span class='k'>BY</span> <span class='n'>INET_ATON</span><span class='p'>(</span><span class='n'>ip_address</span><span class='p'>);</span>
<span class='o'>|</span> <span class='n'>ip_address</span> <span class='o'>|</span>
<span class='o'>+</span><span class='c1'>--------------+</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>1</span> <span class='o'>|</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>2</span> <span class='o'>|</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>3</span> <span class='o'>|</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>13</span> <span class='o'>|</span>
<span class='o'>|</span> <span class='mi'>192</span><span class='p'>.</span><span class='mi'>168</span><span class='p'>.</span><span class='mi'>1</span><span class='p'>.</span><span class='mi'>22</span> <span class='o'>|</span>
</code></pre>
</div>
<p>I needed this for a particular Rails app I was developing. I hope it comes in handy for you as well.</p>Matthew Vincehttp://matthewvince.comLet's Begin2011-08-04T00:00:00-05:00http://matthewvince.com/2011/08/04/lets-begin<p>Another day, another blog.</p>
<h2 id='im_finally_static'>I’m finally static</h2>
<p>After a few years with <a href='http://wordpress.org'>Wordpress</a>, I’ve switched to <a href='http://jekyllrb.com/'>jekyll</a>. No more database management and continual upgrades for me. I’m finally joining the ranks of the static sites, and for now, it feels great. Which is nice. But the real question is whether this will go anywhere. Which brings me to…</p>
<h2 id='whats_going_on_here'>What’s going on here?</h2>
<p>My name is Matthew Vince and I’m a web & software developer, by day and night. I work my day job in the C# world and night time usually in Ruby, PHP or any number of other languages. I plan on using this blog to document my findings, opinions and frustrations with programming. Will I be successful? Here’s hoping. Should you follow along? Yes!</p>Matthew Vincehttp://matthewvince.com