<?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>JEB&#039;s Blog &#187; MySQL</title>
	<atom:link href="http://blog.james.rcpt.to/category/computing/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.james.rcpt.to</link>
	<description>Scribblings of a Techie</description>
	<lastBuildDate>Tue, 20 Dec 2011 07:26:56 +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>MD5s</title>
		<link>http://blog.james.rcpt.to/2011/08/10/md5s/</link>
		<comments>http://blog.james.rcpt.to/2011/08/10/md5s/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 11:33:31 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.james.rcpt.to/?p=410</guid>
		<description><![CDATA[Using an MD5 Digest (or md5 sum) i a neat way of building a predictable key for data. Obviously there is the issue of MD5 collisions (there two completely different source data both produce the same MD5 Digets), but unless you&#8217;re building medical or safety equipment, for general text manipulation its pretty negligible. However, MD5s <a href='http://blog.james.rcpt.to/2011/08/10/md5s/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Using an MD5 Digest (or md5 <em>sum</em>) i a neat way of building a predictable key for data. Obviously there is the issue of MD5 collisions (there two completely different source data both produce the same MD5 Digets), but unless you&#8217;re building medical or safety equipment, for general text manipulation its pretty negligible.</p>
<p>However, MD5s can be represented in several ways. Lets discount the binary envoding of the 128-bits (16 bytes) of data as thats rather cumbersome, and if you&#8217;re storing this in a database such as MySQL, there isn&#8217;t a 16 bytes <a title="MySQl 5.5 numeric data types" href="http://dev.mysql.com/doc/refman/5.5/en/numeric-types.html">numeric data type</a>; BIGINT is 8 bytes, so you&#8217;d have to use two BIGINTs and do lots of horible stuff.</p>
<p>That brings us to the base encodings. Base 16, or hexadecimal, would require us to use a text data type to store the results &#8211; as the base16 encoding will contains the numbers 0-9, and the letters A-F (or a-f &#8211; the case is irrelevent/insensative in base 16). It would be 32 &#8220;characters&#8221; long. We can stuff that in a column with no trouble (char(32)).</p>
<p>We can also use a Base 64  encoding, using upper and lower case letters and a few symbols as well as numerals 0-9. This comes to 22 characters (you&#8217;ll sometimes see == appended to a Base64 to make it 24 characters). Using 22 chars as a key instead of 32 is 31.25% less data. That makes your indexes that much more compact as well as the column data.</p>
<p>It may not be a perfect primary key, but its possibly reasaonable. But then comes the question of converting between Base16 and base 64. Here&#8217;s one way:</p>
<blockquote>
<pre style="text-align: left;">#!/usr/bin/perl
use strict;
use warnings;
use Digest::MD5;
use MIME::Base64;

my $data = "foobarbasbifffoobarbasbiff";
my $md5_base64 = Digest::MD5::md5_base64($data);
printf "%s in base64 as hex: %s\n", $md5_base64, unpack('H*', MIME::Base64::decode_base64($md5_base64));</pre>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.james.rcpt.to/2011/08/10/md5s/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL UTF8 and Perl</title>
		<link>http://blog.james.rcpt.to/2011/06/08/mysql-utf8-and-perl/</link>
		<comments>http://blog.james.rcpt.to/2011/06/08/mysql-utf8-and-perl/#comments</comments>
		<pubDate>Wed, 08 Jun 2011 01:58:02 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.james.rcpt.to/?p=401</guid>
		<description><![CDATA[It&#8217;s been quite annoying; DBI and DBD::MySQL seems to default to Latin 1, and it appears that the client side way of &#8220;updating&#8221; to UTF8 is to issue &#8220;USE NAMES utf8&#8243; as ytour first query when you connect to MySQl (in my case, 5.5.x). The alternate is to tell the server that it should automatically <a href='http://blog.james.rcpt.to/2011/06/08/mysql-utf8-and-perl/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been quite annoying; DBI and DBD::MySQL seems to default to Latin 1, and it appears that the client side way of &#8220;updating&#8221; to UTF8 is to issue &#8220;USE NAMES utf8&#8243; as ytour first query when you connect to MySQl (in my case, 5.5.x). The alternate is to tell the server that it should automatically do this query each time a client connects, or alternatively, disable encoding negotiation and use everything as UTF8. Here&#8217;s a few links I found useful:</p>
<ul>
<li><a href="http://stackoverflow.com/questions/4611645/setting-init-connect-to-a-string-with-spaces-in-an-amazon-rds-parameter-group-usi">Stackoverflow article</a> on RDS and UTF8</li>
<li><a href="http://notes.timeghost.net/2008/10/utf-8-and-mycnf.html">timeghost.net article</a> on MySQL and UTF8</li>
</ul>
<p>And a quote from the second:</p>
<blockquote><p>
[mysqld]<br />
default-character-set=utf8<br />
default-collation=utf8_general_ci<br />
character-set-server=utf8<br />
collation-server=utf8_general_ci<br />
init-connect=&#8217;SET NAMES utf8&#8242;</p>
<p>[client]<br />
default-character-set=utf8</p></blockquote>
<p>As you&#8217;ll see in the first link above (Stackoverflow), adding params with spaces to Amazon RDS is a little tricky from Win platform &#8211; and you have no choice but to use the CLI tools for RDS to do this.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.james.rcpt.to/2011/06/08/mysql-utf8-and-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL varchar not case sensative</title>
		<link>http://blog.james.rcpt.to/2011/04/06/mysql-varchar-not-case-sensative/</link>
		<comments>http://blog.james.rcpt.to/2011/04/06/mysql-varchar-not-case-sensative/#comments</comments>
		<pubDate>Wed, 06 Apr 2011 07:58:05 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[Computing]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.james.rcpt.to/?p=396</guid>
		<description><![CDATA[I managed to overlook an issue with creating a varchar column in an app I have been working on. I have basically got a normalised table, with a forien key to a table of values. In this case, its a set of HTML Document Titles, keyed off an autoincrement column called Title_ID. What I want <a href='http://blog.james.rcpt.to/2011/04/06/mysql-varchar-not-case-sensative/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>I managed to overlook an issue with creating a <code>varchar</code> column in an app I have been working on. I have basically got a normalised table, with a forien key to a table of values. In this case, its a set of HTML Document Titles, keyed off an <em>autoincrement</em> column called <code>Title_ID</code>. What I want to do is look up a title, and get a <code>Title_ID</code> back.</p>
<p>Great; I can do this with a stored function, which I did, and it worked. But it was slow. So I decided that I&#8217;d normalise these en-mass with one big <code>INSERT</code> statement to the normalised table (protected by a unique index constraint), and then store the resulting <code>Title_ID</code>.</p>
<p>There be dragons. As one title came through as &#8220;[Q] help me&#8221; it was duly inserted and given a <code>Title_ID</code>.<br />
However, when a lower case &#8220;[q] help me&#8221; came through, it matched as a duplicate of the original and therefore was not inserted again. I then pulled the strings into a Perl hash, and of course, couldn&#8217;t find a key with &#8220;[<strong>q</strong>] help me&#8221;, only &#8220;[<strong>Q</strong>] help me&#8221;.<br />
Turns out that the issue was my column definition. <code>varchar(<em>x</em>)</code> is not case sensative. <code>varchar(<em>x</em>) binary</code> is. The Unique index I had on here was doing its job and comparing values based upon the case in-sensative column &#8211; not its fault.</p>
<blockquote><p>ALTER TABLE Titles CHANGE COLUMN `Title` `Title` VARCHAR(600) BINARY NULL DEFAULT NULL  ;</p></blockquote>
<p>And now I see my column as &#8220;<code>`Title` varchar(600) CHARACTER SET utf8 <strong>COLLATE utf8_bin</strong> DEFAULT NULL</code>&#8220;.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.james.rcpt.to/2011/04/06/mysql-varchar-not-case-sensative/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Indexes and maximum lengths</title>
		<link>http://blog.james.rcpt.to/2011/03/24/mysql-indexes-and-maximum-lengths/</link>
		<comments>http://blog.james.rcpt.to/2011/03/24/mysql-indexes-and-maximum-lengths/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 13:53:42 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.james.rcpt.to/?p=391</guid>
		<description><![CDATA[MySQL has several index types; the default and therfore probably most common is the BTree. There&#8217;s a limit in MySQL (at least as of this writing when the &#8220;current&#8221; GA is 5.5.9) is 767 bytes &#8211; across all the columns being indexed. Of course, varchar columns can now be bigger than 255 chars, so this <a href='http://blog.james.rcpt.to/2011/03/24/mysql-indexes-and-maximum-lengths/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>MySQL has several index types; the default and therfore probably most common is the BTree. There&#8217;s a limit in MySQL (at least as of this writing when the &#8220;current&#8221; GA is 5.5.9) is 767 bytes &#8211; across all the columns being indexed. Of course, varchar columns can now be bigger than 255 chars, so this limit is probably more easily reached these days.</p>
<p>In my case, I had a table with one column of a URL&#8217;s path, and a URL&#8217;s Query String, both of which can be larger than the old 255 chars. I also have an index that cover these two plus a few other columsn &#8211; normalised protocol, normalised domain, and TCP port.</p>
<p>In trying to move to longer columns (1K) I had to modify my index to restrict the number of characters from these varchar columns to ensure I remained under the 767 limit &#8211; I couldn&#8217;t just change one of these columns from 255 to 1024.</p>
<p>I throught I&#8217;d try and simple change first &#8211; instead of increasing the oclumn, just put the restriction on the current columns as they stand &#8211; so limit the index to 255 chars (while the column still IS 255). Turns out that in at least 5.5.9, since the specified size is the current column size, it ignores this.</p>
<p>Lets make that clearer; you need to specify a SMALLER length for the indexed columns in order for it to stick. Once that&#8217;s done, you can then alter table to increae the column lengths.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.james.rcpt.to/2011/03/24/mysql-indexes-and-maximum-lengths/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL CREATE TABLE as doesn&#8217;t take triggers with it</title>
		<link>http://blog.james.rcpt.to/2011/03/24/mysql-create-table-as-doesnt-take-triggers-with-it/</link>
		<comments>http://blog.james.rcpt.to/2011/03/24/mysql-create-table-as-doesnt-take-triggers-with-it/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 04:32:53 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.james.rcpt.to/?p=388</guid>
		<description><![CDATA[MySQL has a nice feature that you can make a new table exectly like an old table (as far as table column structure and indexes go): create table FOO like BAR; However, as I just rediscovered, any triggers on the table aren&#8217;t taken across with it. D&#8217;oh. Which reminds me, mysqldump has a specific -R <a href='http://blog.james.rcpt.to/2011/03/24/mysql-create-table-as-doesnt-take-triggers-with-it/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>MySQL has a nice feature that you can make a new table exectly like an old table (as far as table column structure and indexes go):</p>
<p><code>create table FOO like BAR;</code></p>
<p>However, as I just rediscovered, any triggers on the table aren&#8217;t taken across with it. D&#8217;oh. Which reminds me, mysqldump has a specific <code>-R</code> flag to backup/dump routines; worth having that on too (I did).</p>
<p>Rule for the day: check your triggers on tables before moving/renaming.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.james.rcpt.to/2011/03/24/mysql-create-table-as-doesnt-take-triggers-with-it/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Partitioning Automation</title>
		<link>http://blog.james.rcpt.to/2010/11/26/mysql-partitioning-automation/</link>
		<comments>http://blog.james.rcpt.to/2010/11/26/mysql-partitioning-automation/#comments</comments>
		<pubDate>Fri, 26 Nov 2010 13:21:18 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.james.rcpt.to/?p=355</guid>
		<description><![CDATA[This is one cool post. It&#8217;s a shame that MySQL doesnt have the ability to automatically add partitions based upon date. For example, if result of a function should generate a new partition: PARTITION BY YEARWEEK(MyDateTimeCol) And hey presto, a bunch of new partitions would appear every time you insert new data thats in a <a href='http://blog.james.rcpt.to/2010/11/26/mysql-partitioning-automation/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://stackoverflow.com/questions/1786579/can-mysql-create-new-partitions-from-the-event-scheduler">This</a> is one cool post.</p>
<p>It&#8217;s a shame that <a href="http://www.mysql.com/">MySQL</a> doesnt have the ability to automatically add partitions based upon date. For example, if result of a function should generate a new partition:</p>
<p><code>PARTITION BY YEARWEEK(MyDateTimeCol)<br />
</code></p>
<p>And hey presto, a bunch of new partitions would appear every time you insert new data thats in a new range. <code>YEARWEEK()</code> may be too course for your massive amount of data &#8211; perhaps <code>TO_DAYS()</code>. Perhaps it&#8217;s not that massive a data set, so just <code>YEAR()</code> would suffice. But having the new partitions created upon <code>INSERT</code> of data that matches would be great. As would deletion of partitions when a partion is empty. Nice bit of housekeeping.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.james.rcpt.to/2010/11/26/mysql-partitioning-automation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to convert IPv4 to IPv6 in MySQL</title>
		<link>http://blog.james.rcpt.to/2010/07/08/hwo-to-convert-ipv4-to-ipv6-in-mysql/</link>
		<comments>http://blog.james.rcpt.to/2010/07/08/hwo-to-convert-ipv4-to-ipv6-in-mysql/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 14:10:59 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://blog.james.rcpt.to/2010/07/08/hwo-to-convert-ipv4-to-ipv6-in-mysql/</guid>
		<description><![CDATA[If you original IPv4 address is in an unsigned long called &#8220;IPv4&#8220;, then&#8230; select concat("0:0:0:0:0:0:", LPAD(CONV(substring_index(inet_ntoa(IPv4), '.', 1), 10, 16), 2, "0"), LPAD(CONV(SUBSTRING_INDEX(SUBSTRING_INDEX( inet_ntoa(IPv4) , '.', 2 ),'.',-1), 10, 16), 2, "0"), ":", LPAD(CONV(SUBSTRING_INDEX(SUBSTRING_INDEX( inet_ntoa(IPv4) , '.', 3 ),'.',-1), 10, 16), 2, "0"), LPAD(CONV(SUBSTRING_INDEX(SUBSTRING_INDEX( inet_ntoa(IPv4) , '.', 4 ),'.',-1), 10, 16), 2, "0")) as IPv6 <a href='http://blog.james.rcpt.to/2010/07/08/hwo-to-convert-ipv4-to-ipv6-in-mysql/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>If you original IPv4 address is in an unsigned long called &#8220;<em>IPv4</em>&#8220;, then&#8230;</p>
<p><code>select concat("0:0:0:0:0:0:", LPAD(CONV(substring_index(inet_ntoa(IPv4), '.', 1), 10, 16), 2, "0"), LPAD(CONV(SUBSTRING_INDEX(SUBSTRING_INDEX( inet_ntoa(IPv4) , '.', 2 ),'.',-1), 10, 16), 2, "0"), ":", LPAD(CONV(SUBSTRING_INDEX(SUBSTRING_INDEX( inet_ntoa(IPv4) , '.', 3 ),'.',-1), 10, 16), 2, "0"), LPAD(CONV(SUBSTRING_INDEX(SUBSTRING_INDEX( inet_ntoa(IPv4) , '.', 4 ),'.',-1), 10, 16), 2, "0")) as IPv6  from Log3NF.Access  limit 1000;</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.james.rcpt.to/2010/07/08/hwo-to-convert-ipv4-to-ipv6-in-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Query Cache: still waiting for duplicate query checking</title>
		<link>http://blog.james.rcpt.to/2009/05/13/mysql-query-cache-still-waiting-for-duplicate-query-checking/</link>
		<comments>http://blog.james.rcpt.to/2009/05/13/mysql-query-cache-still-waiting-for-duplicate-query-checking/#comments</comments>
		<pubDate>Wed, 13 May 2009 00:26:05 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Rants]]></category>

		<guid isPermaLink="false">http://blog.james.rcpt.to/?p=185</guid>
		<description><![CDATA[Way, way back in 2005 (4 years and counting) I finally reported a bug into the then MySQL 5.0 about an issue I was seeing (often) on high volume sites where a single query, if not in the query cache, but spawned from two (or more) simultaneous threads would both be executed in full; this <a href='http://blog.james.rcpt.to/2009/05/13/mysql-query-cache-still-waiting-for-duplicate-query-checking/'>[...]</a>]]></description>
			<content:encoded><![CDATA[<p>Way, way back in 2005 (4 years and counting) I finally reported a bug into the then <a href="http://mysql.com/">MySQL</a> 5.0 about an issue I was seeing (often) on high volume sites where a single query, if not in the query cache, but spawned from two (or more) simultaneous threads would both be executed in full; this is instead of one execution, and then the query cache being populated.</p>
<p>Reference: <a href="http://bugs.mysql.com/bug.php?id=15044">Bug 15044</a>, and <a href="http://forge.mysql.com/worklog/task.php?id=1293">WorkLog 1293</a>.</p>
<p>I had been seeing this for&#8230; well, years before hand, but considered it to be &#8220;just me&#8221;. Since I filed that bug, others have come forward and said they have seen the same issue.</p>
<p>Now, with the Oracle/Sun merge, and Sun having shelled out to &#8220;purchase&#8221; MySQL, we see a miraculous MySQL 5.4 being drafted together. Its good; but it appears to be a simple crowd pleaser that should have happened years ago &#8211; integrate in some very popular performance improvements (notably from <a href="http://code.google.com/p/google-mysql-tools/">Google&#8217;s code repository</a>). If code is being contributed, and it works, why wasn&#8217;t this done earlier? And if not earlier, why now? Smokescreen? Last ditch effort before the project is canned by its new owner? Of course, this has been circulating for a while; I&#8217;m not posting this later after that&#8217;s been in the news for a few weeks now.</p>
<p>What is interesting is the &#8220;<a href="http://forge.mysql.com/wiki/Refactoring_MySQL">Refactoring MySQL</a>&#8221; project being discussed. Where does this leave MySQL 6 &#8211; a little abandoned from here. And then with <a href="http://askmonty.org/wiki/index.php/MariaDB">MariaDB</a> and <a href="https://launchpad.net/drizzle">Drizzle</a> now forked and picking up attention (external to MySQL/Sun/Oracle), it seems the entire thing is just becoming a mess. Drizzel is supposed to be the performance version &#8211; but with the google patches being integrated, perhaps the core MySQL branded project is catching up?</p>
<p>What&#8217;s looking clearer is: Postgres. From my perspective, its worse for MySQL in <a href="http://www.debian.org/">Debian</a>. Lenny (stable now) has MySQL 5.0. The Experimental repo has 5.1 (5.1.34), but this hasn&#8217;t even transitioned to Unstable yet!</p>
<p>Here&#8217;s what I&#8217;d like to see:</p>
<ol>
<li>Someone picks up <a href="http://bugs.mysql.com/bug.php?id=15044">Bug 15044</a>/<a href="http://forge.mysql.com/worklog/task.php?id=1293">WorkLog 1293</a>.</li>
<li>5.4 goes STABLE from MySQL/Sun/Oracle real soon now, with or without my pet qcache bug/feature &#8211; it&#8217;s a big enough win for multi-core systems as it stands</li>
<li>Debian moves MySQl 5.1 from experimental straight to Unstable &#8211; can the mysql-server-5.1 package can coexist with mysql-server-5.0?</li>
<li>Debian also adds, along side the MySQl 5.0 and 5.1 servers, the 5.4 into Unstable, and 6.0 into Experimental.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.james.rcpt.to/2009/05/13/mysql-query-cache-still-waiting-for-duplicate-query-checking/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

