42. SQL Schema Representation
# in a SQL schema
people:
- name
stalkings: stalkings ain’t got
- name no stalkee_id
- stalkee_id
43. SQL Schema Representation
# in a SQL schema
people:
- name
stalkings: stalkee_id is how we map our
- name object to fit in a SQL schema
- stalkee_id
44. SQL Schema Representation
# in a SQL schema
people:
- name
stalkings:
i.e. the “pointless join”
- name
- stalkee_id
56. Needs for a persistence layer:
1.To persist the native state of our objects
57. Needs for a persistence layer:
1.To persist the native state of our objects
2.Should NOT interfere w/ application development
58. Needs for a persistence layer:
1.To persist the native state of our objects
2.Should NOT interfere w/ application development
3.Provides features necessary to build modern web apps
70. Mongo Representation
{ name: "alex",
stalkings: [{ name: "Jim" }, { name: "Bob" }]
}
This is a good thing for scalability, because
JOINS limit our ability to horizontally scale.
71. Mongo Representation
{ name: "alex",
stalkings: [{ name: "Jim" }, { name: "Bob" }]
}
But more importantly, this is more intuitive than
messing with foreign keys
110. Capped collections
Fixed-sized, limited operation, auto age-out
collections (kinda like memcached)
Fixed insertion order
Super fast (faster than normal writes)
Ideal for logging and caching
111. Great. What’s that mean?
We can log additional pieces of arbitrary data
effortlessly due to Mongo’s schemaless nature.
118. require 'bunyan'
# put in config/initializers for rails
Bunyan::Logger.configure do |c|
c.database 'my_bunyan_db'
c.collection 'development_log'
# == 100.megabytes if using rails
c.size 104857600
end
119. class BunyanMiddleware
def initialize(app)
@app = app
end
def call(env)
@status, @headers, @response = @app.call(env)
Bunyan::Logger.insert(prepare_extra_fields)
[@status, @headers, @response]
end
end
127. Blogging Application
A post has an author
A post has many tags
A post has many comments
128. Blogging Application
A post has an author
A post has many tags
A post has many comments
Instead of JOINing separate tables,
we can use embedded documents.
135. MongoMapper
• MongoDB “ORM” developed by John Nunemaker
• author of HttpParty
• Very similar syntax to DataMapper
136. MongoMapper
• MongoDB “ORM” developed by John Nunemaker
• author of HttpParty
• Very similar syntax to DataMapper
• Declarative rather than inheritance-based
137. MongoMapper
• MongoDB “ORM” developed by John Nunemaker
• author of HttpParty
• Very similar syntax to DataMapper
• Declarative rather than inheritance-based
• Very easy to drop into rails
138. MongoMapper
class Post
include MongoMapper::Document
belongs_to :author, :class_name => "User"
key :title, String, :required => true
key :body, String
key :author_id, Integer, :required => true
key :published_at, Time
key :published, Boolean, :default => false
timestamps!
many :tags
end
class Tag
include MongoMapper::EmbeddedDocument
key :name, String, :required => true
end
141. class Bio
include MongoMapper::Document
plugin Joint
key :name, String, :required => true
key :title, String
key :description, String
timestamps!
attachment :headshot
attachment :video_bio
end
142. class Bio
include MongoMapper::Document
plugin Joint
key :name, String, :required => true
key :title, String
key :description, String
timestamps!
Can be served directly
attachment :headshot
from Mongo
attachment :video_bio
end
146. Using mongo w/ Ruby
Ruby mongo driver
MongoMapper
MongoID
MongoRecord (http://github.com/mongodb/mongo-
record)
MongoDoc (http://github.com/leshill/mongodoc)
Many other ORM/ODM’s under active development