<?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>www.nerdscene.com &#187; primary key</title>
	<atom:link href="http://www.nerdscene.com/tag/primary-key/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.nerdscene.com</link>
	<description>bitching about everything, one post at a time...</description>
	<lastBuildDate>Tue, 06 Apr 2010 17:40:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Really neat use for multiple field keys in MySQL</title>
		<link>http://www.nerdscene.com/2007/03/02/11/</link>
		<comments>http://www.nerdscene.com/2007/03/02/11/#comments</comments>
		<pubDate>Sat, 03 Mar 2007 03:33:04 +0000</pubDate>
		<dc:creator>Eli Sand</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[auto_increment]]></category>
		<category><![CDATA[index]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[primary key]]></category>
		<category><![CDATA[table]]></category>
		<category><![CDATA[unique key]]></category>
		<category><![CDATA[varchar]]></category>

		<guid isPermaLink="false">http://www.hoktar.com/blog/archives/9</guid>
		<description><![CDATA[I&#8217;ve been working on a project over the past few days and I came in to a situation where a table I had designed was purposefully created to NOT rely on auto_increment/numerical IDs so that I wouldn&#8217;t run in to any eventual limitations on the number of rows I could have (before the auto_increment field [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on a project over the past few days and I came in to a situation where a table I had designed was purposefully created to NOT rely on auto_increment/numerical IDs so that I wouldn&#8217;t run in to any eventual limitations on the number of rows I could have (before the auto_increment field reached it&#8217;s max value and could no longer allow creation of new records).  The table in question was made to use VARCHARs instead as my indexes so that I could link to other tables with those instead.</p>
<p>Then I noticed a slight issue when it came time to updating records in this table &#8211; if I was going to update a row, I had to compare almost <em>all</em> the fields in my table since I had no unique/primary keys defined (just 2 indexes on VARCHARs).  I thought about how much simpler it would be if I had a unique ID field that would allow me to easily refer to a specific row of data &#8211; but at the same time I didn&#8217;t want to walk in to any data storage limits (though I know, over 4 billion or whatever the max INT is won&#8217;t likely ever be reached, it&#8217;s still a limitation I&#8217;d like to avoid by design).</p>
<p>I thought about it for a while and figured that it would be really nice if I could add an auto_increment field &#8211; but tie it in with another non-unique field (think of groups, and then in that group I count the records independently of other groups).  It was an amazing idea but I had no clue how to make it work.  All I knew is that I could define a UNIQUE KEY and constrain it to multiple fields like so &#8220;ALTER TABLE example ADD UNIQUE KEY id (field1, field2);&#8221;.  The problem I foresaw was that if I made one of those fields auto_increment, MySQL would automatically create an INDEX for that same field to which it would store the increment count meaning that my auto_increment field would pertain to the entire table (meaning that the auto_increment field would increment irregardless of the other field specified in the UNIQUE KEY).<br />
<span id="more-11"></span><br />
I then crawled the MySQL documentation wishing that there was some INSERT syntax that allowed subqueries, or a GROUP BY clause so I could use MAX() to count the highest ID number in my 2nd field and sort of <em>fake</em> an auto_increment field &#8211; but I had no such luck.  So I figured &#8220;hey, why not just see what happens if I set auto_increment on the field&#8221; &#8211; so I did, to give me a table structure just like this:</p>
<p><code>CREATE TABLE `example` (<br />
`domain` varchar(255) NOT NULL,<br />
`id` int(10) unsigned NOT NULL auto_increment,<br />
`data` varchar(255) default NULL,<br />
UNIQUE KEY `id` (`domain`,`id`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=utf8;</code></p>
<p>I was surprised when I noticed that MySQL did <strong>not</strong> auto-create a separate INDEX for just the ID field!  I just <strong>had</strong> to test this out now!  I was on the verge of creating exactly what I had hoped to.  So I quickly inserted some records:</p>
<p><code>INSERT INTO `example` (`domain`, `data`) VALUES ('domain.com', 'test1');<br />
INSERT INTO `example` (`domain`, `data`) VALUES ('domain.com', 'test2');<br />
INSERT INTO `example` (`domain`, `data`) VALUES ('domain.net', 'test1');<br />
INSERT INTO `example` (`domain`, `data`) VALUES ('domain.net', 'test2');<br />
INSERT INTO `example` (`domain`, `data`) VALUES ('domain.org', 'test5');</code></p>
<p>&#8230; and to my amazement, it actually worked!  The &#8220;id&#8221; field auto_increments as a <em>group</em> in conjunction with the &#8220;domain&#8221; field.  If you don&#8217;t understand what this all means &#8211; after inserting that data, this is what it looked like:</p>
<p><code>+------------+---+-------+<br />
| domain.com | 1 | test1 |<br />
| domain.com | 2 | test2 |<br />
| domain.net | 1 | test1 |<br />
| domain.net | 2 | test2 |<br />
| domain.org | 1 | test5 |<br />
+------------+---+-------+</code></p>
<p>The &#8220;cool factor&#8221; is in the IDs &#8211; look at how they&#8217;re auto_increment-ing but only in relation to a common domain name in the first field.  So if I were to insert another record for &#8220;domain.com&#8221;, the next auto_increment ID would be 3 &#8211; but if I insert another record for &#8220;domain.org&#8221;, it would be 2 (since there&#8217;s only 1 record for that domain currently).</p>
<p>Neat eh?!  This is a very cool &#8220;trick&#8221; I guess you could say &#8211; and it can be EXTREMELY useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.nerdscene.com/2007/03/02/11/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

