<?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: To UUID or not to UUID ?</title>
	<atom:link href="http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/</link>
	<description>Percona&#039;s MySQL &#38; InnoDB performance and scalability blog</description>
	<lastBuildDate>Sat, 11 Feb 2012 16:45:54 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<item>
		<title>By: bar4ka</title>
		<link>http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/comment-page-1/#comment-831000</link>
		<dc:creator>bar4ka</dc:creator>
		<pubDate>Thu, 13 Oct 2011 13:05:32 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/#comment-831000</guid>
		<description>UUID is 2 integers long, store it as a composite key of two ints, take the upper part from UUID to the first column and the lower part for the second composite column.</description>
		<content:encoded><![CDATA[<p>UUID is 2 integers long, store it as a composite key of two ints, take the upper part from UUID to the first column and the lower part for the second composite column.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mike O.</title>
		<link>http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/comment-page-1/#comment-794716</link>
		<dc:creator>Mike O.</dc:creator>
		<pubDate>Thu, 20 Jan 2011 23:18:32 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/#comment-794716</guid>
		<description>Why make things so complicated? Innodb and MyISAM allows for a compound primary key. Why can&#039;t you simply add a Server_Id column to each table?

CREATE TABLE `cust` (
          `Cust_Id` int(10) unsigned NOT NULL AUTO_INCREMENT,
          `Server_Id` smallint(6) NOT NULL DEFAULT &#039;1&#039;,
          `First_Name` char(15) DEFAULT NULL,
          `Last_Name` char(20) DEFAULT NULL,
          PRIMARY KEY (`Cust_Id`,`Server_Id`)
        ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1

When each database is defined, run an app that alters the default value of the Server_Id of each table. (You probably also want a ServerId table with a row set to the same value). When the table data gets merged from other servers, you still have unique rows and you know which server created the row. The user app would identify each row as ccccc.sss where ccccc is the Cust_Id and sss is the server id. So the user sees customer id of 1234.21 and the program behind the scene just splits it into Cust_Id=1234 and Server_Id=21. 

It is fast and it is readable. Of course it all depends on the administrator setting up unique Server_Id values for each server but if they are on a network you can write an app to do it and verify it.

Mike</description>
		<content:encoded><![CDATA[<p>Why make things so complicated? Innodb and MyISAM allows for a compound primary key. Why can&#8217;t you simply add a Server_Id column to each table?</p>
<p>CREATE TABLE `cust` (<br />
          `Cust_Id` int(10) unsigned NOT NULL AUTO_INCREMENT,<br />
          `Server_Id` smallint(6) NOT NULL DEFAULT &#8217;1&#8242;,<br />
          `First_Name` char(15) DEFAULT NULL,<br />
          `Last_Name` char(20) DEFAULT NULL,<br />
          PRIMARY KEY (`Cust_Id`,`Server_Id`)<br />
        ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1</p>
<p>When each database is defined, run an app that alters the default value of the Server_Id of each table. (You probably also want a ServerId table with a row set to the same value). When the table data gets merged from other servers, you still have unique rows and you know which server created the row. The user app would identify each row as ccccc.sss where ccccc is the Cust_Id and sss is the server id. So the user sees customer id of 1234.21 and the program behind the scene just splits it into Cust_Id=1234 and Server_Id=21. </p>
<p>It is fast and it is readable. Of course it all depends on the administrator setting up unique Server_Id values for each server but if they are on a network you can write an app to do it and verify it.</p>
<p>Mike</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daevid Vincent</title>
		<link>http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/comment-page-1/#comment-786218</link>
		<dc:creator>Daevid Vincent</dc:creator>
		<pubDate>Fri, 10 Dec 2010 21:05:33 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/#comment-786218</guid>
		<description>Another thing I suspect may happen if you use UUIDs as PK is that every insert would cause mySQL to re-index since they&#039;re not sequential by default as a normal numeric PK is. I think you&#039;d take a performance hit on all INSERT operations.</description>
		<content:encoded><![CDATA[<p>Another thing I suspect may happen if you use UUIDs as PK is that every insert would cause mySQL to re-index since they&#8217;re not sequential by default as a normal numeric PK is. I think you&#8217;d take a performance hit on all INSERT operations.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Josh Smith</title>
		<link>http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/comment-page-1/#comment-769681</link>
		<dc:creator>Josh Smith</dc:creator>
		<pubDate>Tue, 20 Jul 2010 08:26:22 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/#comment-769681</guid>
		<description>If you really need to find something between Jens Wagner&#039;s solution Jay Paroline&#039;s in PHP/MySQL, I suggest this approach.

First simply SELECT REVERSE(UNHEX(REPLACE(UUID(),&#039;-&#039;,&#039;&#039;))); this will give us the UNHEXed and REVERSEd UUID in the way that Jens Wagner above suggests. Then you can place this value into your database as you please.

Then when you retrieve the UUID from the database later, you call SELECT HEX(REVERSE(&#039;{$uuid}&#039;)); And to make the UUID look more &quot;natural,&quot; simply run strtolower() to remove the caps.</description>
		<content:encoded><![CDATA[<p>If you really need to find something between Jens Wagner&#8217;s solution Jay Paroline&#8217;s in PHP/MySQL, I suggest this approach.</p>
<p>First simply SELECT REVERSE(UNHEX(REPLACE(UUID(),&#8217;-',&#8221;))); this will give us the UNHEXed and REVERSEd UUID in the way that Jens Wagner above suggests. Then you can place this value into your database as you please.</p>
<p>Then when you retrieve the UUID from the database later, you call SELECT HEX(REVERSE(&#8216;{$uuid}&#8217;)); And to make the UUID look more &#8220;natural,&#8221; simply run strtolower() to remove the caps.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jens Wagner</title>
		<link>http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/comment-page-1/#comment-766313</link>
		<dc:creator>Jens Wagner</dc:creator>
		<pubDate>Tue, 08 Jun 2010 22:05:34 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/#comment-766313</guid>
		<description>As I understood, the last part of UUIDs changes least on one machine, e.g:

1388681F-7348-11DF-83CD-D0B6181E9833
13CF3551-7348-11DF-8556-D1B6181E9833
13F8B66F-7348-11DF-BBC6-D2B6181E9833
141E8E03-7348-11DF-BFCE-D3B6181E9833
1438CCD7-7348-11DF-807F-D4B6181E9833

To improve InnoDB insert performance, primary keys should be inserted with least changing bits first, correct?

I wrote two functions to encode and decode UUIDs, please find them below.

Best,
-jens


DELIMITER $$

CREATE FUNCTION ENCODE_UUID (uuid CHAR(36))
RETURNS BINARY(16)
DETERMINISTIC
BEGIN
	RETURN REVERSE(UNHEX(REPLACE(uuid, &#039;-&#039;,&#039;&#039;)));
END
$$

DELIMITER $$

CREATE FUNCTION DECODE_UUID (uuid BINARY(16))
RETURNS CHAR(36)
DETERMINISTIC
BEGIN
	RETURN concat(
		HEX(LEFT(REVERSE(uuid),4)),&#039;-&#039;,
		HEX(MID(REVERSE(uuid),5,2)),&#039;-&#039;,
		HEX(MID(REVERSE(uuid),7,2)),&#039;-&#039;,
		HEX(MID(REVERSE(uuid),9,2)),&#039;-&#039;,
		HEX(RIGHT(REVERSE(uuid),6))
	);
END
$$

SELECT DECODE_UUID(ENCODE_UUID(&#039;0935C9C3-7345-11DF-BADD-A8B4181E9833&#039;))</description>
		<content:encoded><![CDATA[<p>As I understood, the last part of UUIDs changes least on one machine, e.g:</p>
<p>1388681F-7348-11DF-83CD-D0B6181E9833<br />
13CF3551-7348-11DF-8556-D1B6181E9833<br />
13F8B66F-7348-11DF-BBC6-D2B6181E9833<br />
141E8E03-7348-11DF-BFCE-D3B6181E9833<br />
1438CCD7-7348-11DF-807F-D4B6181E9833</p>
<p>To improve InnoDB insert performance, primary keys should be inserted with least changing bits first, correct?</p>
<p>I wrote two functions to encode and decode UUIDs, please find them below.</p>
<p>Best,<br />
-jens</p>
<p>DELIMITER $$</p>
<p>CREATE FUNCTION ENCODE_UUID (uuid CHAR(36))<br />
RETURNS BINARY(16)<br />
DETERMINISTIC<br />
BEGIN<br />
	RETURN REVERSE(UNHEX(REPLACE(uuid, &#8216;-&#8217;,&#8221;)));<br />
END<br />
$$</p>
<p>DELIMITER $$</p>
<p>CREATE FUNCTION DECODE_UUID (uuid BINARY(16))<br />
RETURNS CHAR(36)<br />
DETERMINISTIC<br />
BEGIN<br />
	RETURN concat(<br />
		HEX(LEFT(REVERSE(uuid),4)),&#8217;-',<br />
		HEX(MID(REVERSE(uuid),5,2)),&#8217;-',<br />
		HEX(MID(REVERSE(uuid),7,2)),&#8217;-',<br />
		HEX(MID(REVERSE(uuid),9,2)),&#8217;-',<br />
		HEX(RIGHT(REVERSE(uuid),6))<br />
	);<br />
END<br />
$$</p>
<p>SELECT DECODE_UUID(ENCODE_UUID(&#8217;0935C9C3-7345-11DF-BADD-A8B4181E9833&#8242;))</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: David Tang</title>
		<link>http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/comment-page-1/#comment-750948</link>
		<dc:creator>David Tang</dc:creator>
		<pubDate>Wed, 21 Apr 2010 03:35:54 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/#comment-750948</guid>
		<description>I am building an application that can function when network is not available, i.e. off line. I would then replicate the record back to central computer. The problem I face is the unique number to assign to the row. If I use int, I need to allocate a section of number of each of the instance of offline application. I am thinking UUID to solve the problem. Is this the right choice to solve this problem?</description>
		<content:encoded><![CDATA[<p>I am building an application that can function when network is not available, i.e. off line. I would then replicate the record back to central computer. The problem I face is the unique number to assign to the row. If I use int, I need to allocate a section of number of each of the instance of offline application. I am thinking UUID to solve the problem. Is this the right choice to solve this problem?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jay Paroline</title>
		<link>http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/comment-page-1/#comment-750501</link>
		<dc:creator>Jay Paroline</dc:creator>
		<pubDate>Tue, 20 Apr 2010 08:29:52 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/#comment-750501</guid>
		<description>@me, my thoughts exactly. In fact you can make them even smaller if you strip out the information you already &quot;know&quot; when you store it. Portions of the UUID never change when generated on the same server, so if you have some other way of uniquely identifying the server you can toss that out when you store it and just add it back in when it&#039;s needed. That brings the size down to a mere 10 bytes, which isn&#039;t bad at all.

BTW in PHP that looks like this:
$uuid = substr($uuid, 0, 8) . substr($uuid, 9, 4) . substr($uuid, 14, 4) . substr($uuid, 19, 4);
where $uuid is the result of doing a SELECT UUID() in MySQL.</description>
		<content:encoded><![CDATA[<p>@me, my thoughts exactly. In fact you can make them even smaller if you strip out the information you already &#8220;know&#8221; when you store it. Portions of the UUID never change when generated on the same server, so if you have some other way of uniquely identifying the server you can toss that out when you store it and just add it back in when it&#8217;s needed. That brings the size down to a mere 10 bytes, which isn&#8217;t bad at all.</p>
<p>BTW in PHP that looks like this:<br />
$uuid = substr($uuid, 0, <img src='http://www.mysqlperformanceblog.com/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> . substr($uuid, 9, 4) . substr($uuid, 14, 4) . substr($uuid, 19, 4);<br />
where $uuid is the result of doing a SELECT UUID() in MySQL.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: me</title>
		<link>http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/comment-page-1/#comment-706090</link>
		<dc:creator>me</dc:creator>
		<pubDate>Tue, 05 Jan 2010 17:50:33 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/#comment-706090</guid>
		<description>Oh boy. UUIDs are 128 bits == 16 bytes.
Store them in a BINARY(16) column.
Don&#039;t mess around with CHAR(32) or even VARCHAR(36).</description>
		<content:encoded><![CDATA[<p>Oh boy. UUIDs are 128 bits == 16 bytes.<br />
Store them in a BINARY(16) column.<br />
Don&#8217;t mess around with CHAR(32) or even VARCHAR(36).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Josh P</title>
		<link>http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/comment-page-1/#comment-567152</link>
		<dc:creator>Josh P</dc:creator>
		<pubDate>Tue, 26 May 2009 06:51:31 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/#comment-567152</guid>
		<description>Here is the solution that I&#039;m considering for my project:

1. Concatenate the numeric user id (1-9 digits) and the UNIX timestamp (10 digits) 
--&gt; [i.e. &quot;3333&quot; . &quot;1111111111&quot; = &quot;33331111111111&quot;] ***GUARANTEED UNIQUE.

2. Convert to base-36 
--&gt; [ &quot;33331111111111&quot; --&gt; &quot;a3gsei3&quot;] --- (if I had 100 million users, the longest ID would still only be 10 characters)

3. Store as binary in CHAR().

My best guess is that this strategy is a win-win (for my situation) over GUIDs and INTs.  I have guaranteed-unique ids (since they are tied to the user id and the timestamp) that are available without querying the database. PLUS, they are SIGNIFICANTLY shorter than GUIDs (they are 1/3 the size).

Admittedly, I&#039;m relatively new to highly-scalable database architecture, so I&#039;d appreciate any thoughts or feedback.  Thanks.</description>
		<content:encoded><![CDATA[<p>Here is the solution that I&#8217;m considering for my project:</p>
<p>1. Concatenate the numeric user id (1-9 digits) and the UNIX timestamp (10 digits)<br />
&#8211;&gt; [i.e. "3333" . "1111111111" = "33331111111111"] ***GUARANTEED UNIQUE.</p>
<p>2. Convert to base-36<br />
&#8211;&gt; [ "33331111111111" --&gt; "a3gsei3"] &#8212; (if I had 100 million users, the longest ID would still only be 10 characters)</p>
<p>3. Store as binary in CHAR().</p>
<p>My best guess is that this strategy is a win-win (for my situation) over GUIDs and INTs.  I have guaranteed-unique ids (since they are tied to the user id and the timestamp) that are available without querying the database. PLUS, they are SIGNIFICANTLY shorter than GUIDs (they are 1/3 the size).</p>
<p>Admittedly, I&#8217;m relatively new to highly-scalable database architecture, so I&#8217;d appreciate any thoughts or feedback.  Thanks.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Rob</title>
		<link>http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/comment-page-1/#comment-525902</link>
		<dc:creator>Rob</dc:creator>
		<pubDate>Tue, 31 Mar 2009 21:16:51 +0000</pubDate>
		<guid isPermaLink="false">http://www.mysqlperformanceblog.com/2007/03/13/to-uuid-or-not-to-uuid/#comment-525902</guid>
		<description>My biggest gripe about UUID() is that it doesn&#039;t generate random (or at least pseudo-random) values. A reason you would want to use UUID/GUID over auto incrementing integers is when you&#039;re synchronizing data from multiple dispersant sources. If you&#039;re constrained by incremental integers for primary keys you&#039;re constantly updating IDs on record inserts during synchronization. If the UUID() values were random (like a Guid in .NET) there should be very little chance of collisions.

I would also like to see a UUID data type (which would use 16-byte binary representation instead of VARCHAR(36))</description>
		<content:encoded><![CDATA[<p>My biggest gripe about UUID() is that it doesn&#8217;t generate random (or at least pseudo-random) values. A reason you would want to use UUID/GUID over auto incrementing integers is when you&#8217;re synchronizing data from multiple dispersant sources. If you&#8217;re constrained by incremental integers for primary keys you&#8217;re constantly updating IDs on record inserts during synchronization. If the UUID() values were random (like a Guid in .NET) there should be very little chance of collisions.</p>
<p>I would also like to see a UUID data type (which would use 16-byte binary representation instead of VARCHAR(36))</p>
]]></content:encoded>
	</item>
</channel>
</rss>

