<?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>Tudor Barbu&#039;s professional blog &#187; mysql</title>
	<atom:link href="http://blog.motane.lu/tag/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.motane.lu</link>
	<description>Ramblings about software development</description>
	<lastBuildDate>Thu, 02 Feb 2012 17:38:27 +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>Can&#8217;t create table (errno: 150)</title>
		<link>http://blog.motane.lu/2011/04/27/cant-create-table-errno-150/</link>
		<comments>http://blog.motane.lu/2011/04/27/cant-create-table-errno-150/#comments</comments>
		<pubDate>Wed, 27 Apr 2011 18:32:26 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1552</guid>
		<description><![CDATA[SQL constraints are usually good, as they help maintain a certain consistency of the database. But sometimes they suck. And when they do, they suck really bad and yield some weird errors, most common being: Can&#8217;t create table `mydatabase`.`mytable` (errno: 150) Annoying little error, isn&#8217;t it? Especially when you want to load a backup dump [...]]]></description>
			<content:encoded><![CDATA[<p>SQL constraints are usually good, as they help maintain a certain consistency of the database. But sometimes they suck. And when they do, they suck really bad and yield some weird errors, most common being:</p>
<blockquote><p>
Can&#8217;t create table `mydatabase`.`mytable` (errno: 150)
</p></blockquote>
<p>Annoying little error, isn&#8217;t it? Especially when you want to load a backup dump and you can&#8217;t because of unfulfilled constrains. This has happened to me on several occasions, especially since I&#8217;ve switched over to InnoDB and started using constraints. So far, I was unable to find any elegant solution, just to switch the foreign key checks off at the beginning  of the import and switch them back on at the end.</p>
<pre class="brush: sql; title: ; notranslate">
SET FOREIGN_KEY_CHECKS = 0;

# regular dump goes here
# CREATE TABLE `my_table` (...)
# bla bla bla

SET FOREIGN_KEY_CHECKS = 1;
</pre>
<p>Not exactly rocket science, but I hope it saves you some headaches.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2011/04/27/cant-create-table-errno-150/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Help saving MySQL</title>
		<link>http://blog.motane.lu/2009/12/14/help-saving-mysql/</link>
		<comments>http://blog.motane.lu/2009/12/14/help-saving-mysql/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 06:41:46 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[orac]]></category>
		<category><![CDATA[thoughts]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1246</guid>
		<description><![CDATA[As you probably know, the most popular Open Source RDBMS, MySQL, is being acquired by Oracle, which &#8211; some say &#8211; will most likely mean the end of the open source project. MySQL has been eroding Oracle&#8217;s profits for quite some time now, and there&#8217;s a fat chance that Oracle will kill MySQL in order [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.motane.lu/wp-content/uploads/2009/09/mysql-logo.png" alt="mysql-logo" title="mysql-logo" width="200" height="103" class="alignleft size-full wp-image-1088" /> As you probably know, the most popular Open Source RDBMS, MySQL, is being acquired by Oracle, which &#8211; some say &#8211; will most likely mean the end of the open source project. MySQL has been eroding Oracle&#8217;s profits for quite some time now, and there&#8217;s a fat chance that Oracle will kill MySQL in order to keep its high profits. </p>
<p>Why should we care? Well, without MySQL, the web would be much different than it is today. Popular open source applications like WordPress and Drupal, millions of websites and applications rely on MySQL. A lot of start-up companies use MySQL in order to cut down costs and not invest in expensive, proprietary RDBMSs. </p>
<p>But we, the people, have the power to stop it by writing to the EC in order to block the transaction. Read what Michael &#8220;Monty&#8221; Widenius, MySQL&#8217;s creator, has to say on the matter: <a href="http://monty-says.blogspot.com/2009/12/help-saving-mysql.html" title="Help saving MySQL" class="outgoing">Help saying MySQL</a>.</p>
<p>PS: Do you know the difference between God and Larry Ellison? God knows He&#8217;s not Ellison&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2009/12/14/help-saving-mysql/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>MySQL backup script</title>
		<link>http://blog.motane.lu/2009/09/28/mysql-backup-script/</link>
		<comments>http://blog.motane.lu/2009/09/28/mysql-backup-script/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 12:18:08 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=1084</guid>
		<description><![CDATA[What is a bad day? How do you define it? Its very definition varies from person to person and from job to job. For some, a bad day is when they lose the bus or the subway and are late for work. For others, a bad day is when their hair looks weird or they [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.motane.lu/wp-content/uploads/2009/09/mysql-logo.png" alt="mysql-logo" title="mysql-logo" width="200" height="103" class="alignleft size-full wp-image-1088" /><br />
What is a bad day? How do you define it? Its very definition varies from person to person and from job to job. For some, a bad day is when they lose the bus or the subway and are late for work. </p>
<p>For others, a bad day is when their hair looks weird or they can&#8217;t find a good parking lot. For economists and bankers, a bad day is when&#8230;well, everyday, given the current economical climate. </p>
<p>For the average programmer a bad day is when he manages to fuck up something on a epic scale on the production server. Let&#8217;s say a database with thousands of users. Today it happened to&#8230;well&#8230;<em>this friend of mine</em>. </p>
<p>Luckily <em>my friend</em> backups his work on a daily basis and is prepared for such situations. One of the scripts he uses for this is the awesome <a href="http://www.debianhelp.co.uk/mysqlscript.htm" title="AutoMySQLBackup Script on DebianHelp.co.uk" class="outgoing">AutoMySQLBackup script</a>, which I &#8211; I mean he recommends to all of you. It&#8217;s really simple to use, all you have to do are some minor configurations and add the script to be ran daily as a cron job. </p>
<p>Real men <strong>*do*</strong> use backups!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2009/09/28/mysql-backup-script/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Prepared statements</title>
		<link>http://blog.motane.lu/2009/02/08/prepared-statements/</link>
		<comments>http://blog.motane.lu/2009/02/08/prepared-statements/#comments</comments>
		<pubDate>Sun, 08 Feb 2009 20:57:13 +0000</pubDate>
		<dc:creator>Tudor</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[pdo]]></category>
		<category><![CDATA[tips and tricks]]></category>

		<guid isPermaLink="false">http://blog.motane.lu/?p=383</guid>
		<description><![CDATA[While studing for the ZCE exam, I&#8217;ve read a lot about prepared statements, especially prepared statements with PDO. According to the textbook, using prepared statements in repetitive queries (such as inserting multiple rows in the database and so on) can lead to a substantial improvement due to the fact that the query is compiled one [...]]]></description>
			<content:encoded><![CDATA[<p>While studing for the <a href="http://blog.motane.lu/2009/01/08/zend-certified-engineer/" title="Zend Certified Engineer" class="outgoing">ZCE exam</a>, I&#8217;ve read a lot about prepared statements, especially prepared statements with <a href="http://www.php.net/pdo" title="PHP Data Objects" class="outgoing">PDO</a>. According to the textbook, using prepared statements in repetitive queries (such as inserting multiple rows in the database and so on) can lead to a substantial improvement due to the fact that the query is compiled one time and the the values are quoted and put in place, whereas in the &#8220;traditional&#8221; way, a query is compiled every time it&#8217;s executed.</p>
<p>So I&#8217;ve decided to give it a try, and see how faster prepared statements actually are. To give the test some objectivity and relevance, I&#8217;ve calculated the amount of time required for 1000 inserts, repeated this operation 100 times and computed the average execution time.<span id="more-383"></span></p>
<p>First, the database table, very simple, 2 columns, one integer and one string:</p>
<pre class="brush: sql; title: ; notranslate">
 CREATE TABLE `test_table` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `numeric` INT NOT NULL ,
    `string` VARCHAR( 32 ) NOT NULL
)
</pre>
<p>The first script, the one without prepared statements. I&#8217;ve quoted the values using PDO by hand, because when using prepared statements, the arguments are automatically quoted and I&#8217;ve tried to replicate the same behaviour as close as possible.</p>
<pre class="brush: php; title: ; notranslate">
set_time_limit( 0 );
$pdo = new PDO( DSN, DB_USER, DB_PASS );
$total = 0;
for( $tests = 0; $tests &lt; 100; $tests++ ) {
	$start = microtime( true );
	for( $index = 0; $index &lt; 1000; $index++ ) {
		$pdo-&gt;exec(
			sprintf(
				'INSERT INTO test_table (numeric, string) VALUES ( %d, %s )',
				$pdo-&gt;quote( $index, PDO::PARAM_INT ),
				$pdo-&gt;quote( md5( $index ), PDO::PARAM_STR )
			)
		);
	}
	$end = microtime( true );
	$total += ( $end - $start );
}

echo 'Average: ' . number_format( $total / 100 , 4, '.', ' ' ) . ' milliseconds'; // Average: 0.0708 milliseconds
</pre>
<p>And now the script with prepared statements:</p>
<pre class="brush: php; title: ; notranslate">
set_time_limit( 0 );
$pdo = new PDO( DSN, DB_USER, DB_PASS );
$total = 0;
$stmt = $pdo-&gt;prepare( 'INSERT INTO test_table (numeric, string) VALUES ( ?, ? )' );

for( $tests = 0; $tests &lt; 100; $tests++ ) {
	$start = microtime( true );
	for( $index = 0; $index &lt; 1000; $index++ ) {
		$stmt-&gt;execute( array( $index, md5( $index ) ) );
	}
	$end = microtime( true );
	$total += ( $end - $start );
}

echo 'Average: ' . number_format( $total / 100 , 4, '.', ' ' ) . ' milliseconds'; // Average: 0.0693 milliseconds
</pre>
<p>The script using prepared statement was faster by an astonishing 0.0015 milliseconds. Wow! A huge accomplishment. NOT! But maybe I&#8217;ve been using too simple queries that are compiled very fast and thus the result is irrelevant. So I&#8217;ve decided to try again, this time using a table with 10 columns and strings. </p>
<pre class="brush: sql; title: ; notranslate">
CREATE TABLE `second_test_table` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`c1` VARCHAR( 32 ) NOT NULL,
`c2` VARCHAR( 32 ) NOT NULL,
`c3` VARCHAR( 32 ) NOT NULL,
`c4` VARCHAR( 32 ) NOT NULL,
`c5` VARCHAR( 32 ) NOT NULL,
`c6` VARCHAR( 32 ) NOT NULL,
`c7` VARCHAR( 32 ) NOT NULL,
`c8` VARCHAR( 32 ) NOT NULL,
`c9` VARCHAR( 32 ) NOT NULL,
`c10` VARCHAR( 32 ) NOT NULL
)
</pre>
<p>Now the first test, without prepared statements:</p>
<pre class="brush: php; title: ; notranslate">
set_time_limit( 0 );
$pdo = new PDO( DSN, DB_USER, DB_PASS );
$total = 0;
for( $tests = 0; $tests &lt; 100; $tests++ ) {
	$start = microtime( true );
	for( $index = 0; $index &lt; 1000; $index++ ) {
		$pdo-&gt;exec(
			sprintf(
				'INSERT INTO second_test_table ( c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) VALUES ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )',
				$pdo-&gt;quote( md5( srand() ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( srand() ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( srand() ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( srand() ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( srand() ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( srand() ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( srand() ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( srand() ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( srand() ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( srand() ), PDO::PARAM_STR )
			)
		);
	}
	$end = microtime( true );
	$total += ( $end - $start );
}

echo 'Average: ' . number_format( $total / 100 , 4, '.', ' ' ) . ' miliseconds'; //Average: 0.2846 miliseconds
&lt;/pre&gt;
Now the one with prepared statements:
&lt;pre lang=&quot;php&quot;&gt;

set_time_limit( 0 );

$pdo = new PDO( DSN, DB_USER, DB_PASS );
$total = 0;
$stmt = $pdo-&gt;prepare( 'INSERT INTO second_test_table ( c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )' );

for( $tests = 0; $tests &lt; 100; $tests++ ) {
	$start = microtime( true );
	for( $index = 0; $index &lt; 1000; $index++ ) {
		$stmt-&gt;execute(
			array(
				md5( srand() ),
				md5( srand() ),
				md5( srand() ),
				md5( srand() ),
				md5( srand() ),
				md5( srand() ),
				md5( srand() ),
				md5( srand() ),
				md5( srand() ),
				md5( srand() )
			)
		);
	}
	$end = microtime( true );
	$total += ( $end - $start );
}

echo 'Average: ' . number_format( $total / 100 , 4, '.', ' ' ) . ' miliseconds'; // Average: 0.2784 miliseconds
</pre>
<p>Another 0.0062 milliseconds gained. Not good enough. The voices in my head started telling me that maybe I should read the manual and find out more about these prepared statements. How about that? That&#8217;s crazy enough to actually work. So I did. And found this out:</p>
<blockquote><p>
MySQL supports prepared statements in version 4.1 and above.
</p></blockquote>
<p>All I know about my MySQL server is that it the default version that comes bundled with Ubuntu Interprid Ibex, but don&#8217;t know which version it is. A quick fix to that:</p>
<pre class="brush: plain; title: ; notranslate">
tudor@thor:~$ mysql -V
mysql  Ver 14.12 Distrib 5.0.67, for debian-linux-gnu (i486) using readline 5.2
</pre>
<p>Okay, than it should work! But the it doesn&#8217;t. An improvement of only 0.0062 milliseconds in the execution time of a thousand queries is far beyond lame. Why would anyone bother for that?  Something doesn&#8217;t smell good here (yeah, go ahead and make a gym socks joke, I haven&#8217;t heard that in a while).</p>
<p>After staring to my monitor for about 5 minutes, I&#8217;ve noticed that all the rows in the database contain the same information. <del>That&#8217;s because of <em>srand()</em>. If no seed is given, srand takes the current timestamp as a seed for generating random numbers. And since all the queries are executed in the same second, it&#8217;s quite logical that they&#8217;re all identical, so they could trigger a MySQL query caching system I don&#8217;t know about (yet).</del> ( Later edit: these tests were conducted very late at night so I&#8217;ve mistaken <a href="http://us2.php.net/srand" title="srand() on PHP manual" class="outgoing">srand()</a> for <a href="http://us2.php.net/manual/en/function.rand.php" title="rand() on PHP manual" class="outgoing">rand()</a>. Coding late at night sucks, because it leads to this kind of errors and to some incredibly lame explanations on why things happen the way they do.) So I&#8217;ve decided on a last try, now with different queries.</p>
<p>Without prepared statements:</p>
<pre class="brush: php; title: ; notranslate">
set_time_limit( 0 );
$pdo = new PDO( DSN, DB_USER, DB_PASS );
$total = 0;
for( $tests = 0; $tests &lt; 100; $tests++ ) {
	$start = microtime( true );
	for( $index = 0; $index &lt; 1000; $index++ ) {
		$pdo-&gt;exec(
			sprintf(
				'INSERT INTO second_test_table ( c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) VALUES ( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )',
				$pdo-&gt;quote( md5( $index . 1 ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( $index . 2 ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( $index . 3 ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( $index . 4 ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( $index . 5 ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( $index . 6 ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( $index . 7 ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( $index . 8 ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( $index . 9 ), PDO::PARAM_STR ),
				$pdo-&gt;quote( md5( $index . 10 ), PDO::PARAM_STR )
			)
		);
	}
	$end = microtime( true );
	$total += ( $end - $start );
}
echo 'Average: ' . number_format( $total / 100 , 4, '.', ' ' ) . ' miliseconds'; //Average: 0.2833 miliseconds
</pre>
<p>&#8230;and with prepared statements&#8230;</p>
<pre class="brush: php; title: ; notranslate">
set_time_limit( 0 );
$pdo = new PDO( DSN, DB_USER, DB_PASS );
$total = 0;
$stmt = $pdo-&gt;prepare( 'INSERT INTO second_test_table ( c1, c2, c3, c4, c5, c6, c7, c8, c9, c10 ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )' );
for( $tests = 0; $tests &lt; 100; $tests++ ) {
	$start = microtime( true );
	for( $index = 0; $index &lt; 1000; $index++ ) {
		$stmt-&gt;execute(
			array(
				md5( $index . 1 ),
				md5( $index . 2 ),
				md5( $index . 3 ),
				md5( $index . 4 ),
				md5( $index . 5 ),
				md5( $index . 6 ),
				md5( $index . 7 ),
				md5( $index . 8 ),
				md5( $index . 9 ),
				md5( $index . 10 )
			)
		);
	}
	$end = microtime( true );
	$total += ( $end - $start );
}

echo 'Average: ' . number_format( $total / 100 , 4, '.', ' ' ) . ' miliseconds'; // Average: 0.2068 miliseconds
</pre>
<p>Now it starting to make some sense &#8211; 0.0765 milliseconds difference for 1000 insert queries on a 10 columns table. Still not enough, but it&#8217;s okay. </p>
<h2><span>My conclusion on prepared statements</span></h2>
<p>I&#8217;m going to stick with them, because they allow a much better separation between the query and the data being feed into it, preventing by default SQL injection attacks. Also, this separation improves the code&#8217;s readability and in some cases using prepared statements can lead to an improved performance, especially when dealing with repetitive queries. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.motane.lu/2009/02/08/prepared-statements/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

