<?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>Kevin Bradwick &#187; MySQL</title>
	<atom:link href="http://www.kevinbradwick.co.uk/category/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kevinbradwick.co.uk</link>
	<description>Web development and design blog</description>
	<lastBuildDate>Fri, 09 Jul 2010 08:11:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>SQL JOIN statements</title>
		<link>http://www.kevinbradwick.co.uk/2010/02/sql-join-statements/</link>
		<comments>http://www.kevinbradwick.co.uk/2010/02/sql-join-statements/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 16:35:01 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[join]]></category>

		<guid isPermaLink="false">http://www.kevinbradwick.co.uk/?p=122</guid>
		<description><![CDATA[When working with relational databases, you will often find that the data your require can reside on multiple tables. In simple terms, a join statement brings together these tables using a common identifier. Joins are the best way to query a database whilst improving transaction efficiency. An example We&#8217;ll create two tables, a users and [...]]]></description>
			<content:encoded><![CDATA[<p>When working with relational databases, you will often find that the data your require can reside on multiple tables. In simple terms, a join statement brings together these tables using a common identifier. Joins are the best way to query a database whilst improving transaction efficiency.</p>
<h3>An example</h3>
<p>We&#8217;ll create two tables, a users and account table. The account table holds account names (e.g. Guest, Admin, Super Admin) and the users table contains one foreign key that relates to the account type.</p>
<p>The structure looks like this;</p>
<p><img class="alignnone size-thumbnail wp-image-123" title="schema" src="http://www.kevinbradwick.co.uk/wp-content/uploads/2010/02/schema.png" alt="" /></p>
<p>And here&#8217;s some data that we&#8217;ll work with&#8230;</p>
<p><img class="alignnone size-thumbnail wp-image-126" title="sql-select-accounts" src="http://www.kevinbradwick.co.uk/wp-content/uploads/2010/02/sql-select-accounts.png" alt="" /></p>
<p><img class="alignnone size-full wp-image-130" title="users-data" src="http://www.kevinbradwick.co.uk/wp-content/uploads/2010/02/users-data.png" alt="" width="392" height="161" /></p>
<p>Now to perform a simple join of these two tables, we could use&#8230;</p>
<p><img class="alignnone size-full wp-image-132" title="join-1" src="http://www.kevinbradwick.co.uk/wp-content/uploads/2010/02/join-1.png" alt="" width="544" height="139" /></p>
<p>This simple query will return all records but using this as a base we can further customise our query to make it more useful. If we wanted to find out all users who have Admin accounts we&#8217;d use this statement.</p>
<pre name="code" class="php">
SELECT * FROM users u LEFT JOIN accounts a ON u.account_type = a.id WHERE a.name = 'Admin'

// or we could use the ID from the accounts table

SELECT * FROM users u LEFT JOIN accounts a ON u.account_type = a.id WHERE a.id = 2
</pre>
<h3>A note on usage</h3>
<p>This is MySQL join in its most simplest terms. You can join multiple tables providing you database design allows it. So with that cleared up, if you are not already using joins in your queries, start using them and cut down on the number of transactions you make&#8230;it&#8217;ll also make your life a lot easier retrieving data.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kevinbradwick.co.uk/2010/02/sql-join-statements/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grant remote access to MySQL</title>
		<link>http://www.kevinbradwick.co.uk/2010/01/grant-remote-access-to-mysql/</link>
		<comments>http://www.kevinbradwick.co.uk/2010/01/grant-remote-access-to-mysql/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 18:05:32 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[remote access]]></category>

		<guid isPermaLink="false">http://www.kevinbradwick.co.uk/?p=45</guid>
		<description><![CDATA[If you&#8217;ve installed MySQL on a machine other than your work station (localhost) and you want to use the MYSQL GUI tools to administer the server then you&#8217;ll need to grant remote acccess on the root account (or another account that has useful privileges. This is how to do it. Connect via SSH and login [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve installed MySQL on a machine other than your work station (localhost) and you want to use the MYSQL GUI tools to administer the server then you&#8217;ll need to grant remote acccess on the root account (or another account that has useful privileges. This is how to do it.</p>
<p>Connect via SSH and login to mysql&#8230;</p>
<pre name="code" class="php">
# mysql -u root -p

// now grant access for the root account
mysql > GRANT USAGE ON *.* to root@'%' IDENTIFIED BY '[password]';
mysql > FLUSH PRIVILEGES;
</pre>
<p>Change [password] to whatever the password is for the root account and include the single quotes (&#8216;). The % sign means it will accept connections from this account on all IP addresses. You could if you wanted, choose a specific IP here.</p>
<p>You&#8217;ll now be able to login remotely.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kevinbradwick.co.uk/2010/01/grant-remote-access-to-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Foreign Key tutorial using MySQL</title>
		<link>http://www.kevinbradwick.co.uk/2009/12/foreign-key-tutorial-using-mysql/</link>
		<comments>http://www.kevinbradwick.co.uk/2009/12/foreign-key-tutorial-using-mysql/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 06:16:13 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[foreign key]]></category>

		<guid isPermaLink="false">http://www.kevinbradwick.co.uk/?p=27</guid>
		<description><![CDATA[Foreign key&#8217;s in a database table reference primary key&#8217;s of rows in another table. Why does this matter? Well, if you have ever built an application whereby updating/deleting a row from one table requires further transactions to be carried out on other, you&#8217;ll know the nuisance and confusion this can cause (especially if your application [...]]]></description>
			<content:encoded><![CDATA[<p>Foreign key&#8217;s in a database table reference primary key&#8217;s of rows in another table. Why does this matter? Well, if you have ever built an application whereby updating/deleting a row from one table requires further transactions to be carried out on other, you&#8217;ll know the nuisance and confusion this can cause (especially if your application is reasonably large). Foreign key&#8217;s can rescue the situation&#8230;</p>
<h3>A typical example</h3>
<p>Let&#8217;s say you have a table called users and a user_meta table that holds multiple rows relating to the user table (use the following code in a test database).</p>
<pre name="code" class="php">
CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(30) DEFAULT NULL,
  `passwd` varchar(40) DEFAULT NULL,
  `email` varchar(120) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;

CREATE TABLE `user_meta` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `meta_name` varchar(255) DEFAULT NULL,
  `meta_value` text,
  `user_id` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `FK_user_meta_users` (`user_id`),
  CONSTRAINT `FK_user_meta_users` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
</pre>
<p>Notice the database engine in this case is InnoDB. MyISAM does not support foreign keys. Without worrying too much about the syntax, the user_meta table declares that the column &#8216;user_id&#8217; is foreign and references the primary key on the user table (id).</p>
<p>Now that they foreign keys are referenced what can we do with them? In this case, I&#8217;ve declared ON DELETE CASCADE. This means that if we delete a user from the user table, all user_meta records for that user will be deleted automatically. If we said on UPDATE CASCADE, should the users primary key get updated, then the user_meta table will automatically update the user_id column as necessary.</p>
<p>There are other options too&#8230;</p>
<p>RESTRICT and NO ACTION. These two are similar in that nothing will get changed upon the parent table changing. SET NULL will set the foreign key table column values to null upon delete/update. SET DEFAULT can also come in handy if you have set default values to columns.</p>
<p>Try them out, if you havent&#8217; used them before, I will guarantee you will find uses for them in the future.</p>
<p>Download sample database dump: <a class="downloadlink" href="http://www.kevinbradwick.co.uk/getfile/1" title=" downloaded 87 times" >Foreign Key Tutorial SQL Dump (87)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kevinbradwick.co.uk/2009/12/foreign-key-tutorial-using-mysql/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Introduction to Doctrine&#8217;s Nested Set</title>
		<link>http://www.kevinbradwick.co.uk/2009/12/introduction-to-doctrines-nested-set/</link>
		<comments>http://www.kevinbradwick.co.uk/2009/12/introduction-to-doctrines-nested-set/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 02:31:30 +0000</pubDate>
		<dc:creator>kevin</dc:creator>
				<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[nested set]]></category>

		<guid isPermaLink="false">http://www.kevinbradwick.co.uk/?p=24</guid>
		<description><![CDATA[A common problem requirement among developers is to store hierarchial data to a flat file database. You have probably come across the parent/child methodology whereby a table has a typical &#8216;parent&#8217; column that references, you guessed it, its parent &#8211; this method is also known as adjacency list model. Querying in this way can often [...]]]></description>
			<content:encoded><![CDATA[<p>A common <del datetime="2010-01-07T21:13:33+00:00">problem</del> requirement among developers is to store hierarchial data to a flat file database. You have probably come across the parent/child methodology whereby a table has a typical &#8216;parent&#8217; column that references, you guessed it, its parent &#8211; this method is also known as adjacency list model. Querying in this way can often lead to a lot of transactions per single request (one transaction per row) and an application with many rows of hierarchial data will dent your transaction efficiency. There are benefits to this system (simpler SQL management for CRUD operation) but there is another way that is more efficient &#8211; the Nested Set model (also known as modified pre-order tree traversal algorithm &#8211; MPTT).</p>
<p>Doctrine has by far the best known method of Nested Set operation I have come across. My main reason for this is the ability for it to store multiple roots in a single table. For example, this could come in handy for an application that implements multiple blogs.</p>
<p>So, let&#8217;s dive in and take a look at how we use this system.</p>
<p>For this example, I am going to show how this would come in use for a web application that hosts multiple blogs. Our database schema looks like this.</p>
<pre name="code" class="php">
CREATE TABLE `Blogs` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `blog_admin` int(11) unsigned NOT NULL,
  `blog_title` text,
  `blog_description` text,
  `status` enum('live','private','offline') NOT NULL DEFAULT 'live',
  PRIMARY KEY (`id`),
  KEY `FK_Blogs_users` (`blog_admin`),
  CONSTRAINT `FK_Blogs_users` FOREIGN KEY (`blog_admin`) REFERENCES `Users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;

CREATE TABLE `BlogCategories` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `blog_id` int(11) unsigned NOT NULL,
  `name` varchar(140) DEFAULT NULL,
  `description` text,
  `lft` int(11) unsigned NOT NULL,
  `rgt` int(11) unsigned NOT NULL,
  `level` int(10) unsigned NOT NULL DEFAULT '0',
  `root_id` int(11) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  KEY `FK_BlogCategories_blogs` (`blog_id`),
  CONSTRAINT `FK_BlogCategories_blogs` FOREIGN KEY (`blog_id`) REFERENCES `Blogs` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
</pre>
<p>Simply, we have a blogs table that has a foreign key back to a user table and the BlogCategories table will hold our categories relating to all the blogs. Next we will create our models&#8230;</p>
<p>I&#8217;m not going to cover model creation but for reference, I prefer to design my database through MySQL Query Browser first, then let Doctrine to generate the models for me using the generateModelsFromDb method like this;</p>
<pre name="code" class="php">
//...
Doctrine_Core::generateModelsFromDb('/path/to/where/i/want/to/output/my/models/', array('doctrine'), array('generateTableClasses' => true));
</pre>
<p>In my BlogsCategories model, I tell it to act as a nested set, tell it there are many roots and declare the root column name (by default it is root_id, so I don&#8217;t need to declare it here but this is to show you how you would declare it to be a name other than root_id)</p>
<pre name="code" class="php">
//...
$this->actAs('NestedSet', array(
	'hasManyRoots' => TRUE,
	'rootColumnName' => 'root_id'
	));
</pre>
<p>Now we&#8217;re good to go. The first thing we want to do is create a new root category. This category will be the parent category for all other categories.</p>
<pre name="code" class="php">
$root = new BlogCategories();
$root->blog_id = 1; // relates back to the Blogs table
$root->name = 'ROOT';
$root->description = 'DO NOT DELETE';
$root->save(); // saves the new root category

$treeObject = Doctrine_Core::getTable('BlogCategories')->getTree();
$treeObject->createRoot($root);
</pre>
<p>If you look in your database now, you notice this has inserted the row and set the left/right/level/root columns appropriately. You can do this a few times to create a few roots. Now let&#8217;s look at inserting nodes for a particular blog. We&#8217;ll work with blog_id 1.</p>
<pre name="code" class="php">
$blogOneRoot = Doctrine_Core::getTable('BlogCategories')->find(1); // the primary key of the root node for blog_id 1

$child = new BlogCategories();
$child->blog_id = 1;
$child->name = 'Doctrine';
$child->description = 'Good Doctrine tutorials';
$child->getNode()->insertAsLastChildOf($blogOneRoot);
</pre>
<p>This has now inserteda new child category for blog_id 1.</p>
<p>The last step we&#8217;ll take now is rendering a category tree of a particular blog. For this example again, I&#8217;ll assume blog_id 1.</p>
<pre name="code" class="php">
$categoryTree = Doctrine_Core::getTable('BlogCategories')->getTree();
foreach($categoryTree ->fetchTree(array('root_id' => 1)) as $cat)
{
     echo str_repeat(' ', $cat['level']) . $cat['name'] . "\n";

}
</pre>
<p>And that pretty much covers the basics. It&#8217;s really easy &#8211; once you know how. There are many more cool things that can be done with Doctrine&#8217;s nested set method that I may cover on another day. Have fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kevinbradwick.co.uk/2009/12/introduction-to-doctrines-nested-set/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
