Given at Refresh Savannah last November. The slides are really spare, but man was this a fun one to give.
Now we know what it’s not... what is it?
What are we running
• Relational databases are the defacto
standard for storing data in a web
• A lot of times, that data isn’t really
relational at all.
• RDBMS’s have lots of rules that can impact
Rules? What Rules?
• Classic relational databases follow the
• If any part of the update fails, it all fails.
• Databases have to be able to lock tables
and rows for operations, which can block
or delay other incoming requests.
• After a transaction, all copies of the data
must be consistent with each other (my
• Replication across lots of shards is
expensive especially if there’s locking
• Data involved in a transaction must be
inaccessible to other operations.
• Remember the thing about locked rows
• It’s a bummer.
• Once a user is notiﬁed that a transaction
has completed, the data must be accessible
and all integrity constraints have been met.
I come not to bury
• Relational databases are great for a lot of
• If you have data that’s actually relational and
you need transactions, joins and have a
limited number of data types, then an
RDBMS will work for you.
• RDBMS’s have been
treated like hammers
and used for things
they’re not good at and
weren’t designed for.
• Like the web...
Thus were born...
• Key-Value Stores
• Wide-Column Stores
• Document Stores/Databases
• Graph Databases
All thrown together &
Which, despite it’s
“Not Only SQL”
Yeah, I don’t believe it
Just what it sounds like. You set a Key to a Value and
can then retrieve it.
• High performance (usually) because there
are no transactions or relations so it’s a
simple bucket and lookup.
• Extremely ﬂexible
• Commonly used as caches in front of
slower resources (like MySQL - bazinga!)
• memcached - in memory only, extremely
efﬁcient hashing algorithm allows you to
scale easily to hundreds of nodes.
• Redis - persistent, slightly more complex
than memcached (has support for arrays)
but still highly performant.
• Riak - The Rails Machine guys love it. Jesse?
• memcached: Read-through cache for
Rails with cache-money.
• redis: persistent cache for results from
our algorithm, partitioned by version and
• Family of databases modeled on either
Google’s BigTable or Amazon’s Dynamo.
• Pick two out of three from the CAP
theorem in order to get horizontal
• Data stored by column instead of by row.
• Consistency: All clients always have the
same view of the data.
• Availability: Each client can always read
• Partition Tolerance: The system works
well despite physical network partitions
• Making sense out of large amounts of data
where you know your query scenario
ahead of time.
• Large = 100s of millions of records.
• Data-mining log ﬁles and other sources of
• Amazon’s SimpleDB
• Google’s BigTable (the granddaddy of all of
• Store nodes, edges and properties
• Think of them as Things, Connections and
• Good for storing properties and
• Honestly, I don’t fully understand them...
• Short on relationships, tall on rich data
• Big on eventual consistency and ﬂexible
• Hybrid of traditional RDBMS and Key-Value
• Content Management Systems
• Applications with rapid partial updates
• Anything you don’t need joins or
transactions for that you would normally
use a RDBMS for.
• Support for rich data types: arrays, hashes,
embedded documents, etc
• Support for adding and removing things
from arrays and embedded documents
(addToSet, for example).
• Map/Reduce support and strong indexes
• Regular expression support in queries
• Embedded Documents - Use only if it
the embedded document will always be
selected with the parent.
• Indexes - MongoDB punishes you much
earlier for missing indexes than MySQL.
• Document size - Currently, documents
are limited to 4MB, which should be large
enough, but if it’s not...
• We use MongoDB heavily at MIS.
• Statistics application and reporting
• Top-secret new application
• Web crawler and indexer
Let’s do tags. Everything is taggable now, right?
The MySQL Way
And to get a “thing’s”
SELECT `tags`.* FROM `tags`
INNER JOIN `taggings` ON `tags`.id = `taggings`.tag_id
WHERE ((`taggings`.taggable_id = 237)
AND (`taggings`.taggable_type = 'Song'))
That’s a lot of pain for something so simple.
And I didn’t even show you ﬁnding things with tag “x”.
Or how to set and unset tags on a “thing”.
The MongoDB Way
Using MongoMapper and Rails 3
key :title, String
key :body, String
key :tags, Array
Let’s Make This Easy...
tag = Post.clean_tag(tag)
self.tags << tag
self.add_to_set(:tags => tag) unless self.new_record?
tag = Post.clean_tag(tag)
self.pull(:tags => tag) unless self.new_record?
out = 
arr = str.split(",")
arr.each do |t|
out << self.clean_tag(t)
Sorry if you’re looking at this later, but it’s console time!
Why I Love MongoDB
• Document model ﬁts how I build web apps.
• For most apps, I don’t need transactions.
• Eventual consistency is actually OK.
• Partial updates and arrays make things that
are a pain in SQL-land absolutely painless.
• It’s just smart enough without getting in the
What’s NoSQL, really?
• The right tool for the job.
• We’ve got lots of options for storing
• The key is picking the one that solves our
• And if an RDBMS is the right tool, that’s OK
• Visual NoSQL: http://blog.nahurst.com/
• MongoDB: http://mongodb.org
• MongoMapper: http://mongomapper.com/
• Kevin Lawver
• [email protected]