<?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>A.J. Brown&#039;s Blog &#187; CouchDB</title> <atom:link href="http://ajbrown.org/blog/tags/couchdb/feed" rel="self" type="application/rss+xml" /><link>http://ajbrown.org/blog</link> <description>Coding adventures and technology musing for the masses</description> <lastBuildDate>Fri, 26 Mar 2010 17:57:50 +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>Four Reasons to Love CouchDB, Part 2</title><link>http://ajbrown.org/blog/2008/12/30/four-reasons-to-love-couchdb-part-2.html</link> <comments>http://ajbrown.org/blog/2008/12/30/four-reasons-to-love-couchdb-part-2.html#comments</comments> <pubDate>Tue, 30 Dec 2008 11:09:08 +0000</pubDate> <dc:creator>A.J. Brown</dc:creator> <category><![CDATA[Databases]]></category> <category><![CDATA[CouchDB]]></category><guid isPermaLink="false">http://ajbrown.org/blog/?p=109</guid> <description><![CDATA[In "Four Reasons to Love CouchDB, Part 1" I expressed how easy CouchDB is to implement and learn, despite being different than what you'd be used to using any of the many popular database platforms out there.  I even suggested that you don't even have to learn a server-side language to interact with it.  Now, lets move on to our next reason.]]></description> <content:encoded><![CDATA[<ul>Other articles in this series:</p><li><a href="http://ajbrown.org/blog/2008/12/28/four-reasons-to-love-couchdb-part-1.html">Part 1</a></li></ul><p>In "<a href="http://ajbrown.org/blog/2008/12/28/four-reasons-to-love-couchdb-part-1.html">Four Reasons to Love CouchDB, Part 1</a>" I expressed how easy CouchDB is to implement and learn, despite being different than what you'd be used to using any of the many popular database platforms out there.  I even suggested that you don't even have to learn a server-side language to interact with it.  Now, lets move on to our next reason:</p><p></p><h3 id="toc-reason-2-its-not-a-rdbms">Reason #2: It's not a RDBMS</h3><p></p><p>Relational database persist data in a very complex manner.  One of my professors a while ago (do they call them that at Community College?) used an analogy of a garage to show why they don't always make sense.  "If your garage was a RDBMS, and you wanted to store your car in it, you would remove the engine, wheels, steering wheel, gas tank, etc and insert them individually in a neat manner.  When you wanted your car back, you'd select all of the parts and reassemble them."  This works well if you ever want to quickly find the serial number and displacement of your engine,   or want to share tires with another car, but doesn't work well when you (more commonly) just want to drive your car.  Lets not forget to mention the schema changes that would need to be made if you brought home a motorcycle!</p><p><blockquote>CouchDB is a Document-Oriented Database</p></blockquote><p> In MySQL, we're often taught to normalize data to increase performance and reduce data duplication.  This results in lots of "JOIN category ON category.id = article.id, JOIN author ON author.id = article.id" just to fetch all of the useful information for a single object.  CouchDB is a Document-oriented database --  All data for a specific object is self-contained, within the same document.  This results in data being persisted in the same way that we think of it, with sacrifice for data duplication.</p><p>But that doesn't mean that ALL data is duplicated of course.  We can still retain the concept of "foreign keys", but we use them minimally.  The idea is to be <em>semi</em>structured.</p><h4 id="toc-a-real-world-example">A real world example.</h4><p>We want to store articles, each with an article and collection of comments.  We want to be able to show an article on a page, along with it's comments.  We also want to be able to get all comments across all posts for a "latest comments" page.</p><p>In MySQL, we would normally normalize all of this data into separate tables, and create foreign key references.  There would be a single table for<cite>authors</cite>, a table for<cite>articles</cite>, and a table for<cite>comments</cite>.  With this complex schema, we'd end up with queries such as the following</p><div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> articles <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> author <span style="color: #993333; font-weight: bold;">ON</span> author<span style="color: #66cc66;">.</span>id <span style="color: #66cc66;">=</span> article<span style="color: #66cc66;">.</span>author_id <span style="color: #993333; font-weight: bold;">WHERE</span> article<span style="color: #66cc66;">.</span>id <span style="color: #66cc66;">=</span> $articleId</pre></td></tr></table></div><p>To show the article information, and then a second query to show all comments for that article:</p><div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> comments <span style="color: #993333; font-weight: bold;">WHERE</span> article_id <span style="color: #66cc66;">=</span> $articleId</pre></td></tr></table></div><p>In CouchDB, we can easily store all of this data within the same document, without hindering out ability to query it.  Although schema-less, CouchDB does have the concept of "views", which are similar to the concept of Views in RDBMS.  Views are functions stored within special documents called "design documents".  They contain a field named "views" which is an array of  JavaScript (the default language) functions used to filter (map) and sort (key) document data, and to generate aggregate results (reduce).</p><p>The following document represents all of the data we stored in our MySQL schema above, except that it's all stored within one object.</p><div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;id&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;article_id_2&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;type&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;article&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;title&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Some Title&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;author&quot;</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
          <span style="color: #3366CC;">&quot;name&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;A.J. Brown&quot;</span><span style="color: #339933;">,</span> 
          <span style="color: #3366CC;">&quot;email&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;nospam@ajbrown.org&quot;</span> 
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    . . . 
    <span style="color: #3366CC;">&quot;comments&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span>
        <span style="color: #009900;">&#123;</span> 
            <span style="color: #3366CC;">&quot;name&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;John Smith&quot;</span><span style="color: #339933;">,</span> 
            <span style="color: #3366CC;">&quot;text&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;A.J. Brown is the best, ever&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;created&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;2008-12-21 01:23:24 AM&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#123;</span> 
            <span style="color: #3366CC;">&quot;name&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Jane Applebees&quot;</span><span style="color: #339933;">,</span> 
            <span style="color: #3366CC;">&quot;text&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;I totally agree with John&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;created&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;2008-12-21 02:55:24 AM&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#93;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div><p>Although everything is stored within the structure of a single document, We can still get all of the data we need easily. We just need a view that will key our documents on the article id:</p><div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> map <span style="color: #009900;">&#40;</span> doc <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span> doc.<span style="color: #660066;">type</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">'article'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          emit<span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span> doc <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div><p>This function says <em>"Show me all documents with a field named "type" that has a value of "article", and sort and collate (key) them by their document id"</em>.  Now we can call the view and get all articles and their comments. By adding "?key=<document_id>" to the URL for our view, we can retrieve only 1 post. </document_id></p><p>To retrieve only all comments of all posts, we'll need to create a second view.  This view will extract the comments from every document has a type=article, and collate them by them by the comment's created field.</p><p></p><div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> map <span style="color: #009900;">&#40;</span> doc <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #000066; font-weight: bold;">in</span> doc.<span style="color: #660066;">comments</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		emit<span style="color: #009900;">&#40;</span>doc.<span style="color: #660066;">comments</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">created</span><span style="color: #339933;">,</span> doc.<span style="color: #660066;">comments</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div><p></p><p>Our resultset would look something like this: (note, view result sets have key and id information.  I've left those out for simplicity sake):</p><p></p><div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">        <span style="color: #009900;">&#123;</span> 
            <span style="color: #3366CC;">&quot;name&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;John Smith&quot;</span><span style="color: #339933;">,</span> 
            <span style="color: #3366CC;">&quot;text&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;A.J. Brown is the best, ever&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;created&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;2008-12-21 01:23:24 AM&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#123;</span> 
            <span style="color: #3366CC;">&quot;name&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Jane Applebees&quot;</span><span style="color: #339933;">,</span> 
            <span style="color: #3366CC;">&quot;text&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;I totally agree with John&quot;</span><span style="color: #339933;">,</span>
            <span style="color: #3366CC;">&quot;created&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;2008-12-21 02:55:24 AM&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></td></tr></table></div><p></p><p>Since we keyed our view on the comments created field,we can easily narrow our results by date by specifying a<cite>startKey</cite> and an<cite>endKey</cite> in our request URI:</p><p><cite>http://couchserver/database/_view/articles/comments?startkey=["2008-12-21 02:00:00 AM"]</cite></p><p>This would only return "Jane Applebee's" comment, since the specified start key come sequentially after the rest of the results.</p><p><blockquote>Handling the custom fields is simple with CouchDB</p></blockquote><h4 id="toc-conclusion">Conclusion</h4><p>Storing data this way makes a lot of sense in a lot of cases.  For example, my newest project needs to be able to store system events.  Every event has (and enforces) a standard set of fields, but there may be additional custom (unpredictable) fields as well, as defined by whatever process sends the event.  Those custom fields must be available for querying by any program that does know of them.  Handling the custom fields is simple with CouchDB -- I just add them to the document being stored.  A relational database schema for this data model would be complex and hard to follow.</p><p>RDMS's are powerful, but sometimes they're overkill for our applications.  I've seen some hypothesis suggesting that CouchDB's document oriented strategy would work for  90% of web applications today.  Who knows how accurate that is, but it definitely makes you think.  After all, you can't get any more cutting edge than a database engine asking us to rethink how we model data which is written in a language that asks us to rethink parallel processing.</p><p>Check back tomorrow for Reason #3</p><p>Special thanks to the following blogs for helping me get started with CouchDb:</p><ul><li><a href="http://www.cmlenz.net/">about:cmlenz</a></li><li><a href="http://horicky.blogspot.com/2008/10/couchdb-implementation.html">Ricky Ho</a></li><li><a href="http://barkingiguana.com/2008/06/28/installing-couchdb-080-on-ubuntu-804">Barking Ignuana</a></li></ul> ]]></content:encoded> <wfw:commentRss>http://ajbrown.org/blog/2008/12/30/four-reasons-to-love-couchdb-part-2.html/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Four Reasons to Love CouchDB, Part 1</title><link>http://ajbrown.org/blog/2008/12/28/four-reasons-to-love-couchdb-part-1.html</link> <comments>http://ajbrown.org/blog/2008/12/28/four-reasons-to-love-couchdb-part-1.html#comments</comments> <pubDate>Mon, 29 Dec 2008 06:14:22 +0000</pubDate> <dc:creator>A.J. Brown</dc:creator> <category><![CDATA[Databases]]></category> <category><![CDATA[CouchDB]]></category><guid isPermaLink="false">http://ajbrown.org/blog/?p=114</guid> <description><![CDATA[This is a multi-part series on why you should consider CouchDB for your next project.  CouchDB is a distributed, fault-tolerant and schema-free document-oriented database accessible via a RESTful HTTP/JSON API.  It redefines the typical relational database storage schema by using a schema-less Document oriented storage strategy, better fitting for most web applications.]]></description> <content:encoded><![CDATA[<ul>Other articles in this series:</p><li><a href="http://ajbrown.org/blog/2008/12/30/four-reasons-to-love-couchdb-part-2.html">Part 2</a></li></ul><p>I've been sensing a lot of hype around <a href="http://couchdb.apache.org">CouchDB</a> lately, and I recently decided to give it a try.  After about ~30 hours of working with it, and a successful prototype of a project driven by CouchDB (and special shout-out to <a href="http://ajbrown.org/blog/topics/php/zend-framework">Zend Framework</a> and <a href="http://weierophinney.net/phly/">Phly</a>),  I think I may have found a favorite new toy to share it with you.</p><p>This will be a multi-part series with each article touching on a single aspect of CouchDB.  I enjoy MySQL and PostgreSQL as well, so I hope these posts aren't taken as a knock on them, but more of a thumbs up to CouchDB.</p><h4 id="toc-what-is-couchdb">What is CouchDB</h4><p>Taken straight from their website, "Apache CouchDB is a distributed, fault-tolerant and schema-free document-oriented database accessible via a RESTful HTTP/JSON API."  It's designed to drive today's rich internet applications with scalability and even offline-operation in mind.  If you're interested in reading technical inforamtion about CouchDB, check out:</p><ul><li><a href="http://couchdb.apache.org/index.html">Apache CouchDb's Website</a></li><li><a href="http://books.couchdb.org/relax/why-couchdb">Why CouchDB?</a></li><li><a href="http://damienkatz.net/">Damien Katz, Creator and Project Lead</a></li></ul><p></p><h3 id="toc-reason-1-its-easy-to-learn">Reason #1:  It's Easy To Learn</h3><p></p><p>My first experience with databases was Microsoft Access.  I remember writing a Maxis fan site in ASP using an Access database which I manually updated every so often to store all of my content.  I was able to leverage the "power" of Access (note: I was 13 or so at the time.), but it took a bit for me to really comprehend the features, and how my data should best be stored.</p><p>Fast forward to now.  Companies are paying database administrators pretty good salaries for their database engineering skills.  Even companies with rather simple data-structures need an experienced and talented database developer to keep their data schema scalable.  It's becoming a very specialized skill, such as the multi-hat of "Webmaster" has nearly vanished and split into "Graphics Designer", "Web Programmer", and "Systems Administrator" (in the simplest of cases).  Writing queries can be the simplest thing you've ever done, or can cause you to pull out your hair, depending on the data needed.  Lets not get into replication and clustering.</p><p><blockquote>Database systems aren't simple bread baskets.</p></blockquote><p>CouchDB is very easy to learn.  That's actually a two-part reason, depending on your expertise.  If you're a developer or database expert, It's not that MySQL or PostgreSQL are hard to learn, but rather that CouchDB is easy to pick up and run with despite being philosophically different.  Thinking outside of the box of relational data that has been etched into my brain for the past 8 years was tough at first, but within a few hours of reading examples and playing around with it, I was able to start harnessing the full feature-suite.</p><p><blockquote>Who needs a server-side language, anyway?</p></blockquote><p>If you're a front-end developer who's never worked with a programming language other than JavaScript or Flex, there's no SQL or complex protocol to learn.  In fact, you don't need any application layer whatsoever to start playing around with it:  CouchDB operates completely over HTTP.  It cuts out the "middle man" by serving data in JSON.  Hell, the administration tools is completely AJAX based.  Creating databases and views, querying data, and modifying data is done all through a RESTful interface.  Imagine a world where Flex developers don't even have to talk to PHP developers <img src='http://ajbrown.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p><p>I encourage you to start playing around with CouchDB.  Keep in mind that CouchDB is still in an incubation phase, so it hasn't even met its full potential yet.  This project is very exciting to me, and I will continue to watch it's progress.</p> ]]></content:encoded> <wfw:commentRss>http://ajbrown.org/blog/2008/12/28/four-reasons-to-love-couchdb-part-1.html/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
