<?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>Snow Giraffe Tech &#187; unsigned</title>
	<atom:link href="http://www.snowgiraffe.com/tech/tag/unsigned/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.snowgiraffe.com/tech</link>
	<description>rails, rubies, and sometimes dolphins</description>
	<lastBuildDate>Mon, 17 Oct 2011 17:45:19 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Rails Migrations, MySQL, unsigned integers, primary keys, and a lot of fun times</title>
		<link>http://www.snowgiraffe.com/tech/366/rails-migrations-mysql-unsigned-integers-primary-keys-and-a-lot-of-fun-times/</link>
		<comments>http://www.snowgiraffe.com/tech/366/rails-migrations-mysql-unsigned-integers-primary-keys-and-a-lot-of-fun-times/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 03:34:34 +0000</pubDate>
		<dc:creator>blythe</dc:creator>
				<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[Migrations]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[:limit]]></category>
		<category><![CDATA[:precision]]></category>
		<category><![CDATA[:scale]]></category>
		<category><![CDATA[column width]]></category>
		<category><![CDATA[mysql_migration_optimizer]]></category>
		<category><![CDATA[numeric type]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[primary key]]></category>
		<category><![CDATA[unsigned]]></category>

		<guid isPermaLink="false">http://www.snowgiraffe.com/tech/?p=366</guid>
		<description><![CDATA[By default Rails uses int(11) as the standard for primary key (id) columns. MySQL prefers unsigned numeric types. Plugin mysql_migration_optimize supports unsigned integers, column display width and complete control over the primary key. Also explained is how to use different numeric types such as tinyint and bigint with Rails Migrations.]]></description>
			<content:encoded><![CDATA[<div id="attachment_383" class="wp-caption alignright" style="width: 298px"><a href="http://www.flickr.com/photos/typefour/2765029015/"><img class="size-medium wp-image-383" title="Antique Keys by Kerri" src="http://www.snowgiraffe.com/tech/wp-content/uploads/2009/04/antique_keys-288x300.jpg" alt="Customize your primary keys. Pic by Kerri on flickr." width="288" height="300" /></a><p class="wp-caption-text">Customize your primary keys. Pic by Kerri on flickr.</p></div>
<p>Although the standard MySQL type for id columns is an <span class="inline_code">unsigned int</span>, Rails has no support for them and uses regular signed <span class="inline_code">int(11)</span> as the default for primary keys. In addition, most of my tables are less than 16 million rows (max rows  for an unsigned <span class="inline_code">mediumint</span>) and so it saves space to use smaller sized numeric types such as <span class="inline_code">smallint</span> or <span class="inline_code">mediumint</span> to save space.</p>
<p>Inspired by <a href="http://thewebfellas.com/blog/2008/6/2/unsigned-integers-for-mysql-on-rails/">Rob Anderton&#8217;s patch</a> which was dismissed as an uncommon requirement, I built yet another plugin to allow customization of primary keys, support unsigned integers and allow users to specify column width for numeric types.</p>
<pre>script/plugin install http://github.com/blythedunham/mysql_migration_optimizer/tree/master</pre>
<div id="attachment_387" class="wp-caption alignleft" style="width: 160px"><a href="http://www.flickr.com/photos/alexsuarez/2504638107/"><img class="size-thumbnail wp-image-387" title="Ignore this sign" src="http://www.snowgiraffe.com/tech/wp-content/uploads/2009/04/ignore_sign2-150x150.jpg" alt="Rails ignores signed! pic by alex suarez flikr" width="150" height="150" /></a><p class="wp-caption-text">Rails ignores signs! pic by alex suarez flikr</p></div>
<h2>Specifying Column Width and Unsigned Integers</h2>
<p>The MySQL connection adapter was ignoring the <span class="inline_code">:precision</span> and <span class="inline_code">:scale</span> options and so I just loaded em up to allow unsigned numeric types and allow column width to be specified which was supported on postgresql but not MySQL.</p>
<pre class="ruby"><span class="ident">add_column</span> <span class="symbol">:giraffe</span><span class="punct">,</span> <span class="symbol">:beer_count</span><span class="punct">,</span> <span class="symbol">:integer</span><span class="punct">,</span> <span class="symbol">:limit</span> <span class="punct">=&gt;</span> <span class="number">2</span><span class="punct">,</span> <span class="symbol">:precision</span> <span class="punct">=&gt;</span> <span class="symbol">:unsigned</span><span class="punct">,</span> <span class="symbol">:scale</span> <span class="punct">=&gt;</span> <span class="number">4</span>
#SQL: ALTER TABLE `giraffe` ADD `beer_count` smallint(4) UNSIGNED</pre>
<p><span id="more-366"></span></p>
<ul>
<li>:limit determines the numeric type. Rails introduced smart integer columns in 2.1 which more or less translates to the number of bytes needed for storage. Here&#8217;s a little map taken from the <a href="http://github.com/rails/rails/blob/dc88847e5ce392eed210b97525c14fca55852867/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb">adapter</a> code. Do be careful, however, as some versions of Rails (2.1) <a href="http://blog.smartlogicsolutions.com/2008/06/24/rails-21-broke-my-mysql-foreign-keys/">break foreign keys</a>.<br />
<table style="background-color:#CCCCFF" border="0" align="center">
<tbody>
<tr>
<th> <span class="inline_code">:limit</span></th>
<th> Numeric Type</th>
<th> Column Size</th>
</tr>
<tr>
<td>1</td>
<td><span style="color: #ff9900;">tinyint</span></td>
<td>1 byte</td>
</tr>
<tr>
<td>2</td>
<td><span style="color: #ff9900;">smallint</span></td>
<td>2 bytes</td>
</tr>
<tr>
<td>3</td>
<td><span style="color: #ff9900;">mediumint</span></td>
<td>3 bytes</td>
</tr>
<tr>
<td>nil, 4, 11</td>
<td><span style="color: #ff9900;">int(11)</span></td>
<td>4 bytes</td>
</tr>
<tr>
<td>5 to 8</td>
<td><span style="color: #ff9900;">bigint</span></td>
<td>8 bytes</td>
</tr>
</tbody>
</table>
</li>
<li> :scale: <a href="http://matthom.com/archive/2006/11/28/mysql-integer-columns-and-display-width">column width explained here by Matt Thommes</a> number in parenthesis (4) .</li>
<li>:precision : specify <span class="inline_code">:signed</span> or <span class="inline_code">:unsigned</span>. Default will be <span class="inline_code">:unsigned</span> unless you specify set <span class="inline_code">MySqlMigrationOptimizer.default_sign = :signed </span><br />
in your  enviroment.rb.</li>
</ul>
<h2>Customizing Primary Keys</h2>
<pre class="ruby"><span class="ident">create_table</span> <span class="punct">"</span><span class="string">animal</span><span class="punct">",</span> <span class="symbol">:force</span> <span class="punct">=&gt;</span> <span class="constant">true</span><span class="punct">,</span>  <span class="symbol">:primary_column</span> <span class="punct">=&gt;</span> <span class="punct">{</span><span class="symbol">:type=</span><span class="punct">&gt;</span><span class="symbol">:integer</span><span class="punct">,</span> <span class="symbol">:limit</span> <span class="punct">=&gt;</span> <span class="number">3</span><span class="punct">,</span> <span class="symbol">:scale=</span><span class="punct">&gt;</span><span class="number">5</span><span class="punct">}</span>  <span class="keyword">do</span> <span class="punct">|</span><span class="ident">t</span><span class="punct">|</span> <span class="keyword">end</span>
#SQL: CREATE TABLE `animal` ( `id` mediumint(5) UNSIGNED NOT NULL auto_increment PRIMARY KEY) ENGINE=InnoDB</pre>
<p>If you really want to get crazy you can specify some other type. Here&#8217;s the rope, I&#8217;ll leave the room if you want to hang yourself.</p>
<pre class="ruby"><span class="comment"># Specify a string column as the primary key</span>
<span class="ident">create_table</span> <span class="punct">"</span><span class="string">blah</span><span class="punct">",</span> <span class="symbol">:force</span> <span class="punct">=&gt;</span> <span class="constant">true</span><span class="punct">,</span>
<span class="symbol">:primary_column</span> <span class="punct">=&gt;</span> <span class="punct">{</span><span class="symbol">:type=</span><span class="punct">&gt;</span><span class="symbol">:string</span><span class="punct">,</span> <span class="symbol">:limit=</span><span class="punct">&gt;</span><span class="number">25</span><span class="punct">,</span> <span class="symbol">:auto_increment=</span><span class="punct">&gt;</span><span class="constant">false</span><span class="punct">}</span> <span class="keyword">do</span> <span class="punct">|</span><span class="ident">t</span><span class="punct">|</span><span class="comment">#</span>
<span class="keyword">end</span>

#SQL: CREATE TABLE `blah` (`id` varchar(25) NOT NULL PRIMARY KEY) ENGINE=InnoDB</pre>
<p>Do be careful to use the same numeric type for the foreign key columns as the referenced id column.</p>
<pre class="ruby"><span class="ident">add_column</span> <span class="symbol"> <img src='http://www.snowgiraffe.com/tech/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> ther_table</span><span class="punct">,</span> <span class="symbol">:blah_id</span><span class="punct">,</span> <span class="symbol">:integer</span><span class="punct">,</span> <span class="symbol">:limit</span> <span class="punct">=&gt;</span> <span class="number">3</span><span class="punct">,</span> <span class="symbol">:scale=</span><span class="punct">&gt;</span><span class="number">5</span></pre>
<p>If you have already generated a lot of tables and do not want to change all the old column types, specify the default to be <span class="inline_code">:signed</span> in config/environment.rb. Any new columns should then specify <span class="inline_code">:precision =&gt; :unsigned</span></p>
<pre class="ruby"><span class="constant">MySqlMigrationOptimizer</span><span class="punct">.</span><span class="ident">default_sign</span> <span class="punct">=</span> <span class="symbol">:signed</span></pre>
<p>The schemadumper has been amended to work correctly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.snowgiraffe.com/tech/366/rails-migrations-mysql-unsigned-integers-primary-keys-and-a-lot-of-fun-times/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

