<?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>Aphelion Web Development Blog</title>
	<atom:link href="http://apheliondynamics.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://apheliondynamics.com/blog</link>
	<description>Keep it simple, keep it fast, less is more.</description>
	<lastBuildDate>Fri, 04 Nov 2011 15:09:26 +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>Database Optimization: Vertical Partitioning in MySQL</title>
		<link>http://apheliondynamics.com/blog/2010/02/11/database-optimization-vertical-partitioning-in-mysql/</link>
		<comments>http://apheliondynamics.com/blog/2010/02/11/database-optimization-vertical-partitioning-in-mysql/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 05:44:12 +0000</pubDate>
		<dc:creator>Fadi Chalfoun</dc:creator>
				<category><![CDATA[Database Systems]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[database optimization]]></category>
		<category><![CDATA[full table scan]]></category>
		<category><![CDATA[innodb]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[vertical partition]]></category>
		<category><![CDATA[vertical split]]></category>

		<guid isPermaLink="false">http://apheliondynamics.com/blog/?p=23</guid>
		<description><![CDATA[Introduction When considering the architecture of your database, you must be wary of allowing your tables to contain more columns than necessary to accomplish the majority of queries associated with that table. You might have heard of normalization, which is the process of organizing your tables in a way that minimizes both redundancy and data [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>When considering the architecture of your database, you must be wary of allowing your tables to contain more columns than necessary to accomplish the majority of queries associated with that table. You might have heard of <strong>normalization</strong>, which is the process of organizing your tables in a way that minimizes both redundancy and data manipulation anomalies (insert, delete, update). While this process usually results in splitting tables, the reasons we perform a vertical partition differ from those of partitioning. <strong>Vertical Partitioning</strong> in our context will be defined as breaking apart the columns of high <strong>cardinality</strong> (number of columns) tables into distinct smaller tables based on <strong>frequency of usage</strong> of each column or set of columns. While some definitions require that the tables be in Boyce Codd Normal Form [1, p.584], in practice, this might not always be optimal. This depends on your own situation and what works best for you.</p>
<h2>A Deeper Look At the Internals: Disk Storage and Memory Access</h2>
<p>In many cases, you will not always be able to utilize a key of the table to perform a query. This is when a <strong>full table scan</strong> is performed. A full table scan is when you access all of the data sequentially to operate. In some cases, this is actually better than using a key. When a row is matched using a key a seek is performed to retrieve that row, if a large amount of rows are matched then you may end up performing more seeks than you a would with a full table scan. [2][3]</p>
<h3>Memory Blocks</h3>
<p>For a full table scan, when the database wants to find matching rows it must first pull all the rows sequentially into memory and perform its work. The DBMS can only pull in finite amount of data into memory to work on it. These chunks of finite data that the DBMS reads in known as a <strong>Memory Block</strong>. For instance, <strong>InnoDB uses a 16Kb page size</strong> [4] which means that it will pull records into memory 16kb at a time to perform work on it. Think of a page of memory as a &#8220;window&#8221; into a segment of memory on your system that is used to pull data and work with it. We can now determine how many records can be pulled into each block of memory by determining (1) the record length (size of an individual row) (2) the block size. [1, p.503] </p>
<p><img src="http://apheliondynamics.com/blog/wp-content/uploads/2010/02/mem-block-diagrams.png" alt="" title="mem-block-diagrams" width="549" height="504" class="aligncenter size-full wp-image-32" /></p>
<h3>Let&#8217;s look at a simple example:</h3>
<p>- Suppose a record length (determined by the sum of the sizes of each column in the row) is 1.5kb.<br />
- If we are using InnoDB the page size is 16kb.<br />
- Table size is 1500kb</p>
<p>The number of records per block is: floor(block size / record length) = floor(16 / 1.5) = <strong>10 records per block</strong>. This is known as the <strong>Blocking Factor</strong>. [1, p.503]<br />
To read the whole table into memory we determine this by: ceil(table size / blocking factor) = ceil(1500 / 10) = <strong>150 block reads</strong>. [1, p.503]</p>
<p>The time a block read takes depends on the seek time of the disk. However, we can intuitively determine that the less number of blocks needed to read into memory, the less the number of seeks to perform and thus faster performance. This also applies when scanning with keys, so for this context we will not differentiate between using or not using a key, that is reserved for a different discussion. Also, whenever you run a query a certain number of times the contents of that query get &#8220;<strong>warmed up</strong>&#8221; into the OS&#8217;s cache so <strong>consequent executions of the query will not cause a disk seek</strong> [5]. However, this does not mean that memory block reads are not performed anymore, the <strong>number of block reads remain constant</strong>, however their speed is greatly improved from accessing the RAM or other caches on the system instead of going to the hard drive. This means that while the block read is faster [6], it will still slow down as your data scales.</p>
<p>This is the hand-waiving explanation as to why reducing the number of columns to that only those needed most for the highest number of queries is important. Now let&#8217;s look at some real numbers to see the difference.</p>
<h2>A Practical Example of Vertical Partitioning</h2>
<p>For these query timing tests we will have the query cache turned off and will not be using keys to optimize any queries. Also all queries are &#8220;warmed up&#8221; as that was the best way for me to get consistent measurements.</p>
<p>Let&#8217;s suppose we are running a social networking site and we have a &#8220;user&#8221; table that contains many attributes of that user, as portrayed here (I am using MySQL Workbench to model the data):</p>
<p><img src="http://apheliondynamics.com/blog/wp-content/uploads/2010/02/user-big.png" alt="" title="Big User Table" width="182" height="412" class="aligncenter size-full wp-image-39" /></p>
<p>This table is not, in fact, overly-large. However, there is room for improvement. As you can imagine, many queries will be executed that do not need to consider all of these columns, and as described earlier means more block processing and the extra I/O will slow us down. Because I wanted the data to model very closely what a real-world data set might look like (instead of random data) I wrote a script that creates random suitable values for each column. Here is an example of a row in the user table in CSV format:</p>
<p>1, Jeff, Dara, Dara1265430074695@example.com, c2e3103d28633677e173839977ce47c2, 2010-01-08 01:44:18, 0, NULL, NULL, NULL, NULL, NULL, 0, 0, 1, NULL, NULL<br />
2, Noah, Kit, Kit1265430074768@example.com, 6c6a9ac3d5ea78d67f0a9c2364a4bf61, 2010-01-06 10:22:14, 0, Pittsburgh, NY, 60336, 5554206162, Kit1265430074326@example.com, 1, 0, 0, Poway, 2009-12-29 17:53:30</p>
<p>Because some of the fields were nullable I made 1 in 5 records use NULL for those records to better simulate a variety in the data input. Also the city/state names were completely randomized, so the table ended up having incorrect city/state pairings but for the purposes of this test that wasn&#8217;t really important.</p>
<p>Here are the queries that we will be running against the database:</p>
<h4>Query&#8217;s Goal: A user attempts to log in, we check the user-entered password/email with our existing records. As a side note: In a real environment, for security purposes, you should never save your passwords in plain text, therefore, we are saving all of our passwords as the MD5 of their password.</h4>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">SELECT</span>  <span style="color: #008000;">`id`</span> <span style="color: #000033;">,</span>  <span style="color: #008000;">`first<span style="color: #008080; font-weight: bold;">_</span>name`</span> <span style="color: #000033;">,</span>  <span style="color: #008000;">`last<span style="color: #008080; font-weight: bold;">_</span>name`</span> 
<span style="color: #990099; font-weight: bold;">FROM</span>  <span style="color: #008000;">`user`</span> 
<span style="color: #990099; font-weight: bold;">WHERE</span>  <span style="color: #008000;">`email`</span> <span style="color: #CC0099;">=</span>  <span style="color: #008000;">'Dara1265430074695@example.com'</span> <span style="color: #CC0099; font-weight: bold;">AND</span>  <span style="color: #008000;">`password`</span> <span style="color: #CC0099;">=</span>  <span style="color: #008000;">'c2e3103d28633677e173839977ce47c2'</span><span style="color: #000033;">;</span></pre></div></div>

<h4>Query&#8217;s Goal: We want to send out an email blast to all of our Tucson users that haven&#8217;t logged in since last year while honoring their email preferences, perhaps we want to remind them of our application and to get back on.</h4>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #008000;">`id`</span> <span style="color: #000033;">,</span> <span style="color: #008000;">`first<span style="color: #008080; font-weight: bold;">_</span>name`</span> <span style="color: #000033;">,</span> <span style="color: #008000;">`last<span style="color: #008080; font-weight: bold;">_</span>name`</span> <span style="color: #000033;">,</span> <span style="color: #008000;">`email`</span> 
<span style="color: #990099; font-weight: bold;">FROM</span> <span style="color: #008000;">`user`</span> 
<span style="color: #990099; font-weight: bold;">WHERE</span> <span style="color: #008000;">`city`</span> <span style="color: #CC0099;">=</span> <span style="color: #008000;">'Tucson'</span> <span style="color: #CC0099; font-weight: bold;">AND</span> <span style="color: #008000;">`receive<span style="color: #008080; font-weight: bold;">_</span>digest`</span> <span style="color: #CC0099;">=</span> <span style="color: #008080;">1</span> <span style="color: #CC0099; font-weight: bold;">AND</span> <span style="color: #000099;">YEAR</span><span style="color: #FF00FF;">&#40;</span> <span style="color: #008000;">`last<span style="color: #008080; font-weight: bold;">_</span>login`</span> <span style="color: #FF00FF;">&#41;</span> <span style="color: #CC0099;">=</span> <span style="color: #008080;">2009</span><span style="color: #000033;">;</span></pre></div></div>

<h4>Query&#8217;s Goal: We want to graph a trend of our performance history, monitoring the number of new signups we are getting on a monthly basis. Hopefully the numbers are looking good for our performance review.</h4>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">SELECT</span> <span style="color: #000099;">COUNT</span><span style="color: #FF00FF;">&#40;</span> <span style="color: #008080;">1</span> <span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">AS</span> <span style="color: #000099;">count</span><span style="color: #000033;">,</span> <span style="color: #000099;">MONTH</span><span style="color: #FF00FF;">&#40;</span>  <span style="color: #008000;">`date<span style="color: #008080; font-weight: bold;">_</span>registered`</span> <span style="color: #FF00FF;">&#41;</span> <span style="color: #000033;">,</span> <span style="color: #000099;">YEAR</span><span style="color: #FF00FF;">&#40;</span>  <span style="color: #008000;">`last<span style="color: #008080; font-weight: bold;">_</span>login`</span> <span style="color: #FF00FF;">&#41;</span> 
<span style="color: #990099; font-weight: bold;">FROM</span>  <span style="color: #008000;">`user`</span>  
<span style="color: #990099; font-weight: bold;">GROUP BY</span> <span style="color: #000099;">MONTH</span><span style="color: #FF00FF;">&#40;</span>  <span style="color: #008000;">`date<span style="color: #008080; font-weight: bold;">_</span>registered`</span> <span style="color: #FF00FF;">&#41;</span> <span style="color: #000033;">,</span> <span style="color: #000099;">YEAR</span><span style="color: #FF00FF;">&#40;</span>  <span style="color: #008000;">`date<span style="color: #008080; font-weight: bold;">_</span>registered`</span> <span style="color: #FF00FF;">&#41;</span></pre></div></div>

<p>Most of these queries only use a subset of the columns stored in the table. I created 3 separate versions of this same table with 1000, 10,000 and 100,000 records each with populated data.  Before I show the times for these queries I want to first introduce the &#8220;split&#8221; version of this table, then give a side by side comparison of the performance difference. Here is the proposed design change:</p>
<p><img src="http://apheliondynamics.com/blog/wp-content/uploads/2010/02/user-split.png" alt="" title="Split User Tables" width="661" height="304" class="aligncenter size-full wp-image-40" /></p>
<p>The large user table has been split into different tables in order to not only accommodate our common queries but in a structure that makes good logical sense. The rest of the development will also appreciate the setup. Keep in mind we are <strong>not normalizing</strong> our table as mentioned earlier, we did not address our functional dependencies, the &#8220;user_address&#8221; table is still in second normal form as was the original user table. However, it is acceptable in some situations to intentionally leave the table in a lower-order form for performance reasons, this is called <strong>denormalization</strong>.</p>
<p>Now that we have seen the proposed design change, let&#8217;s see now how this changed out performance:</p>
<p><img src="http://apheliondynamics.com/blog/wp-content/uploads/2010/02/singe-row-lookup.jpg" alt="" title="Single Row Lookup" class="aligncenter size-full wp-image-40" /><br />
<img src="http://apheliondynamics.com/blog/wp-content/uploads/2010/02/joining-query.jpg" alt="" title="Multi-row Conditional Lookup" class="aligncenter size-full wp-image-40" /><br />
<img src="http://apheliondynamics.com/blog/wp-content/uploads/2010/02/aggregate-query.jpg" alt="" title="Multi-row Aggregate Lookup" class="aligncenter size-full wp-image-40" /></p>
<h2>Conclusion</h2>
<p>Having too many columns can bloat your record size, which in turn results in more memory blocks being read in and out of memory causing <strong>higher I/O</strong>. This can hurt performance. One way to combat this is to <strong>split your tables</strong> into smaller more independent tables with smaller cardinalities than the original. This should now allow for a <strong>better Blocking Factor</strong> (as defined above) which means less I/O and <strong>faster performance</strong>. This process of breaking apart the table like this is a called a <strong>Vertical Partition</strong>. There is a catch, however, as you might have noticed on the second chart, the <strong>performance actually dropped</strong> after breaking apart the tables. This happened because of <strong>all the expensive JOIN operations</strong> that were required to get the desired information. Keep in mind that if you are to break apart your tables, make sure you try to minimize the number of JOIN operations you will need to end up doing to get the same data set back that you used to. In our example we can justify the performance hit by claiming that the overall benefit of having the split table is better than having them together, and that the query used to join all those tables doesn&#8217;t occur frequently. This catch reminds us that there are <strong>no black and white solutions</strong> when it comes to database design and optimization, you always have to do what is best for your situation.</p>
<h3>REFERENCES</h3>
<p>[1] &#8211; Elmasri and Navathe. <strong>Fundamentals of Database Systems</strong>. Boston: 2007.<br />
[2] &#8211; MySQL Documentation &#8211; 7.4.4. <strong>How MySQL Uses Indexes</strong> &#8211; http://dev.mysql.com/doc/refman/5.5/en/mysql-indexes.html<br />
[3] &#8211; <strong>IBM solidDB Sql Guide</strong>, Full table scan &#8211; http://publib.boulder.ibm.com/infocenter/soliddb/v6r3/index.jsp?topic=/com.ibm.swg.im.soliddb.sql.doc/doc/full.table.scan.html<br />
[4] &#8211; <strong>InnoDB Plugin 1.0 for MySQL 5.1</strong> (Early Adopter Release) User&#8217;s Guide &#8211; http://www.innodb.com/doc/innodb_plugin-1.0/<br />
[5] &#8211; MySQL Documentation &#8211; 7.4.6. <strong>The InnoDB Buffer Pool</strong> &#8211; http://dev.mysql.com/doc/refman/5.0/en/innodb-buffer-pool.html<br />
[6] &#8211; MySQL Documentation &#8211; <strong>A Practical Look at the MySQL Query Cache</strong> &#8211; http://dev.mysql.com/tech-resources/articles/mysql-query-cache.html</p>
]]></content:encoded>
			<wfw:commentRss>http://apheliondynamics.com/blog/2010/02/11/database-optimization-vertical-partitioning-in-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Power of JQuery .data() and a Practical Example</title>
		<link>http://apheliondynamics.com/blog/2010/01/19/the-power-of-jquery-data-and-a-practical-example/</link>
		<comments>http://apheliondynamics.com/blog/2010/01/19/the-power-of-jquery-data-and-a-practical-example/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 06:57:12 +0000</pubDate>
		<dc:creator>Fadi Chalfoun</dc:creator>
				<category><![CDATA[Javscript]]></category>

		<guid isPermaLink="false">http://apheliondynamics.com/blog/?p=5</guid>
		<description><![CDATA[Introduction Jquery .data() is an excellent tool that allows you to treat DOM elements as containers of data without actually manipulating the DOM structure itself. Have you ever saved information not shown to the user in the DOM structure (such as in the &#8220;title&#8221; tag) and wished there was a better way to do it? [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Jquery .data() is an excellent tool that allows you to <strong>treat DOM elements as containers of data</strong> without actually manipulating the DOM structure itself. Have you ever saved information not shown to the user in the DOM structure (such as in the &#8220;title&#8221; tag) and wished there was a better way to do it? If so, then Jquery .data() is the perfect tool for you! You can &#8220;attach&#8221; <strong>key/value pairs</strong> of data to a specific DOM element like so:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">//Set data</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'showNavBar'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">//Get data</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'showNavBar'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// true</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">showNavBar</span> <span style="color: #006600; font-style: italic;">// true</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'body'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// {showNavBar: true}</span></pre></div></div>

<p>Yes it&#8217;s that easy! But where does this data really go? <strong>It goes in the cache</strong> for quick and easy access, if we dive into the JQuery library (version 1.4 is shown here) we can see where it&#8217;s being put in the cache. I am showing only a segment of the data function as seen in the library (if you want to see the rest of it I recommend you look in the library lines 963-1004):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Avoid generating a new cache unless none exists and we</span>
<span style="color: #006600; font-style: italic;">// want to manipulate it.</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">typeof</span> <span style="color: #000066;">name</span> <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;object&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	elem<span style="color: #009900;">&#91;</span> expando <span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> id<span style="color: #339933;">;</span>
	thisCache <span style="color: #339933;">=</span> cache<span style="color: #009900;">&#91;</span> id <span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> jQuery.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #000066;">name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> cache<span style="color: #009900;">&#91;</span> id <span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	thisCache <span style="color: #339933;">=</span> cache<span style="color: #009900;">&#91;</span> id <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">typeof</span> data <span style="color: #339933;">===</span> <span style="color: #3366CC;">&quot;undefined&quot;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	thisCache <span style="color: #339933;">=</span> emptyObject<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
	thisCache <span style="color: #339933;">=</span> cache<span style="color: #009900;">&#91;</span> id <span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Prevent overriding the named cache with undefined values</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> data <span style="color: #339933;">!==</span> undefined <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	elem<span style="color: #009900;">&#91;</span> expando <span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> id<span style="color: #339933;">;</span>
	thisCache<span style="color: #009900;">&#91;</span> <span style="color: #000066;">name</span> <span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> data<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h2>Example</h2>
<p>So now we know how to save arbitrary data (values of keys can be of any type) to specific DOM elements, what could we do with something like this? As mentioned earlier we can treat DOM elements as containers of internal data, not just containers for holding data shown to the user, let&#8217;s take a look the amazing <strong>house finder application</strong>, this can handle searches such as &#8220;$100,000&#8243;, &#8220;1200 square feet&#8221;, &#8220;2 stories&#8221; and any variation of those numbers, there isn&#8217;t much error checking or such so please treat it gently:</p>
<p><a href="http://www.apheliondynamics.com/blog/house-finder/jquery-data-example.html" target="_blank">House Finder JQuery .data() Example</a></p>
<p>Let&#8217;s first take a look at the <strong>final</strong> structure of the container for each house:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;house1&quot;</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h1</span>&gt;</span>100 N. Green Hills Dr.<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h1</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">img</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;house1.jpg&quot;</span> <span style="color: #000066;">alt</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h2</span>&gt;</span>$140,000<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h2</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h3</span>&gt;</span>Roomy home out in the country side<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h3</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">h4</span>&gt;</span>2 story house (2400 square feet)<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">h4</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></pre></div></div>

<p>Notice that there is <strong>no special code</strong> to contain extra attributes or to help extract the values from the DOM as we won&#8217;t need to! We will initialize our base data here:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#house1'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> id<span style="color: #339933;">:</span><span style="color: #CC0000;">1</span><span style="color: #339933;">,</span> price<span style="color: #339933;">:</span><span style="color: #CC0000;">140000</span><span style="color: #339933;">,</span> stories<span style="color: #339933;">:</span><span style="color: #CC0000;">2</span><span style="color: #339933;">,</span> squareFeet<span style="color: #339933;">:</span><span style="color: #CC0000;">2400</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Now that we have our DOM and data all setup let&#8217;s put this code into action, first let&#8217;s add a search box with a button that will trigger our event to handle the search:</p>
<p>Some markup for the search field and button.</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span> <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">button</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;search&quot;</span>&gt;</span>Search<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">button</span>&gt;</span></pre></div></div>

<p>Bind the click event of the search button:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#search&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> filterHouses<span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'input'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The core of the code is right here where we filter the house data based on criteria and existing data of each house:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> filterHouses<span style="color: #009900;">&#40;</span>searchString<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> sortByPrice <span style="color: #339933;">=</span> sortByStories <span style="color: #339933;">=</span> sortBySquareFeet <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>searchString.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\$/</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #006600; font-style: italic;">//Searching by price</span>
	<span style="color: #009900;">&#123;</span>
		sortByPrice <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> priceCriteria <span style="color: #339933;">=</span> searchString.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/\$|[^0-9]/g</span><span style="color: #339933;">,</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>searchString.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;story&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		sortByStories <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> storyCriteria <span style="color: #339933;">=</span> searchString.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/[^0-9]/g</span><span style="color: #339933;">,</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>searchString.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;square feet&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		sortBySquareFeet <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> squareFeetCriteria <span style="color: #339933;">=</span> searchString.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/[^0-9]/g</span><span style="color: #339933;">,</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	$.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#houses div'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">,</span> house<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		$house <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>house<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> houseData <span style="color: #339933;">=</span> $house.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>houseData.<span style="color: #660066;">disposition</span> <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>sortByPrice <span style="color: #339933;">&amp;&amp;</span> houseData.<span style="color: #660066;">price</span> <span style="color: #339933;">&lt;=</span> priceCriteria<span style="color: #009900;">&#41;</span>
				<span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>sortByStories <span style="color: #339933;">&amp;&amp;</span> houseData.<span style="color: #660066;">stories</span> <span style="color: #339933;">==</span> storyCriteria<span style="color: #009900;">&#41;</span>
				<span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>sortBySquareFeet <span style="color: #339933;">&amp;&amp;</span> houseData.<span style="color: #660066;">squareFeet</span> <span style="color: #339933;">&gt;=</span> squareFeetCriteria<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			$house.<span style="color: #660066;">animate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>opacity<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			houseData.<span style="color: #660066;">matching</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000066; font-weight: bold;">else</span>
		<span style="color: #009900;">&#123;</span>
			$house.<span style="color: #660066;">animate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>opacity<span style="color: #339933;">:</span> <span style="color: #CC0000;">0.5</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			houseData.<span style="color: #660066;">matching</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Take note that first of all we are only iterating through the <strong>divs themselves</strong>, not an external data structure that we have to manage. Also, when we come to extract the data associated with each house we are <strong>not</strong> reading the HTML of the DOM itself but instead using .data() to return the values (remember from the cache) for us in a clean format (lines 162-172). In this way we are treating our house div as not just a presentational element but it houses (pun not intended <img src='http://apheliondynamics.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  its own attributes in very convenient fashion. We can almost think of the house divs as objects in which we can set and get all the values we want from it without doing expensive DOM manipulations and string processing. Very clean!</p>
<p>It gets even better when we think of being able to add new data on the fly and handling it without changing the DOM structure, looking at the code to like/dislike a house we can see how powerful Jquery .data() can get:</p>
<p>Some markup for plus and minus sign buttons to represent the user liking and disliking the houses:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;dislike&quot;</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;disposition&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>-<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">a</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;like&quot;</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;disposition&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;#&quot;</span>&gt;</span>+<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">a</span>&gt;</span></pre></div></div>

<p>Bind the click event for these buttons:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#like'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">parent</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">animate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>opacity<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">disposition</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#dislike'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">parent</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">animate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>opacity<span style="color: #339933;">:</span> <span style="color: #CC0000;">0.5</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">data</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">disposition</span> <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>Notice how easy it is to remember the user&#8217;s disposition towards a specific house, aside from the fancy animate effects, remembering that the user dislikes or likes a certain house is a matter of once again just referencing a (new) variable belonging to the div&#8217;s data we are keeping track of. This data was also used earlier when we were filtering the houses to know if we should consider or throw out a house even if it doesn&#8217;t match or matches the criteria.</p>
<h2>Conclusion</h2>
<p>JQuery .data() is shown here to be a useful tool in remembering data associated with elements on the screen without the need to store information in the DOM itself or through externally managed data structures such as an array which would be much more messy than handling your data this way. Not only is this method easy to use and keeps your code clean, but JQuery saves this data in the cache for some great performance as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://apheliondynamics.com/blog/2010/01/19/the-power-of-jquery-data-and-a-practical-example/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>

