<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Source Allies Blog &#187; SQL</title>
	<atom:link href="http://blogs.sourceallies.com/tag/sql/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.sourceallies.com</link>
	<description>Technical and process thinking from Source Allies employees</description>
	<lastBuildDate>Thu, 19 Aug 2010 18:35:29 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>IP Addresses in PHP/MySQL</title>
		<link>http://blogs.sourceallies.com/2010/02/ip-addresses-in-phpmysql/</link>
		<comments>http://blogs.sourceallies.com/2010/02/ip-addresses-in-phpmysql/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 13:32:39 +0000</pubDate>
		<dc:creator>Mark Ciecior</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://blogs.sourceallies.com/?p=924</guid>
		<description><![CDATA[I&#8217;ve been working on a web-based tool that stores, among other network-related things, IP addresses.  When I first started I stored each IP address as four TINYINTS (0-255 for each octet):

mysql&#62; DESC ipaddresses;
+----------+---------------------+------+-----+---------+----------------+
&#124; FIELD    &#124; Type                [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on a web-based tool that stores, among other network-related things, IP addresses.  When I first started I stored each IP address as four TINYINTS (0-255 for each octet):</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">mysql<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">DESC</span> ipaddresses;
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----------+---------------------+------+-----+---------+----------------+</span>
<span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">FIELD</span>    <span style="color: #66cc66;">|</span> Type                <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #66cc66;">|</span> Extra          <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----------+---------------------+------+-----+---------+----------------+</span>
<span style="color: #66cc66;">|</span> id       <span style="color: #66cc66;">|</span> int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span>    <span style="color: #66cc66;">|</span> NO   <span style="color: #66cc66;">|</span> PRI <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span>    <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span> <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">|</span> A        <span style="color: #66cc66;">|</span> tinyint<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #66cc66;">|</span> NO   <span style="color: #66cc66;">|</span>     <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span>    <span style="color: #66cc66;">|</span>                <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">|</span> B        <span style="color: #66cc66;">|</span> tinyint<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #66cc66;">|</span> NO   <span style="color: #66cc66;">|</span>     <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span>    <span style="color: #66cc66;">|</span>                <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">|</span> C        <span style="color: #66cc66;">|</span> tinyint<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #66cc66;">|</span> NO   <span style="color: #66cc66;">|</span>     <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span>    <span style="color: #66cc66;">|</span>                <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">|</span> D        <span style="color: #66cc66;">|</span> tinyint<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #66cc66;">|</span> NO   <span style="color: #66cc66;">|</span>     <span style="color: #66cc66;">|</span> <span style="color: #993333; font-weight: bold;">NULL</span>    <span style="color: #66cc66;">|</span>                <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----------+---------------------+------+-----+---------+----------------+</span>
<span style="color: #cc66cc;">5</span> rows <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">&#41;</span>
&nbsp;
mysql<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> ipaddresses <span style="color: #993333; font-weight: bold;">WHERE</span> id<span style="color: #66cc66;">=</span><span style="color: #cc66cc;">1</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+----+----+----+-----+</span>
<span style="color: #66cc66;">|</span> id <span style="color: #66cc66;">|</span> A  <span style="color: #66cc66;">|</span> B  <span style="color: #66cc66;">|</span> C  <span style="color: #66cc66;">|</span> D   <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+----+----+----+-----+</span>
<span style="color: #66cc66;">|</span>  <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">|</span> <span style="color: #cc66cc;">10</span> <span style="color: #66cc66;">|</span> <span style="color: #cc66cc;">20</span> <span style="color: #66cc66;">|</span> <span style="color: #cc66cc;">30</span> <span style="color: #66cc66;">|</span> <span style="color: #cc66cc;">131</span> <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+----+----+----+-----+</span>
<span style="color: #cc66cc;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.02</span> sec<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>As I started manipulating these addresses I found it awkward to do common binary math (like bitwise ANDs).  I decided instead to store these 32-bit values as unsigned integers (of length 32).  To make my life easier yet, MySQL and PHP both have native functions to convert IP addresses between my old and new formats to make this migration extremely easy.<br />
<span id="more-924"></span><br />
In MySQL:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">mysql<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">SELECT</span> INET_ATON<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'10.20.30.131'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">---------------------------+</span>
<span style="color: #66cc66;">|</span> INET_ATON<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'10.20.30.131'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">---------------------------+</span>
<span style="color: #66cc66;">|</span>                 <span style="color: #cc66cc;">169090691</span> <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">---------------------------+</span>
<span style="color: #cc66cc;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">&#41;</span>
&nbsp;
mysql<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">SELECT</span> INET_NTOA<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">169090691</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----------------------+</span>
<span style="color: #66cc66;">|</span> INET_NTOA<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">169090691</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----------------------+</span>
<span style="color: #66cc66;">|</span> 10<span style="color: #66cc66;">.</span>20<span style="color: #66cc66;">.</span>30<span style="color: #66cc66;">.</span>131         <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----------------------+</span>
<span style="color: #cc66cc;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>In PHP:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$ip_string</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;10.20.30.131&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$ip_integer</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ip2long</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ipstring</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$ip_integer</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">## 169090691
</span><span style="color: #b1b100;">echo</span> <span style="color: #990000;">long2ip</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ip_integer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">## 10.20.30.131</span></pre></div></div>

<p>In another example of inefficiency, I used to gather all sorts of info from the user and use PHP to make multiple SQL queries before modifying my data.  I&#8217;ve since learned about stored procedures &#8211; the database does all the work and I only need to make one SQL call from PHP.  This presented me with an unexpected problem, however:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">mysql<span style="color: #66cc66;">&gt;</span> CALL getAddress<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+----+----+----+----+</span>
<span style="color: #66cc66;">|</span> id <span style="color: #66cc66;">|</span> A  <span style="color: #66cc66;">|</span> B  <span style="color: #66cc66;">|</span> C  <span style="color: #66cc66;">|</span> D  <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+----+----+----+----+</span>
<span style="color: #66cc66;">|</span>  <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">|</span> <span style="color: #cc66cc;">10</span> <span style="color: #66cc66;">|</span> <span style="color: #cc66cc;">20</span> <span style="color: #66cc66;">|</span> <span style="color: #cc66cc;">30</span> <span style="color: #66cc66;">|</span> <span style="color: #cc66cc;">131</span><span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+----+----+----+----+</span>
<span style="color: #cc66cc;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">&#41;</span>
&nbsp;
Query OK<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">0</span> rows affected <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>The string &#8220;Query OK, 0 rows affected (0.00 sec)&#8221; is a second result set, which the PHP <i>mysql</i> library can&#8217;t handle.  The fix here is to use the <i>mysqli</i> library instead and access only the result sets you need.  In my case I&#8217;m only concerned with the first result set so I added a bunch of wasteful while loops after each of my CALL queries.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysqli_next_result</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>Lastly, PHP&#8217;s ip2long function treats 32-bit numbers as signed ints, so I had to specifically treat them as unsigned ints:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">echo $ip_integer; <span style="color: #808080; font-style: italic;">## BAD</span>
echo sprintf<span style="color: #66cc66;">&#40;</span>%u<span style="color: #66cc66;">,</span> $ip_integer<span style="color: #66cc66;">&#41;</span>; <span style="color: #808080; font-style: italic;">## GOOD</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blogs.sourceallies.com/2010/02/ip-addresses-in-phpmysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
