<?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>Doing My Best... a Web Developers Blog &#187; Tutorials</title>
	<atom:link href="http://www.iwilldomybest.com/category/tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.iwilldomybest.com</link>
	<description>Ranging from PHP &#38; MySQL to Random Crap from the internet, I got it all here.</description>
	<lastBuildDate>Sun, 31 Jan 2010 01:46:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>PHP &amp; MySQL Tip #3 &#8211; EAV Modeling w/ PHP &amp; MySQL</title>
		<link>http://www.iwilldomybest.com/2008/08/php-mysql-tip-3/</link>
		<comments>http://www.iwilldomybest.com/2008/08/php-mysql-tip-3/#comments</comments>
		<pubDate>Mon, 25 Aug 2008 22:52:05 +0000</pubDate>
		<dc:creator>dschreck</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[eav]]></category>

		<guid isPermaLink="false">http://www.iwilldomybest.com/2008/08/25/php-mysql-tip-3/</guid>
		<description><![CDATA[PHP &#38; MySQL Tip #3 I want to share with some of you an easy way to set up your database design in a very flexible and reliable EAV like model. EAV stands for Entity Attribute Value, which is a common design for complex database structures that require many different Entities using many different attributes [...]]]></description>
			<content:encoded><![CDATA[<p>PHP &amp; MySQL Tip #3</p>
<p>I want to share with some of you an easy way to set up your database design in a very flexible and reliable EAV like model.</p>
<p><span id="more-20"></span></p>
<p><a title="http://en.wikipedia.org/wiki/Entity-attribute-value_model" href="http://en.wikipedia.org/wiki/Entity-attribute-value_model" target="_blank">EAV</a> stands for Entity Attribute Value, which is a common design for complex database structures that require many different Entities using many different attributes with, again, many different values. It's very common to find this set up in medical offices or records.</p>
<p>Let's go ahead and assume a situation, and we'll work through it.</p>
<p>Let's say you're accepting a feed of some sort, and you need to save the items being fed to you into a database. The problem here, is that the content length of these items, attributes, and values varies.</p>
<p>So let's consider the following:</p>
<pre>Item 'Node1' -&gt;
	Attribute 'Main' -&gt;
		Value 1
		Value 2
		Value 3
		Value 4
Item 'Node2' -&gt;
	Attribute 'Main' -&gt;
		Value 1
		Value 2
		Value 3
		Value 4
	Attribute 'Other' -&gt;
		Value 1
		Value 2

Item 'Node3' -&gt;
	Attribute 'Main' -&gt;
		Value 1
		Value 2
		Value 3
		Value 4
		Value 5
		Value 6
		Value 7
		Value 8</pre>
<p>Now this is a very cheap and generic example of a data structure. But we'll work with it for now.</p>
<p>So let's go ahead and draw some conclusions.</p>
<p>The Item list will come in with a name, and have Attributes. These attributes will have values. But the number of attributes and the number of values varies.</p>
<p>So with that in mind, we shall come up with some SQL to create some times. For this example we're going to need three tables: items, item_attributes, and attribute_values.</p>
<p>So here we go:</p>
<p><code><br />
-- first our items table:<br />
CREATE TABLE `items` (<br />
`id` int(11) NOT NULL auto_increment,<br />
`item_name` varchar(50) default NULL,<br />
PRIMARY KEY  (`id`)<br />
);<br />
-- now our item attributes<br />
CREATE TABLE  `item_attributes` (<br />
`id` int(11) NOT NULL auto_increment,<br />
`item_id` int(11) NOT NULL default '0',<br />
`attribute_name` varchar(50) default NULL,<br />
PRIMARY KEY  (`id`),<br />
KEY `item_id_attribute_name` (`item_id`,`attribute_name`)<br />
);<br />
-- now finally our attribute values<br />
CREATE TABLE  `attribute_values` (<br />
`attribute_id` int(11) NOT NULL default '0',<br />
`attribute_value` varchar(100) default NULL,<br />
UNIQUE KEY `attribute_id` (`attribute_id`,`attribute_value`)<br />
);<br />
</code></p>
<p>Now that we have our layout, let's take a look at how this is going to work:</p>
<p>Let's assume the following PHP array is a reprentation of our data...</p>
<pre>// start up our array
$data = array();
//
// Now, let's just load it with some test data
$data['item_1'] = array();
$data['item_1']['attribute_1'] = array();
$data['item_1']['attribute_1'][] = 'value1';
$data['item_1']['attribute_1'][] = 'value2';
$data['item_1']['attribute_1'][] = 'value3';
$data['item_1']['attribute_1'][] = 'value4';
// that's good for now.
/**
* Now let's insert this int our new schema
*
* Please note, for example sake, I will not be double checking queries
* but you SHOULD check each query for an error.
**/
foreach($data as $item_name =&gt; $attributes)
{
	$sql = "INSERT INTO items (id, item_name) VALUES (NULL, '{$item_name}');";
	mysql_query($sql);
	$item_id = mysql_insert_id();
	// now let's loop through our attributes
	foreach($attributes as $attribute =&gt; $values)
	{
		// this is now our insert into the attributes...
		$sql = "INSERT INTO item_attributes (id, item_id, attribute_name) VALUES (NULL, {$item_id}, '{$attribute}');";
		mysql_query($sql);
		$attribute_id = mysql_insert_id();
		// now let's loop through the attribute values
		foreach($values as $value)
		{
			$sql = "INSERT INTO attribute_values (attribute_id, attribute_value) VALUES ({$attribute_id}, '{$value}');";
			mysql_query($sql);
		}
	}
}
?&gt;</pre>
<p>And there you have it - that's now how we can get our data into our database in a flexiable manner, without having to rely<br />
on an 'excel' like database.</p>
<p>To get it out, we'll simply use some joins...</p>
<p><code><br />
$sql =<br />
"SELECT<br />
items.item_name,<br />
ia.attribute_name,<br />
av.attribute_value<br />
FROM<br />
attribute_values AS av<br />
JOIN item_attributes AS ia<br />
ON (ia.id = av.attribute_id)<br />
JOIN items AS items<br />
ON (items.id = ia.item_id);<br />
";<br />
</code></p>
<p>You could also use a concat_ws to make a comma seperated list, but now that you have it in your database, you can do anything you want with it <img src='http://www.iwilldomybest.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.iwilldomybest.com/2008/08/php-mysql-tip-3/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
