<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Everything you need to know about designing MySQL InnoDB primary keys</title>
	<atom:link href="http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/</link>
	<description></description>
	<lastBuildDate>Thu, 12 Jan 2012 19:17:13 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>By: John</title>
		<link>http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/comment-page-1/#comment-32116</link>
		<dc:creator>John</dc:creator>
		<pubDate>Sun, 04 Oct 2009 08:23:05 +0000</pubDate>
		<guid isPermaLink="false">http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/#comment-32116</guid>
		<description>Okay, cool, sounds like you&#039;ve got quite the specialized problem space, and you are on top of it :)

And if the column is numeric, and almost always sequential, then you are set.

Actually it might be worth it to see if you can somehow guarantee that it is sequential, because a re-org for a big system like it seems you are dealing with, could be quite expensive, even if it only happens once a day.

I guess you can achieve this with a timestamp column in the table, representing the timestamp prefix of the primary key. Or by making a &#039;timestamp server&quot; -- a meta table running on a single box, keeping track of all the IDs across all shards.

Anyway, I&#039;m sure you can think of your own ways to do this-- but at least look into (or experiment with) how expensive a non-sequential insert would be.

Hmm actually, now that I think of it, even if you did have a non-sequential insert, it would only be out-of-order with the most recent 1 row (if they were submitted at the same millisecond) -- and I&#039;m guessing that re-org would be quite cheap.

But maybe not? Like i said, it&#039;s worth doing a quick experiment (and reporting your findings here :) )

John</description>
		<content:encoded><![CDATA[<p>Okay, cool, sounds like you&#8217;ve got quite the specialized problem space, and you are on top of it <img src='http://jjb.blogs.jjb.cc/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>And if the column is numeric, and almost always sequential, then you are set.</p>
<p>Actually it might be worth it to see if you can somehow guarantee that it is sequential, because a re-org for a big system like it seems you are dealing with, could be quite expensive, even if it only happens once a day.</p>
<p>I guess you can achieve this with a timestamp column in the table, representing the timestamp prefix of the primary key. Or by making a &#8216;timestamp server&#8221; &#8212; a meta table running on a single box, keeping track of all the IDs across all shards.</p>
<p>Anyway, I&#8217;m sure you can think of your own ways to do this&#8211; but at least look into (or experiment with) how expensive a non-sequential insert would be.</p>
<p>Hmm actually, now that I think of it, even if you did have a non-sequential insert, it would only be out-of-order with the most recent 1 row (if they were submitted at the same millisecond) &#8212; and I&#8217;m guessing that re-org would be quite cheap.</p>
<p>But maybe not? Like i said, it&#8217;s worth doing a quick experiment (and reporting your findings here <img src='http://jjb.blogs.jjb.cc/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</p>
<p>John</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Benjie</title>
		<link>http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/comment-page-1/#comment-31619</link>
		<dc:creator>Benjie</dc:creator>
		<pubDate>Sat, 26 Sep 2009 09:12:29 +0000</pubDate>
		<guid isPermaLink="false">http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/#comment-31619</guid>
		<description>Theres many Pros:
- Simple sharding - client generates a UUID and then sends request to the correct DB, future requests are sent to the relevant database based on predefined rules
- AUTO_INCREMENT causes locks on the tables whilst it generates the next entry, this is avoided by having the client generate the ID (not a problem normally but at extremely high load it can be)
- Reverse engineering of data: you can no longer tell how many (e.g.) users the system has by looking at the latest user ID. This isn&#039;t just obfuscated - the information simply not there.
- When sharding, no need to keep track of what IDs have been used before. No single point of failure.
- IDs are unique across tables and not just within them. (Not sure this is particularly helpful, but it doesn&#039;t hurt!)
- Security: e.g. user IDs are unpredictable - it would take forever to guess another user id even if one is already known (even if the format is understood the likelyhood of generating an identical ID is negilgable).
- Less human readable
- Other reasons I&#039;ve forgotten

Cons:
- Storage space increases
- Index sizes increase
- Marginally slower DB performance
- Less human readable (both a pro and a con :))
- Other reasons I&#039;ve forgotten

The &quot;UUID&quot; style format I&#039;ll be using does very precise time information first (100nanosecond resolution) and then random data afterwards, so it will be (mostly) incremental and is unlikely to ever have any conflicts.</description>
		<content:encoded><![CDATA[<p>Theres many Pros:<br />
- Simple sharding &#8211; client generates a UUID and then sends request to the correct DB, future requests are sent to the relevant database based on predefined rules<br />
- AUTO_INCREMENT causes locks on the tables whilst it generates the next entry, this is avoided by having the client generate the ID (not a problem normally but at extremely high load it can be)<br />
- Reverse engineering of data: you can no longer tell how many (e.g.) users the system has by looking at the latest user ID. This isn&#8217;t just obfuscated &#8211; the information simply not there.<br />
- When sharding, no need to keep track of what IDs have been used before. No single point of failure.<br />
- IDs are unique across tables and not just within them. (Not sure this is particularly helpful, but it doesn&#8217;t hurt!)<br />
- Security: e.g. user IDs are unpredictable &#8211; it would take forever to guess another user id even if one is already known (even if the format is understood the likelyhood of generating an identical ID is negilgable).<br />
- Less human readable<br />
- Other reasons I&#8217;ve forgotten</p>
<p>Cons:<br />
- Storage space increases<br />
- Index sizes increase<br />
- Marginally slower DB performance<br />
- Less human readable (both a pro and a con <img src='http://jjb.blogs.jjb.cc/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )<br />
- Other reasons I&#8217;ve forgotten</p>
<p>The &#8220;UUID&#8221; style format I&#8217;ll be using does very precise time information first (100nanosecond resolution) and then random data afterwards, so it will be (mostly) incremental and is unlikely to ever have any conflicts.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: John</title>
		<link>http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/comment-page-1/#comment-31596</link>
		<dc:creator>John</dc:creator>
		<pubDate>Fri, 25 Sep 2009 22:07:05 +0000</pubDate>
		<guid isPermaLink="false">http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/#comment-31596</guid>
		<description>But what is your motivation behind such a scheme? Why not just use an auto-incrementing integer?</description>
		<content:encoded><![CDATA[<p>But what is your motivation behind such a scheme? Why not just use an auto-incrementing integer?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Benjie</title>
		<link>http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/comment-page-1/#comment-31385</link>
		<dc:creator>Benjie</dc:creator>
		<pubDate>Wed, 23 Sep 2009 08:27:02 +0000</pubDate>
		<guid isPermaLink="false">http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/#comment-31385</guid>
		<description>You can make a BINARY(16) that would be (mostly) increasing by making it time based. e.g. get the current 8 byte high-resolution unix timestamp (this is at least millisecond accurate) and convert it to binary, and then tack on another 8 bytes of random binary data. This will be increasing except sometimes when two inserts take place during the same millisecond. It&#039;s not sequential, but it is monotonically increasing (for the vast majority of inserts), and I think that&#039;s what&#039;s important? (Also, those inserts which are not increasing will be extremely recent, so will still be in memory and thus the shuffling should be very minor.)

Of course, I assume that MySQL can order by binary columns and does so sensibly 11 &gt; 10 &gt; 01 &gt; 00.</description>
		<content:encoded><![CDATA[<p>You can make a BINARY(16) that would be (mostly) increasing by making it time based. e.g. get the current 8 byte high-resolution unix timestamp (this is at least millisecond accurate) and convert it to binary, and then tack on another 8 bytes of random binary data. This will be increasing except sometimes when two inserts take place during the same millisecond. It&#8217;s not sequential, but it is monotonically increasing (for the vast majority of inserts), and I think that&#8217;s what&#8217;s important? (Also, those inserts which are not increasing will be extremely recent, so will still be in memory and thus the shuffling should be very minor.)</p>
<p>Of course, I assume that MySQL can order by binary columns and does so sensibly 11 &gt; 10 &gt; 01 &gt; 00.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: John</title>
		<link>http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/comment-page-1/#comment-31367</link>
		<dc:creator>John</dc:creator>
		<pubDate>Wed, 23 Sep 2009 05:20:46 +0000</pubDate>
		<guid isPermaLink="false">http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/#comment-31367</guid>
		<description>Long intelligent comments are encouraged-- keep em coming! :)

A non-sequential primary key (which i imagine will be the case for all non-numeric keys, unless you have a hex key or something similar), will result in the main data store having to be shuffled around for _every_ insert, because the main data store is sorted by order of its primary key.</description>
		<content:encoded><![CDATA[<p>Long intelligent comments are encouraged&#8211; keep em coming! <img src='http://jjb.blogs.jjb.cc/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>A non-sequential primary key (which i imagine will be the case for all non-numeric keys, unless you have a hex key or something similar), will result in the main data store having to be shuffled around for _every_ insert, because the main data store is sorted by order of its primary key.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Benjie</title>
		<link>http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/comment-page-1/#comment-31031</link>
		<dc:creator>Benjie</dc:creator>
		<pubDate>Thu, 17 Sep 2009 08:45:40 +0000</pubDate>
		<guid isPermaLink="false">http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/#comment-31031</guid>
		<description>I was trying to find evidence for what you said in point 1 above about having a non-numeric PK, but http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html seems to disagree - it says it only uses the automatic field if there is no PK and no suitable unique indexes, which suggests that a long non-numeric PK (e.g. BINARY(16)) or even a multi-column PK (e.g. 3 INTs for 18 bytes) would work without it clustering on the automatic field. I couldn&#039;t find evidence for your point in the manual - where did you find it out? Perhaps the source code? (I realise the documentation often skips over the deeper mechanics, and documents how it should work/should be used rather than the exact method that it does work internally.) It seems to be mentioned on a lot of blogs, but I cannot find it anywhere &quot;official&quot;.

I understand the issues with using a long non-numeric PK, such as larger indexes, more disk reads, potential page splits if it&#039;s non-monotonically-increasing, etc. My interest is whether it will cluster on a large non-numeric PK or not, and whether this long PK is used in the secondary indexes or whether the automatic row id is, instead (as this would mean that queries run on just the indexed column and the PK would use the index and then look up the physical data as well, which is obviously slower than just using the index and being done with it).

Sorry for the long comment!</description>
		<content:encoded><![CDATA[<p>I was trying to find evidence for what you said in point 1 above about having a non-numeric PK, but <a href="http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html" rel="nofollow">http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html</a> seems to disagree &#8211; it says it only uses the automatic field if there is no PK and no suitable unique indexes, which suggests that a long non-numeric PK (e.g. BINARY(16)) or even a multi-column PK (e.g. 3 INTs for 18 bytes) would work without it clustering on the automatic field. I couldn&#8217;t find evidence for your point in the manual &#8211; where did you find it out? Perhaps the source code? (I realise the documentation often skips over the deeper mechanics, and documents how it should work/should be used rather than the exact method that it does work internally.) It seems to be mentioned on a lot of blogs, but I cannot find it anywhere &#8220;official&#8221;.</p>
<p>I understand the issues with using a long non-numeric PK, such as larger indexes, more disk reads, potential page splits if it&#8217;s non-monotonically-increasing, etc. My interest is whether it will cluster on a large non-numeric PK or not, and whether this long PK is used in the secondary indexes or whether the automatic row id is, instead (as this would mean that queries run on just the indexed column and the PK would use the index and then look up the physical data as well, which is obviously slower than just using the index and being done with it).</p>
<p>Sorry for the long comment!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: John</title>
		<link>http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/comment-page-1/#comment-31022</link>
		<dc:creator>John</dc:creator>
		<pubDate>Wed, 16 Sep 2009 21:46:59 +0000</pubDate>
		<guid isPermaLink="false">http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/#comment-31022</guid>
		<description>I would imagine that innodb still has the same design in these regards. It would be a pretty big deal if that had changed.

However-- I&#039;m not 100% sure.</description>
		<content:encoded><![CDATA[<p>I would imagine that innodb still has the same design in these regards. It would be a pretty big deal if that had changed.</p>
<p>However&#8211; I&#8217;m not 100% sure.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Benjie</title>
		<link>http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/comment-page-1/#comment-30582</link>
		<dc:creator>Benjie</dc:creator>
		<pubDate>Mon, 07 Sep 2009 09:44:44 +0000</pubDate>
		<guid isPermaLink="false">http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/#comment-30582</guid>
		<description>I would also be interested in your response to RIchard&#039;s question above - basically &quot;Is this still the case?&quot;</description>
		<content:encoded><![CDATA[<p>I would also be interested in your response to RIchard&#8217;s question above &#8211; basically &#8220;Is this still the case?&#8221;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Richard</title>
		<link>http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/comment-page-1/#comment-30156</link>
		<dc:creator>Richard</dc:creator>
		<pubDate>Thu, 27 Aug 2009 15:09:09 +0000</pubDate>
		<guid isPermaLink="false">http://blog.johnjosephbachir.org/2006/10/22/everything-you-need-to-know-about-designing-mysql-innodb-primary-keys/#comment-30156</guid>
		<description>Great post - you have just saved me from using a 32 character GUID as the primary key.
However is this still relevent for the current GA versions of MySQL, or have things moved on in the last few years?
Thanks, Richard</description>
		<content:encoded><![CDATA[<p>Great post &#8211; you have just saved me from using a 32 character GUID as the primary key.<br />
However is this still relevent for the current GA versions of MySQL, or have things moved on in the last few years?<br />
Thanks, Richard</p>
]]></content:encoded>
	</item>
</channel>
</rss>

