Download - CouchDB at JAOO Århus 2009
![Page 1: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/1.jpg)
CouchDBApache
JAOO October 5th, 2009
Jason Davies
![Page 2: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/2.jpg)
About Jason• Cambridge University (2002-2005)
• Director, Jason Davies Ltd (2005-present)
• Web Developer: Python, Django, JavaScript, jQuery, Erlang, &c.
• Apache CouchDB committer (2009)
![Page 3: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/3.jpg)
CouchDB from
3,333km
![Page 4: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/4.jpg)
CouchDB Features• “Cluster of Unreliable Commodity Hardware”
• Schema-free (JSON)
• Document-oriented, distributed database
• RESTful HTTP API
• JavaScript-powered Map/Reduce
• N-Master Replication
![Page 5: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/5.jpg)
![Page 6: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/6.jpg)
![Page 7: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/7.jpg)
Features• Schema-Free (JSON)
• Document Oriented, Not Relational
• Highly Concurrent
• RESTful HTTP API
• JavaScript-Powered Map/Reduce
• N-Master Replication
• Robust Storage
![Page 8: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/8.jpg)
Features• Schema-Free (JSON)
• Document Oriented, Not Relational
• Highly Concurrent
• RESTful HTTP API
• JavaScript-Powered Map/Reduce
• N-Master Replication
• Robust Storage
![Page 9: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/9.jpg)
Documents
http://www.flickr.com/photos/stilleben2001/223243329/
![Page 10: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/10.jpg)
Schema-Free ( JSON){ "_id": "BCCD12CBB", "_rev": "AB764C",
"type": "person", "name": "Darth Vader", "age": 63, "headware": ["Helmet", "Sombrero"], "dark_side": true}
![Page 11: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/11.jpg)
Schema-Free ( JSON){ "_id": "BCCD12CBB", "_rev": "AB764C",
"type": "person", "name": "Darth Vader", "age": 63, "headware": ["Helmet", "Sombrero"], "dark_side": true}
![Page 12: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/12.jpg)
Schema-Free ( JSON){ "_id": "BCCD12CBB", "_rev": "AB764C",
"type": "person", "name": "Darth Vader", "age": 63, "headware": ["Helmet", "Sombrero"], "dark_side": true}
![Page 13: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/13.jpg)
Schema-Free ( JSON){ "_id": "BCCD12CBB", "_rev": "AB764C",
"type": "person", "name": "Darth Vader", "age": 63, "headware": ["Helmet", "Sombrero"], "dark_side": true}
![Page 14: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/14.jpg)
Features• Schema-Free (JSON)
• Document-Oriented, Not Relational
• Highly Concurrent
• RESTful HTTP API
• JavaScript-Powered Map/Reduce
• N-Master Replication
• Robust Storage
![Page 15: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/15.jpg)
Document-Oriented
• Documents in the Real World™
• Bills, letters, tax forms…
• Same type != same structure
• Can be out of date (so what?)
• No references
Not Relational
![Page 16: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/16.jpg)
Document-Oriented• Documents in the Real World™
• Bills, letters, tax forms…
• Same type != same structure
• Can be out of date (so what?)
• No references
Not Relational
Natural Data Behaviour
![Page 17: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/17.jpg)
Features• Schema-Free (JSON)
• Document-Oriented, Not Relational
• Highly Concurrent
• RESTful HTTP API
• JavaScript-Powered Map/Reduce
• N-Master Replication
• Robust Storage
![Page 18: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/18.jpg)
![Page 19: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/19.jpg)
![Page 20: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/20.jpg)
Highly Concurrent
• Functional languages highly appropriate for parallellism
• Lightweight “processes” and message-passing; “shared-nothing”
• Easy to create fault-tolerant systems
Erlang FTW
![Page 21: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/21.jpg)
MVCC• Multiversion Concurrency Control
• Reads: lock-free; never block
• Potential for massive horizontal scaling
• Writes: all-or-nothing
• Success
• Fail: conflict error, fetch and try again
![Page 22: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/22.jpg)
Features• Schema-Free (JSON)
• Document-Oriented, Not Relational
• Highly Concurrent
• RESTful HTTP API
• JavaScript-Powered Map/Reduce
• N-Master Replication
• Robust Storage
![Page 23: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/23.jpg)
!"#$ful %$$& '&(• Create
HTTP PUT /db/mydocid
• ReadHTTP GET /db/mydocid
• UpdateHTTP PUT /db/mydocid
• DeleteHTTP DELETE /db/mydocid
CRUD
![Page 24: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/24.jpg)
couch = CouchRest.database!("http://127.0.0.1:5984/tweets")
tweets_url = "http://twitter.com/statuses/user_timeline.json"
tweets = http.get(tweets_url)couch.bulk_save(tweets)
!"#$ful %$$& '&(Example
![Page 25: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/25.jpg)
Cacheability• Both documents and views return ETags
• Clients send If-None-Match
• CouchDB responds with 304 Not Modified and bypasses potentially expensive lookup
• Can use Varnish/Squid as caching proxy
• Proxy- friendly
![Page 26: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/26.jpg)
Features• Schema-Free (JSON)
• Document-Oriented, Not Relational
• Highly Concurrent
• RESTful HTTP API
• JavaScript-Powered Map/Reduce
• N-Master Replication
• Robust Storage
![Page 27: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/27.jpg)
JavaScript-Powered Map/Reduce
• Map functions extract data from your documents
• Reduce functions aggregate intermediate values
• The kicker: Incremental B-tree storage
![Page 28: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/28.jpg)
http://horicky.blogspot.com/2008/10/couchdb-implementation.html
![Page 29: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/29.jpg)
Map/Reduce ViewsDocs
Map{"user" : "Chris",
"points" : 3 }{"user": "Joe","points" : 10 }
{"user": "Alice","points" : 5 }
{"user": "Mary","points" : 9}
{"user": "Bob","points": 7}
function(doc) {if (doc.user && doc.points) {
emit(doc.user, doc.points);}
}
{"key": "Alice", "value": 5}{"key": "Bob", "value": 7}
{"key": "Chris", "value": 3}{"key": "Joe", "value": 10}{"key": "Mary", "value": 9}
ReduceAlice ... Chris: 15
Everyone: 34function(keys, values, rereduce) { return sum(values);}
![Page 30: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/30.jpg)
Map/Reduce ViewsDocs
Map{"user" : "Chris",
"points" : 3 }{"user": "Joe","points" : 10 }
{"user": "Alice","points" : 5 }
{"user": "Mary","points" : 9}
{"user": "Bob","points": 7}
function(doc) {if (doc.user && doc.points) {
emit(doc.user, doc.points);}
}
{"key": "Alice", "value": 5}{"key": "Bob", "value": 7}
{"key": "Chris", "value": 3}{"key": "Joe", "value": 10}{"key": "Mary", "value": 9}
ReduceAlice … Chris: 15
Everyone: 34function(keys, values, rereduce) { return sum(values);}
![Page 31: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/31.jpg)
Map/Reduce ViewsDocs
Map{"user" : "Chris",
"points" : 3 }{"user": "Joe","points" : 10 }
{"user": "Alice","points" : 5 }
{"user": "Mary","points" : 9}
{"user": "Bob","points": 7}
function(doc) {if (doc.user && doc.points) {
emit(doc.user, doc.points);}
}
{"key": "Alice", "value": 5}{"key": "Bob", "value": 7}
{"key": "Chris", "value": 3}{"key": "Joe", "value": 10}{"key": "Mary", "value": 9}
ReduceAlice … Chris: 15
Everyone: 34function(keys, values, rereduce) { return sum(values);}
![Page 32: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/32.jpg)
Render Views as HTMLlists/index.js /drl/_list/sofa/index/recent-posts?descending=true&limit=8
![Page 33: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/33.jpg)
Server-Side JavaScript• _show for transforming documents
• _list for transforming views
• _update for transforming PUTs/POSTs
• Code-sharing between client and server
• Easy deployment
![Page 34: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/34.jpg)
Features• Schema-Free (JSON)
• Document-Oriented, Not Relational
• Highly Concurrent
• RESTful HTTP API
• JavaScript-Powered Map/Reduce
• N-Master Replication
• Robust Storage
![Page 35: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/35.jpg)
Replication• Incremental
• Near-real-time
• Clustered mirrors
• Scheduled
• Ad-hoc
![Page 36: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/36.jpg)
http://www.flickr.com/photos/mcpig/872293700/
“Ground Computing”@jhuggins
- local to the user, more like desktop web than like Gears - local http server - browser apps - same application on the client and server or the cloud
![Page 37: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/37.jpg)
http://www.flickr.com/photos/hercwad/2290378571/
![Page 38: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/38.jpg)
Latency Sucks
speed of lightdrawback to cloud computing
![Page 39: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/39.jpg)
! !
Stuart Langridge - Canonical
![Page 40: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/40.jpg)
![Page 41: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/41.jpg)
![Page 42: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/42.jpg)
![Page 43: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/43.jpg)
![Page 44: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/44.jpg)
![Page 45: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/45.jpg)
![Page 46: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/46.jpg)
![Page 47: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/47.jpg)
![Page 48: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/48.jpg)
![Page 49: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/49.jpg)
Con)icts
![Page 50: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/50.jpg)
❦
Con)ict resolution by example
A B
![Page 51: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/51.jpg)
❦❦
Con)ict resolution by example
A B
![Page 52: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/52.jpg)
❦
Con)ict resolution by example
A B
❦ ✿♪
![Page 53: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/53.jpg)
✿♪
Con)ict resolution by example
A B
♪
![Page 54: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/54.jpg)
✿♪
Con)ict resolution by example
A B
♪
![Page 55: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/55.jpg)
Features• Schema-Free (JSON)
• Document-Oriented, Not Relational
• Highly Concurrent
• RESTful HTTP API
• JavaScript-Powered Map/Reduce
• N-Master Replication
• Robust Storage
![Page 56: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/56.jpg)
Robust Storage
Append-Only File Structure
Designed to Crash
Instant-On
![Page 57: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/57.jpg)
Robust
- when britain is burning - Enda Farrell - bbc
![Page 58: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/58.jpg)
No Silver Bullet!• Read-optimised; not so much for writes
• Use ?batch=ok for “don’t care” logging
• Views must be specified beforehand
• Relational databases are better at highly dynamic queries
• But: use externals e.g. Lucene, SQLite
![Page 59: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/59.jpg)
Experiments!
http://www.flickr.com/photos/seanstayte/378461237/
![Page 60: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/60.jpg)
`couchapp`
• Scripts written in Python to make developing pure CouchDB applications easier
• sudo easy_install couchapp
• couchapp generate relax && cd relax
• couchapp push http://127.0.0.1:5984/mydb
![Page 61: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/61.jpg)
Directory Structure
![Page 62: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/62.jpg)
Resulting Design Doc
![Page 63: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/63.jpg)
_list• Arbitrary JS transformation for views
• http://127.0.0.1:5984/mydb/_design/app/_list/myview?startkey=...&endkey=...
• JSON -> HTML, JSON -> XML, ...
• E4X nice for XML generation
• Iteratively call getRow() and use send(...)
![Page 64: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/64.jpg)
_show
• Arbitrary transformation for documents
• http://127.0.0.1:5984/mydb/_design/app/_show/mydoc
• function (doc, req) { return “foo”; }
![Page 65: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/65.jpg)
JavaScript Templating
• EmbeddedJS (EJS)
• <% /* execute arbitrary JS */ %>
• <%= /* execute and include result */ %>
• new EJS({ text: mytemplate }).render(doc);
• John Resig’s Micro-Templating
• new template(mytemplate)(doc);
• Doesn’t preserve whitespace or LaTeX backslashes
![Page 66: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/66.jpg)
Push Helper Macros
• Simple macros to facilitate code re-use
• Insert code directly
• // !code path/to/code.js
• Encode file as JSON: path/to/test.html
• // !json path.to.test
• // !json _attachments/test.html
![Page 67: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/67.jpg)
Secure Cookie Authentication
• Reasonable performance/simplicity of JavaScript implementation
• Mutual authentication
• Resistance to off-line dictionary attacks based on passive eavesdropping
• Passwords stored in a form that is not plaintext-equivalent
• Limited resistance to replay attacks
![Page 68: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/68.jpg)
![Page 69: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/69.jpg)
Tamper-Proof Cookies
Timestamp + signature => limited forward-security (outside of timestamp window)
![Page 70: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/70.jpg)
Secure Remote Password Protocol (SRP)
• Zero-Knowledge Password Proof
• Simple to implement in Erlang using BigInt and crypto libraries
• JavaScript too slow: over 5s for 1024 bits
• Vulnerable to active injection attacks
• There are simpler protocols that can be used to give equivalent security
• Just add SSL for protection from active attacks (or lobby for TLS-SRP/J-PAKE!)
![Page 71: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/71.jpg)
![Page 72: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/72.jpg)
![Page 73: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/73.jpg)
![Page 74: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/74.jpg)
![Page 75: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/75.jpg)
![Page 76: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/76.jpg)
http://books.couchdb.org/relax
@couchdbinaction
![Page 77: CouchDB at JAOO Århus 2009](https://reader034.vdocuments.net/reader034/viewer/2022052617/5481d1beb07959570c8b4608/html5/thumbnails/77.jpg)
Thank you for listening!www.jasondavies.com
@jasondavies