From Tables to
Documents
Changing Your Database Mindset
Lauren Schaefer | Staff Developer Advocate | MongoDB | @lauren_schaefer
Parks and Recreation, Season 6, Episode 14 @Lauren_Schaefer
@Lauren_Schaefer
@Lauren_Schaefer
@Lauren_Schaefer
@Lauren_Schaefer
Parks and Recreation, Season 6, Episode 14
@Lauren_Schaefer
Staff Developer Advocate
MongoDB
@Lauren_Schaefer
@Lauren_Schaefer
Staff Developer Advocate
MongoDB
@Lauren_Schaefer
From Tables to
Documents
Changing Your Database Mindset
Lauren Schaefer | Staff Developer Advocate | MongoDB | @lauren_schaefer
The mental journey from tables to documents
Map terms & concepts from tables to documents
Discover the 4 major advantages of documents
Change your mindset in 3 key ways
@Lauren_Schaefer
@Lauren_Schaefer
The mental journey from tables to documents
Map terms & concepts from tables to documents
Discover the 4 major advantages of documents
Change your mindset in 3 key ways
@Lauren_Schaefer
@Lauren_Schaefer
Let’s talk about
documents
@Lauren_Schaefer
Let’s talk about
documents
@Lauren_Schaefer
Let’s talk about
documents
@Lauren_Schaefer
Let’s talk about
documents
{
}
@Lauren_Schaefer
Let’s talk about
documents
{
field: value,
field: value,
field: value
}
@Lauren_Schaefer
USERS
ID first_name last_name cell city
1 Leslie Yepp 8125552344 Pawnee
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee"
}
USERS
USERS
ID first_name last_name cell city
1 Leslie Yepp 8125552344 Pawnee
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee"
}
USERS
USERS
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee",
"location": [ -86.536632,
39.170344 ]
}
USERS
USERS
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee",
"location": [ -86.536632,
39.170344 ]
}
USERS
USERS
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee",
"location": [ -86.536632,
39.170344 ]
}
USERS
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
USERS
HOBBIES
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee",
"location": [ -86.536632,
39.170344 ],
"hobbies": [
"scrapbooking",
"eating waffles",
"working”
]
}
USERS
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
USERS
HOBBIES
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee",
"location": [ -86.536632,
39.170344 ],
"hobbies": [
"scrapbooking",
"eating waffles",
"working”
]
}
USERS
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
USERS
HOBBIES
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee",
"location": [ -86.536632,
39.170344 ],
"hobbies": [
"scrapbooking",
"eating waffles",
"working”
]
}
USERS
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
JOB HISTORY
USERS
HOBBIES
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee",
"location": [ -86.536632,
39.170344 ],
"hobbies": [
"scrapbooking",
"eating waffles",
"working”
]
}
USERS
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
JOB HISTORY
USERS
HOBBIES
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee",
"location": [ -86.536632,
39.170344 ],
"hobbies": [
"scrapbooking",
"eating waffles",
"working”
],
"jobHistory": [
{
"title": "Deputy Director",
"yearStarted": 2004
},
{
"title": "City Councillor",
"yearStarted": 2012
},
{
"title": "Director, National Parks
Service, Midwest Branch",
"yearStarted": 2014
}
]
}
USERS
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
JOB HISTORY
USERS
HOBBIES
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee",
"location": [ -86.536632,
39.170344 ],
"hobbies": [
"scrapbooking",
"eating waffles",
"working”
],
"jobHistory": [
{
"title": "Deputy Director",
"yearStarted": 2004
},
{
"title": "City Councillor",
"yearStarted": 2012
},
{
"title": "Director, National Parks
Service, Midwest Branch",
"yearStarted": 2014
}
]
}
USERS
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
JOB HISTORY
USERS
HOBBIES
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee",
"location": [ -86.536632,
39.170344 ],
"hobbies": [
"scrapbooking",
"eating waffles",
"working”
],
"jobHistory": [
{
"title": "Deputy Director",
"yearStarted": 2004
},
{
"title": "City Councillor",
"yearStarted": 2012
},
{
"title": "Director, National Parks
Service, Midwest Branch",
"yearStarted": 2014
}
]
}
USERS
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
JOB HISTORY
USERS
HOBBIES
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
2 Ron Swandaughter 8125559347 Pawnee NULL NULL
USERS
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
JOB HISTORY
{
"_id": 2,
"first_name": "Ron",
"last_name": "Swandaughter",
"cell": "8125559347",
"city": "Pawnee"
}
USERS
HOBBIES
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
2 Ron Swandaughter 8125559347 Pawnee NULL NULL
USERS
{
"_id": 2,
"first_name": "Ron",
"last_name": "Swandaughter",
"cell": "8125559347",
"city": "Pawnee"
}
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
13 2 woodworking
14 2 fishing
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
23 2 Director 2002
24 2 CEO, Kinda Good
Building Company
2014
JOB HISTORY
USERS
HOBBIES
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
2 Ron Swandaughter 8125559347 Pawnee NULL NULL
USERS
{
"_id": 2,
"first_name": "Ron",
"last_name": "Swandaughter",
"cell": "8125559347",
"city": "Pawnee",
"hobbies": [
"woodworking",
"fishing"
],
"jobHistory": [
{
"title": "Director",
"yearStarted": 2002
},
{
"title": "CEO, Kinda Good Building
Company",
"yearStarted": 2014
}
]
}
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
13 2 woodworking
14 2 fishing
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
23 2 Director 2002
24 2 CEO, Kinda Good
Building Company
2014
JOB HISTORY
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
2 Ron Swandaughter 8125559347 Pawnee NULL NULL
USERS
HOBBIES
USERS
{
"_id": 2,
"first_name": "Ron",
"last_name": "Swandaughter",
"cell": "8125559347",
"city": "Pawnee",
"hobbies": [
"woodworking",
"fishing"
],
"jobHistory": [
{
"title": "Director",
"yearStarted": 2002
},
{
"title": "CEO, Kinda Good Building
Company",
"yearStarted": 2014
}
]
}
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
13 2 woodworking
14 2 fishing
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
23 2 Director 2002
24 2 CEO, Kinda Good
Building Company
2014
JOB HISTORY
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
2 Ron Swandaughter 8125559347 Pawnee NULL NULL
USERS
HOBBIES
USERS
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
23 2 Director 2002
24 2 CEO, Kinda Good
Building Company
2014
JOB HISTORY
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
13 2 woodworking
14 2 fishing
15 3 soccer
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
2 Ron Swandaughter 8125559347 Pawnee NULL NULL
3 Lauren Burhug NULL Pawnee NULL NULL
USERS
HOBBIES
{
"_id": 2,
"first_name": "Ron",
"last_name": "Swandaughter",
"cell": "8125559347",
"city": "Pawnee",
"hobbies": [
"woodworking",
"fishing"
],
"jobHistory": [
{
"title": "Director",
"yearStarted": 2002
},
{
"title": "CEO, Kinda Good Building
Company",
"yearStarted": 2014
}
]
}
USERS USERS
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
23 2 Director 2002
24 2 CEO, Kinda Good
Building Company
2014
JOB HISTORY
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
13 2 woodworking
14 2 fishing
15 3 soccer
HOBBIES
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
2 Ron Swandaughter 8125559347 Pawnee NULL NULL
3 Lauren Burhug NULL Pawnee NULL NULL
{
"_id": 3,
"first_name": "Lauren",
"last_name": "Burhug",
"city": "Pawnee",
"hobbies": [ "soccer" ]
}
USERS USERS
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
23 2 Director 2002
24 2 CEO, Kinda Good
Building Company
2014
JOB HISTORY
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
13 2 woodworking
14 2 fishing
15 3 soccer
HOBBIES
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
2 Ron Swandaughter 8125559347 Pawnee NULL NULL
3 Lauren Burhug NULL Pawnee NULL NULL
{
"_id": 3,
"first_name": "Lauren",
"last_name": "Burhug",
"city": "Pawnee",
"hobbies": [ "soccer" ]
}
USERS USERS
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
23 2 Director 2002
24 2 CEO, Kinda Good
Building Company
2014
JOB HISTORY
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
13 2 woodworking
14 2 fishing
15 3 soccer
HOBBIES
ID first_name last_name cell city latitude longitude school
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 NULL
2 Ron Swandaughter 8125559347 Pawnee NULL NULL NULL
3 Lauren Burhug NULL Pawnee NULL NULL Pawnee
Elementary
{
"_id": 3,
"first_name": "Lauren",
"last_name": "Burhug",
"city": "Pawnee",
"hobbies": [ "soccer" ]
}
USERS USERS
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
23 2 Director 2002
24 2 CEO, Kinda Good
Building Company
2014
JOB HISTORY
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
13 2 woodworking
14 2 fishing
15 3 soccer
HOBBIES
ID first_name last_name cell city latitude longitude school
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 NULL
2 Ron Swandaughter 8125559347 Pawnee NULL NULL NULL
3 Lauren Burhug NULL Pawnee NULL NULL Pawnee
Elementary
{
"_id": 3,
"first_name": "Lauren",
"last_name": "Burhug",
"city": "Pawnee",
"hobbies": [ "soccer" ]
}
USERS USERS
ID user_id job_title year_started
20 1 Deputy Directory 2004
21 1 City Councilor 2012
22 1 Director, National
Parks Service,
Midwest Branch
2014
23 2 Director 2002
24 2 CEO, Kinda Good
Building Company
2014
JOB HISTORY
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
13 2 woodworking
14 2 fishing
15 3 soccer
HOBBIES
ID first_name last_name cell city latitude longitude school
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 NULL
2 Ron Swandaughter 8125559347 Pawnee NULL NULL NULL
3 Lauren Burhug NULL Pawnee NULL NULL Pawnee
Elementary
{
"_id": 3,
"first_name": "Lauren",
"last_name": "Burhug",
"city": "Pawnee",
"hobbies": [ "soccer" ],
"school": "Pawnee Elementary"
}
Don’t panic!
Don’t panic!
Use schema
validation.
Document
Row
ID a ...
1 b ...
2 ... ...
3 ... ...
{
...
a: “b”
...
}
@Lauren_Schaefer
Document
Row(s)
ID a ...
1 b ...
2 ... ...
3 ... ...
... ... ...
... ... ...
... ... ...
... ... ...
... ... ...
... ... ...
... ... ...
... ... ...
{
...
a: “b”
...
}
Field
Column
ID a ...
1 b ...
2 c ...
3 ... ...
{
...
a: “b”
...
}
{
...
a: “c”
...
}
@Lauren_Schaefer
Collection
Table
... ... ...
... ... ...
... ... ...
... ... ...
{
...
} {
...
} {
...
}
@Lauren_Schaefer
... ... ...
... ... ...
... ... ...
... ... ...
Database
Database
{
...
}
{
...
}
{
...
}
... ... ...
... ... ...
... ... ...
... ... ...
{
...
}
{
...
}
{
...
}
{
...
}
... ... ...
... ... ...
... ... ...
... ... ...
Index
Index
{
...
}
{
...
}
{
...
}
{
...
}
View
View
... ... ...
... ... ...
... ... ...
... ... ...
{
...
} {
...
} {
...
}
@Lauren_Schaefer
ID a ...
1 b ...
2 ... ...
3 ... ...
Embedding
Join
ID d ...
4 e ...
... ... ...
... ... ...
{
...
a: “b”,
...
c: {
d: “e”
...
},
...
}
@Lauren_Schaefer
... ... ...
... ... ...
... ... ...
... ... ...
Multi-document
Multi-record
{
...
}
{
...
}
{
...
}
... ... ...
... ... ...
... ... ...
... ... ...
{
...
}
{
...
}
{
...
}
{
...
}
ACID Transaction ACID Transaction
@Lauren_Schaefer
Term mapping summary
Row Column Table Database Index View Join Transaction
Document Field Collection Database Index View Embedding Transaction
@Lauren_Schaefer
The mental journey from tables to documents
Map terms & concepts from tables to documents
Discover the 4 major advantages of documents
Change your mindset in 3 key ways
@Lauren_Schaefer
@Lauren_Schaefer
@Lauren_Schaefer
@Lauren_Schaefer
Scale cheaper!
As the size of your database grows, scale horizontally.
@Lauren_Schaefer
Tabular Database Document Database
Query faster!
Stop doing expensive joins to get your data.
ID a ...
1 b ...
2 ... ...
3 ... ...
{
...
a: “b”,
...
c: {
d: “e”
...
},
...
}
... ... ...
... ... ...
... ... ...
... ... ...
... ... ...
... ... ...
... ... ...
... ... ...
@Lauren_Schaefer
{
first_name:
“Lauren”,
…
}
Tabular Database Document Database
Pivot easier!
Easily change the shape of your data as your app evolves.
ALTER TABLE
`CityHall`.`Users`
ADD COLUMN `school`
VARCHAR(45) NULL
AFTER `longitude`;
@Lauren_Schaefer
{
first_name:
“Lauren”,
School:
“Pawnee
Elementary”,
…
}
Program faster!
Documents map
to data structures
in most popular
languages.
@Lauren_Schaefer
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee",
"location": [ -86.536632,
39.170344 ],
"hobbies": [
"scrapbooking",
"eating waffles",
"working”
]
}
USERS
ID user_id hobby
10 1 scrapbooking
11 1 eating waffles
12 1 working
USERS
HOBBIES
ID first_name last_name cell city latitude longitude
1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
import mysql.connector
# CONNECT TO THE DB
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd="rootroot",
database="CityHall" )
mycursor = mydb.cursor(dictionary=True)
# THE ID OF THE USER WHOSE PROFILE WE
# WILL BE RETRIEVING AND UPDATING
userId = 1
Program faster!
import pymongo
from pymongo import MongoClient
# CONNECT TO THE DB
client = MongoClient()
client = pymongo
.MongoClient("mongodb+srv://root:rootroot@m
ycluster.mongodb.net/test?retryWrites=true&
w=majority")
db = client.CityHall
# THE ID OF THE USER WHOSE PROFILE WE
# WILL BE RETRIEVING AND UPDATING
userId = 1
@Lauren_Schaefer
sql = "SELECT * FROM Users LEFT JOIN
Hobbies ON Users.ID = Hobbies.user_id WHERE
Users.id=%s"
values = (userId,)
my cursor.execute(sql, values)
user = mycursor.fetchone()
Program faster!
user = db['Users’]
.find_one({"_id": userId})
@Lauren_Schaefer
hobbies = []
if (user["hobby"]):
hobbies.append(user["hobby"])
del user["hobby"]
del user["ID"]
for result in mycursor:
hobbies.append(result["hobby"])
user["hobbies"] = hobbies
{
'city': 'Pawnee',
'first_name': 'Leslie',
'last_name': 'Yepp',
'school': None,
'cell': '8125552344',
'latitude': 39.1703,
'longitude': -86.5366,3
'hobbies’: [
'scrapbooking’,
'eating waffles’,
'working’
],
'user_id': 1
}
Program faster!
{
'city': 'Pawnee',
'first_name’: 'Leslie',
'last_name': 'Yepp',
'cell': '8125552344',
'location': [-86.536632, 39.170344],
'hobbies’: [
'scrapbooking’,
'eating waffles’,
'working’
],
'_id': 1
}
@Lauren_Schaefer
user.update( {
"city": "Washington, DC",
"latitude": 38.897760,
"longitude": -77.036809,
"hobbies": [
"scrapbooking",
"eating waffles",
"signing bills"]
} )
Program faster!
user.update( {
"city": "Washington, DC",
"location": [-77.036809, 38.897760],
"hobbies": [
"scrapbooking",
"eating waffles",
"signing bills"]
} )
@Lauren_Schaefer
sql = "UPDATE Users SET first_name=%s,
last_name=%s, cell=%s, city=%s,
latitude=%s, longitude=%s, school=%s WHERE
(ID=%s)"
values = (user["first_name"],
user["last_name"], user["cell"],
user["city"], user["latitude"],
user["longitude"], user["school"], userId)
mycursor.execute(sql, values)
mydb.commit()
Program faster!
result = db['Users’]
.update_one(
{"_id": userId},
{"$set": user})
@Lauren_Schaefer
sql = "DELETE FROM Hobbies WHERE
user_id=%s"
values = (userId,)
mycursor.execute(sql, values)
mydb.commit()
if(len(user["hobbies"]) > 0):
sql = "INSERT INTO Hobbies
(user_id, hobby) VALUES (%s, %s)"
values = []
for hobby in user["hobbies"]:
values.append((userId, hobby))
mycursor.executemany(sql,values)
mydb.commit()
27 lines of code 2 lines of code
@Lauren_Schaefer
Scale cheaper Query faster Program faster
Pivot easier
4 major advantages
@Lauren_Schaefer
The mental journey from tables to documents
Map terms & concepts from tables to documents
Discover the 4 major advantages of documents
Change your mindset in 3 key ways
@Lauren_Schaefer
@Lauren_Schaefer
@Lauren_Schaefer
@Lauren_Schaefer
@Lauren_Schaefer
Embrace document
diversity
The Polymorphic Pattern
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee",
"location": [ -86.536632, 39.170344 ],
"hobbies": [
"scrapbooking",
"eating waffles",
"working”
],
"jobHistory": [
{
"title": "Deputy Director",
"yearStarted": 2004
},
{
"title": "City Councillor",
"yearStarted": 2012
},
{
"title": "Director, National Parks
Service, Midwest Branch",
"yearStarted": 2014
}
]
}
{
"_id": 1,
"first_name": "Ron",
"last_name": "Swandaughter",
"cell": ”8125559347",
"city": "Pawnee",
"hobbies": [
”woodworking",
”fishing"
],
"jobHistory": [
{
"title": "Director",
"yearStarted": 2002
},
{
"title": ”CEO, Kinda Good
Building Company",
"yearStarted": 2014
}
]
}
{
"_id": 3,
"first_name": "Lauren",
"last_name": "Burhug",
"city": "Pawnee",
"hobbies": [ "soccer" ],
"school": "Pawnee Elementary"
}
The Outlier Pattern
{
"_id": 3,
"first_name": "Lauren",
"last_name": "Burhug",
"city": "Pawnee",
"hobbies": ["soccer"],
"school": "Pawnee Elementary",
"followers": [
"Brandon",
"Wesley",
"Ciara",
...
]
}
{
"_id": 2.1,
"followers": [
"Jerry",
"Ann",
"Ben"
...
],
"is_overflow": true
}
{
"_id": 2,
"first_name": "Ron",
"last_name": "Swandaughter",
"cell": "8125559347",
"city": "Pawnee",
"hobbies": [
"woodworking",
"fishing"],
"jobHistory": [
{
"title": "Director",
"yearStarted": 2002
},
...
],
"followers": [
"Leslie",
"Donna",
"Tom" ... ],
}
{
"_id": 2,
"first_name": "Ron",
"last_name": "Swandaughter",
"cell": "8125559347",
"city": "Pawnee",
"hobbies": [
"woodworking",
"fishing"],
"jobHistory": [
{
"title": "Director",
"yearStarted": 2002
},
...
],
"followers": [
"Leslie",
"Donna",
"Tom" ... ],
"has_extras": true
}
Data that is accessed
together should be
stored together
@Lauren_Schaefer
Data that is accessed together should be stored together
@Lauren_Schaefer
US$/MB vs date 1956 to 2016 (Log Scale)
@Lauren_Schaefer
@Lauren_Schaefer
100,000
30,000
100,000
20,000
40,000
60,000
80,000
100,000
120,000
0
1985 2017
1
Storage Cost vs. Developer Costs
Storage cost per GB
Developer salary
Data that is accessed together should be stored together
Data that is
accessed together
should be stored
together
Don’t normalize your data for
the sake of normalizing it.
{
a: “b”,
c: {
d: “e”
...
},
f: [“g”, “h”, “i”],
j: [
{
k: “l”
},
{
m: “n”
}
]
}
@Lauren_Schaefer
{
a: “b”,
c: {
d: “e”
...
},
f: [“g”, “h”, “i”],
j: [
{
k: “l”
},
{
m: “n”
}
]
}
{
a: “b”,
c: {
d: “e”
...
},
f: [“g”, “h”, “i”],
j: [
{
k: “l”
},
{
m: “n”
}
]
}
{
a: “b”,
c: {
d: “e”
...
},
f: [“g”, “h”, “i”],
j: [
{
k: “l”
},
{
m: “n”
}
]
}
Tread carefully with
transactions
Tread carefully
with transactions
Relying on transactions is
a bad design smell.
{
...
}
{
...
}
{
...
}
{
...
}
{
...
}
{
...
}
{
...
}
@Lauren_Schaefer
Change your mindset in 3 key ways
Embrace document diversity
Data that is accessed together should be stored together
Tread carefully with transactions
@Lauren_Schaefer
The mental journey from tables to documents
@Lauren_Schaefer
@Lauren_Schaefer
The mental journey from tables to documents
Map terms & concepts from tables to documents
@Lauren_Schaefer
@Lauren_Schaefer
Row Column Table Database Index View Join Transaction
Document Field Collection Database Index View Embedding Transaction
The mental journey from tables to documents
Map terms & concepts from tables to documents
Discover the 4 major advantages of documents
@Lauren_Schaefer
@Lauren_Schaefer
The mental journey from tables to documents
Map terms & concepts from tables to documents
Discover the 4 major advantages of documents
Scale cheaper
@Lauren_Schaefer
@Lauren_Schaefer
The mental journey from tables to documents
Map terms & concepts from tables to documents
Discover the 4 major advantages of documents
Scale cheaper
Query faster
@Lauren_Schaefer
@Lauren_Schaefer
{
...
a: “b”,
...
c: {
d: “e”
...
},
...
}
The mental journey from tables to documents
Map terms & concepts from tables to documents
Discover the 4 major advantages of documents
Scale cheaper
Query faster
Pivot easier
@Lauren_Schaefer
@Lauren_Schaefer
{
first_name:
“Lauren”,
…
}
{
first_name:
“Lauren”,
School:
“Pawnee
Elementary”,
…
}
The mental journey from tables to documents
Map terms & concepts from tables to documents
Discover the 4 major advantages of documents
Scale cheaper
Query faster
Pivot easier
Program faster
@Lauren_Schaefer
@Lauren_Schaefer
The mental journey from tables to documents
Map terms & concepts from tables to documents
Discover the 4 major advantages of documents
Change your mindset in 3 key ways
@Lauren_Schaefer
@Lauren_Schaefer
The mental journey from tables to documents
Map terms & concepts from tables to documents
Discover the 4 major advantages of documents
Change your mindset in 3 key ways
Embrace document diversity
@Lauren_Schaefer
@Lauren_Schaefer
{
"_id": 1,
"first_name": "Leslie",
"last_name": "Yepp",
"cell": "8125552344",
"city": "Pawnee",
"location": [ -86.536632, 39.170344 ],
"hobbies": [
"scrapbooking",
"eating waffles",
"working”
],
"jobHistory": [
{
"title": "Deputy Director",
"yearStarted": 2004
},
{
"title": "City Councillor",
"yearStarted": 2012
},
{
"title": "Director, National Parks
Service, Midwest Branch",
"yearStarted": 2014
}
]
}
{
"_id": 1,
"first_name": "Ron",
"last_name": "Swandaughter",
"cell": ”8125559347",
"city": "Pawnee",
"hobbies": [
”woodworking",
”fishing"
],
"jobHistory": [
{
"title": "Director",
"yearStarted": 2002
},
{
"title": ”CEO, Kinda Good
Building Company",
"yearStarted": 2014
}
]
}
{
"_id": 3,
"first_name": "Lauren",
"last_name": "Burhug",
"city": "Pawnee",
"hobbies": [ "soccer" ],
"school": "Pawnee Elementary"
}
The mental journey from tables to documents
Map terms & concepts from tables to documents
Discover the 4 major advantages of documents
Change your mindset in 3 key ways
Embrace document diversity
Data that is accessed together should be stored together
@Lauren_Schaefer
@Lauren_Schaefer
{
a: “b”,
c: {
d: “e”
...
},
f: [“g”, “h”, “i”],
j: [
{
k: “l”
},
{
m: “n”
}
]
}
The mental journey from tables to documents
Map terms & concepts from tables to documents
Discover the 4 major advantages of documents
Change your mindset in 3 key ways
Embrace document diversity
Data that is accessed together should be stored together
Tread carefully with transactions
@Lauren_Schaefer
@Lauren_Schaefer
{
...
}
{
...
} {
...
}
{
...
}
{
...
} {
...
} {
...
}
Don’t be
Ron Swanson
(in this particular case)
@Lauren_Schaefer
Change your
mindset and get
the full value of
document
databases
@Lauren_Schaefer
Additional resources
SQL to MongoDB Blog (blog series)
Quick Start: MongoDB and Node.js (blog series & video series)
Advanced Schema Design Patterns (webinar)
Building with Patterns: A Summary (blog series)
A Summary of Schema Design Anti-Patterns and How to Spot Them (blog series & video
series)
M320: Data Modeling (MongoDB University Course)
JSON Schema Validation – Locking down your model the smart way (blog)
@Lauren_Schaefer
Give document databases a try using MongoDB Atlas
Get the slides on my Twitter page: @Lauren_Schaefer
@Lauren_Schaefer

From Tables to Documents—Changing Your Database Mindset

  • 1.
    From Tables to Documents ChangingYour Database Mindset Lauren Schaefer | Staff Developer Advocate | MongoDB | @lauren_schaefer
  • 2.
    Parks and Recreation,Season 6, Episode 14 @Lauren_Schaefer
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
    From Tables to Documents ChangingYour Database Mindset Lauren Schaefer | Staff Developer Advocate | MongoDB | @lauren_schaefer
  • 10.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents Discover the 4 major advantages of documents Change your mindset in 3 key ways @Lauren_Schaefer @Lauren_Schaefer
  • 11.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents Discover the 4 major advantages of documents Change your mindset in 3 key ways @Lauren_Schaefer @Lauren_Schaefer
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
    Let’s talk about documents { field:value, field: value, field: value } @Lauren_Schaefer
  • 19.
    USERS ID first_name last_namecell city 1 Leslie Yepp 8125552344 Pawnee
  • 20.
    { "_id": 1, "first_name": "Leslie", "last_name":"Yepp", "cell": "8125552344", "city": "Pawnee" } USERS USERS ID first_name last_name cell city 1 Leslie Yepp 8125552344 Pawnee
  • 21.
    { "_id": 1, "first_name": "Leslie", "last_name":"Yepp", "cell": "8125552344", "city": "Pawnee" } USERS USERS ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
  • 22.
    { "_id": 1, "first_name": "Leslie", "last_name":"Yepp", "cell": "8125552344", "city": "Pawnee", "location": [ -86.536632, 39.170344 ] } USERS USERS ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
  • 23.
    { "_id": 1, "first_name": "Leslie", "last_name":"Yepp", "cell": "8125552344", "city": "Pawnee", "location": [ -86.536632, 39.170344 ] } USERS USERS ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
  • 24.
    { "_id": 1, "first_name": "Leslie", "last_name":"Yepp", "cell": "8125552344", "city": "Pawnee", "location": [ -86.536632, 39.170344 ] } USERS ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working USERS HOBBIES ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
  • 25.
    { "_id": 1, "first_name": "Leslie", "last_name":"Yepp", "cell": "8125552344", "city": "Pawnee", "location": [ -86.536632, 39.170344 ], "hobbies": [ "scrapbooking", "eating waffles", "working” ] } USERS ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working USERS HOBBIES ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
  • 26.
    { "_id": 1, "first_name": "Leslie", "last_name":"Yepp", "cell": "8125552344", "city": "Pawnee", "location": [ -86.536632, 39.170344 ], "hobbies": [ "scrapbooking", "eating waffles", "working” ] } USERS ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working USERS HOBBIES ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
  • 27.
    { "_id": 1, "first_name": "Leslie", "last_name":"Yepp", "cell": "8125552344", "city": "Pawnee", "location": [ -86.536632, 39.170344 ], "hobbies": [ "scrapbooking", "eating waffles", "working” ] } USERS ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working ID user_id job_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 JOB HISTORY USERS HOBBIES ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
  • 28.
    { "_id": 1, "first_name": "Leslie", "last_name":"Yepp", "cell": "8125552344", "city": "Pawnee", "location": [ -86.536632, 39.170344 ], "hobbies": [ "scrapbooking", "eating waffles", "working” ] } USERS ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working ID user_id job_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 JOB HISTORY USERS HOBBIES ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
  • 29.
    { "_id": 1, "first_name": "Leslie", "last_name":"Yepp", "cell": "8125552344", "city": "Pawnee", "location": [ -86.536632, 39.170344 ], "hobbies": [ "scrapbooking", "eating waffles", "working” ], "jobHistory": [ { "title": "Deputy Director", "yearStarted": 2004 }, { "title": "City Councillor", "yearStarted": 2012 }, { "title": "Director, National Parks Service, Midwest Branch", "yearStarted": 2014 } ] } USERS ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working ID user_id job_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 JOB HISTORY USERS HOBBIES ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
  • 30.
    { "_id": 1, "first_name": "Leslie", "last_name":"Yepp", "cell": "8125552344", "city": "Pawnee", "location": [ -86.536632, 39.170344 ], "hobbies": [ "scrapbooking", "eating waffles", "working” ], "jobHistory": [ { "title": "Deputy Director", "yearStarted": 2004 }, { "title": "City Councillor", "yearStarted": 2012 }, { "title": "Director, National Parks Service, Midwest Branch", "yearStarted": 2014 } ] } USERS ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working ID user_id job_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 JOB HISTORY USERS HOBBIES ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
  • 31.
    { "_id": 1, "first_name": "Leslie", "last_name":"Yepp", "cell": "8125552344", "city": "Pawnee", "location": [ -86.536632, 39.170344 ], "hobbies": [ "scrapbooking", "eating waffles", "working” ], "jobHistory": [ { "title": "Deputy Director", "yearStarted": 2004 }, { "title": "City Councillor", "yearStarted": 2012 }, { "title": "Director, National Parks Service, Midwest Branch", "yearStarted": 2014 } ] } USERS ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working ID user_id job_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 JOB HISTORY USERS HOBBIES ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 2 Ron Swandaughter 8125559347 Pawnee NULL NULL
  • 32.
    USERS ID user_id hobby 101 scrapbooking 11 1 eating waffles 12 1 working ID user_id job_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 JOB HISTORY { "_id": 2, "first_name": "Ron", "last_name": "Swandaughter", "cell": "8125559347", "city": "Pawnee" } USERS HOBBIES ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 2 Ron Swandaughter 8125559347 Pawnee NULL NULL
  • 33.
    USERS { "_id": 2, "first_name": "Ron", "last_name":"Swandaughter", "cell": "8125559347", "city": "Pawnee" } ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working 13 2 woodworking 14 2 fishing ID user_id job_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 23 2 Director 2002 24 2 CEO, Kinda Good Building Company 2014 JOB HISTORY USERS HOBBIES ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 2 Ron Swandaughter 8125559347 Pawnee NULL NULL
  • 34.
    USERS { "_id": 2, "first_name": "Ron", "last_name":"Swandaughter", "cell": "8125559347", "city": "Pawnee", "hobbies": [ "woodworking", "fishing" ], "jobHistory": [ { "title": "Director", "yearStarted": 2002 }, { "title": "CEO, Kinda Good Building Company", "yearStarted": 2014 } ] } ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working 13 2 woodworking 14 2 fishing ID user_id job_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 23 2 Director 2002 24 2 CEO, Kinda Good Building Company 2014 JOB HISTORY ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 2 Ron Swandaughter 8125559347 Pawnee NULL NULL USERS HOBBIES
  • 35.
    USERS { "_id": 2, "first_name": "Ron", "last_name":"Swandaughter", "cell": "8125559347", "city": "Pawnee", "hobbies": [ "woodworking", "fishing" ], "jobHistory": [ { "title": "Director", "yearStarted": 2002 }, { "title": "CEO, Kinda Good Building Company", "yearStarted": 2014 } ] } ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working 13 2 woodworking 14 2 fishing ID user_id job_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 23 2 Director 2002 24 2 CEO, Kinda Good Building Company 2014 JOB HISTORY ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 2 Ron Swandaughter 8125559347 Pawnee NULL NULL USERS HOBBIES
  • 36.
    USERS ID user_id job_titleyear_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 23 2 Director 2002 24 2 CEO, Kinda Good Building Company 2014 JOB HISTORY ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working 13 2 woodworking 14 2 fishing 15 3 soccer ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 2 Ron Swandaughter 8125559347 Pawnee NULL NULL 3 Lauren Burhug NULL Pawnee NULL NULL USERS HOBBIES { "_id": 2, "first_name": "Ron", "last_name": "Swandaughter", "cell": "8125559347", "city": "Pawnee", "hobbies": [ "woodworking", "fishing" ], "jobHistory": [ { "title": "Director", "yearStarted": 2002 }, { "title": "CEO, Kinda Good Building Company", "yearStarted": 2014 } ] }
  • 37.
    USERS USERS ID user_idjob_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 23 2 Director 2002 24 2 CEO, Kinda Good Building Company 2014 JOB HISTORY ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working 13 2 woodworking 14 2 fishing 15 3 soccer HOBBIES ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 2 Ron Swandaughter 8125559347 Pawnee NULL NULL 3 Lauren Burhug NULL Pawnee NULL NULL { "_id": 3, "first_name": "Lauren", "last_name": "Burhug", "city": "Pawnee", "hobbies": [ "soccer" ] }
  • 38.
    USERS USERS ID user_idjob_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 23 2 Director 2002 24 2 CEO, Kinda Good Building Company 2014 JOB HISTORY ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working 13 2 woodworking 14 2 fishing 15 3 soccer HOBBIES ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 2 Ron Swandaughter 8125559347 Pawnee NULL NULL 3 Lauren Burhug NULL Pawnee NULL NULL { "_id": 3, "first_name": "Lauren", "last_name": "Burhug", "city": "Pawnee", "hobbies": [ "soccer" ] }
  • 40.
    USERS USERS ID user_idjob_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 23 2 Director 2002 24 2 CEO, Kinda Good Building Company 2014 JOB HISTORY ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working 13 2 woodworking 14 2 fishing 15 3 soccer HOBBIES ID first_name last_name cell city latitude longitude school 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 NULL 2 Ron Swandaughter 8125559347 Pawnee NULL NULL NULL 3 Lauren Burhug NULL Pawnee NULL NULL Pawnee Elementary { "_id": 3, "first_name": "Lauren", "last_name": "Burhug", "city": "Pawnee", "hobbies": [ "soccer" ] }
  • 41.
    USERS USERS ID user_idjob_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 23 2 Director 2002 24 2 CEO, Kinda Good Building Company 2014 JOB HISTORY ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working 13 2 woodworking 14 2 fishing 15 3 soccer HOBBIES ID first_name last_name cell city latitude longitude school 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 NULL 2 Ron Swandaughter 8125559347 Pawnee NULL NULL NULL 3 Lauren Burhug NULL Pawnee NULL NULL Pawnee Elementary { "_id": 3, "first_name": "Lauren", "last_name": "Burhug", "city": "Pawnee", "hobbies": [ "soccer" ] }
  • 42.
    USERS USERS ID user_idjob_title year_started 20 1 Deputy Directory 2004 21 1 City Councilor 2012 22 1 Director, National Parks Service, Midwest Branch 2014 23 2 Director 2002 24 2 CEO, Kinda Good Building Company 2014 JOB HISTORY ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working 13 2 woodworking 14 2 fishing 15 3 soccer HOBBIES ID first_name last_name cell city latitude longitude school 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632 NULL 2 Ron Swandaughter 8125559347 Pawnee NULL NULL NULL 3 Lauren Burhug NULL Pawnee NULL NULL Pawnee Elementary { "_id": 3, "first_name": "Lauren", "last_name": "Burhug", "city": "Pawnee", "hobbies": [ "soccer" ], "school": "Pawnee Elementary" }
  • 44.
  • 45.
  • 47.
    Document Row ID a ... 1b ... 2 ... ... 3 ... ... { ... a: “b” ... } @Lauren_Schaefer
  • 48.
    Document Row(s) ID a ... 1b ... 2 ... ... 3 ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... { ... a: “b” ... }
  • 49.
    Field Column ID a ... 1b ... 2 c ... 3 ... ... { ... a: “b” ... } { ... a: “c” ... } @Lauren_Schaefer
  • 50.
    Collection Table ... ... ... ...... ... ... ... ... ... ... ... { ... } { ... } { ... } @Lauren_Schaefer
  • 51.
    ... ... ... ...... ... ... ... ... ... ... ... Database Database { ... } { ... } { ... } ... ... ... ... ... ... ... ... ... ... ... ... { ... } { ... } { ... } { ... }
  • 52.
    ... ... ... ...... ... ... ... ... ... ... ... Index Index { ... } { ... } { ... } { ... }
  • 53.
    View View ... ... ... ...... ... ... ... ... ... ... ... { ... } { ... } { ... } @Lauren_Schaefer
  • 54.
    ID a ... 1b ... 2 ... ... 3 ... ... Embedding Join ID d ... 4 e ... ... ... ... ... ... ... { ... a: “b”, ... c: { d: “e” ... }, ... } @Lauren_Schaefer
  • 55.
    ... ... ... ...... ... ... ... ... ... ... ... Multi-document Multi-record { ... } { ... } { ... } ... ... ... ... ... ... ... ... ... ... ... ... { ... } { ... } { ... } { ... } ACID Transaction ACID Transaction @Lauren_Schaefer
  • 56.
    Term mapping summary RowColumn Table Database Index View Join Transaction Document Field Collection Database Index View Embedding Transaction @Lauren_Schaefer
  • 57.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents Discover the 4 major advantages of documents Change your mindset in 3 key ways @Lauren_Schaefer @Lauren_Schaefer
  • 58.
  • 59.
  • 60.
    Scale cheaper! As thesize of your database grows, scale horizontally. @Lauren_Schaefer
  • 61.
    Tabular Database DocumentDatabase Query faster! Stop doing expensive joins to get your data. ID a ... 1 b ... 2 ... ... 3 ... ... { ... a: “b”, ... c: { d: “e” ... }, ... } ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... @Lauren_Schaefer
  • 62.
    { first_name: “Lauren”, … } Tabular Database DocumentDatabase Pivot easier! Easily change the shape of your data as your app evolves. ALTER TABLE `CityHall`.`Users` ADD COLUMN `school` VARCHAR(45) NULL AFTER `longitude`; @Lauren_Schaefer { first_name: “Lauren”, School: “Pawnee Elementary”, … }
  • 63.
    Program faster! Documents map todata structures in most popular languages. @Lauren_Schaefer
  • 64.
    { "_id": 1, "first_name": "Leslie", "last_name":"Yepp", "cell": "8125552344", "city": "Pawnee", "location": [ -86.536632, 39.170344 ], "hobbies": [ "scrapbooking", "eating waffles", "working” ] } USERS ID user_id hobby 10 1 scrapbooking 11 1 eating waffles 12 1 working USERS HOBBIES ID first_name last_name cell city latitude longitude 1 Leslie Yepp 8125552344 Pawnee 39.170344 -86.536632
  • 65.
    import mysql.connector # CONNECTTO THE DB mydb = mysql.connector.connect( host="localhost", user="root", passwd="rootroot", database="CityHall" ) mycursor = mydb.cursor(dictionary=True) # THE ID OF THE USER WHOSE PROFILE WE # WILL BE RETRIEVING AND UPDATING userId = 1 Program faster! import pymongo from pymongo import MongoClient # CONNECT TO THE DB client = MongoClient() client = pymongo .MongoClient("mongodb+srv://root:rootroot@m ycluster.mongodb.net/test?retryWrites=true& w=majority") db = client.CityHall # THE ID OF THE USER WHOSE PROFILE WE # WILL BE RETRIEVING AND UPDATING userId = 1 @Lauren_Schaefer
  • 66.
    sql = "SELECT* FROM Users LEFT JOIN Hobbies ON Users.ID = Hobbies.user_id WHERE Users.id=%s" values = (userId,) my cursor.execute(sql, values) user = mycursor.fetchone() Program faster! user = db['Users’] .find_one({"_id": userId}) @Lauren_Schaefer hobbies = [] if (user["hobby"]): hobbies.append(user["hobby"]) del user["hobby"] del user["ID"] for result in mycursor: hobbies.append(result["hobby"]) user["hobbies"] = hobbies
  • 67.
    { 'city': 'Pawnee', 'first_name': 'Leslie', 'last_name':'Yepp', 'school': None, 'cell': '8125552344', 'latitude': 39.1703, 'longitude': -86.5366,3 'hobbies’: [ 'scrapbooking’, 'eating waffles’, 'working’ ], 'user_id': 1 } Program faster! { 'city': 'Pawnee', 'first_name’: 'Leslie', 'last_name': 'Yepp', 'cell': '8125552344', 'location': [-86.536632, 39.170344], 'hobbies’: [ 'scrapbooking’, 'eating waffles’, 'working’ ], '_id': 1 } @Lauren_Schaefer
  • 68.
    user.update( { "city": "Washington,DC", "latitude": 38.897760, "longitude": -77.036809, "hobbies": [ "scrapbooking", "eating waffles", "signing bills"] } ) Program faster! user.update( { "city": "Washington, DC", "location": [-77.036809, 38.897760], "hobbies": [ "scrapbooking", "eating waffles", "signing bills"] } ) @Lauren_Schaefer
  • 69.
    sql = "UPDATEUsers SET first_name=%s, last_name=%s, cell=%s, city=%s, latitude=%s, longitude=%s, school=%s WHERE (ID=%s)" values = (user["first_name"], user["last_name"], user["cell"], user["city"], user["latitude"], user["longitude"], user["school"], userId) mycursor.execute(sql, values) mydb.commit() Program faster! result = db['Users’] .update_one( {"_id": userId}, {"$set": user}) @Lauren_Schaefer sql = "DELETE FROM Hobbies WHERE user_id=%s" values = (userId,) mycursor.execute(sql, values) mydb.commit() if(len(user["hobbies"]) > 0): sql = "INSERT INTO Hobbies (user_id, hobby) VALUES (%s, %s)" values = [] for hobby in user["hobbies"]: values.append((userId, hobby)) mycursor.executemany(sql,values) mydb.commit()
  • 70.
    27 lines ofcode 2 lines of code @Lauren_Schaefer
  • 71.
    Scale cheaper Queryfaster Program faster Pivot easier 4 major advantages @Lauren_Schaefer
  • 72.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents Discover the 4 major advantages of documents Change your mindset in 3 key ways @Lauren_Schaefer @Lauren_Schaefer
  • 73.
  • 74.
  • 75.
  • 76.
    The Polymorphic Pattern { "_id":1, "first_name": "Leslie", "last_name": "Yepp", "cell": "8125552344", "city": "Pawnee", "location": [ -86.536632, 39.170344 ], "hobbies": [ "scrapbooking", "eating waffles", "working” ], "jobHistory": [ { "title": "Deputy Director", "yearStarted": 2004 }, { "title": "City Councillor", "yearStarted": 2012 }, { "title": "Director, National Parks Service, Midwest Branch", "yearStarted": 2014 } ] } { "_id": 1, "first_name": "Ron", "last_name": "Swandaughter", "cell": ”8125559347", "city": "Pawnee", "hobbies": [ ”woodworking", ”fishing" ], "jobHistory": [ { "title": "Director", "yearStarted": 2002 }, { "title": ”CEO, Kinda Good Building Company", "yearStarted": 2014 } ] } { "_id": 3, "first_name": "Lauren", "last_name": "Burhug", "city": "Pawnee", "hobbies": [ "soccer" ], "school": "Pawnee Elementary" }
  • 77.
    The Outlier Pattern { "_id":3, "first_name": "Lauren", "last_name": "Burhug", "city": "Pawnee", "hobbies": ["soccer"], "school": "Pawnee Elementary", "followers": [ "Brandon", "Wesley", "Ciara", ... ] } { "_id": 2.1, "followers": [ "Jerry", "Ann", "Ben" ... ], "is_overflow": true } { "_id": 2, "first_name": "Ron", "last_name": "Swandaughter", "cell": "8125559347", "city": "Pawnee", "hobbies": [ "woodworking", "fishing"], "jobHistory": [ { "title": "Director", "yearStarted": 2002 }, ... ], "followers": [ "Leslie", "Donna", "Tom" ... ], } { "_id": 2, "first_name": "Ron", "last_name": "Swandaughter", "cell": "8125559347", "city": "Pawnee", "hobbies": [ "woodworking", "fishing"], "jobHistory": [ { "title": "Director", "yearStarted": 2002 }, ... ], "followers": [ "Leslie", "Donna", "Tom" ... ], "has_extras": true }
  • 78.
    Data that isaccessed together should be stored together @Lauren_Schaefer
  • 79.
    Data that isaccessed together should be stored together @Lauren_Schaefer US$/MB vs date 1956 to 2016 (Log Scale)
  • 80.
  • 81.
    @Lauren_Schaefer 100,000 30,000 100,000 20,000 40,000 60,000 80,000 100,000 120,000 0 1985 2017 1 Storage Costvs. Developer Costs Storage cost per GB Developer salary Data that is accessed together should be stored together
  • 82.
    Data that is accessedtogether should be stored together Don’t normalize your data for the sake of normalizing it. { a: “b”, c: { d: “e” ... }, f: [“g”, “h”, “i”], j: [ { k: “l” }, { m: “n” } ] } @Lauren_Schaefer { a: “b”, c: { d: “e” ... }, f: [“g”, “h”, “i”], j: [ { k: “l” }, { m: “n” } ] } { a: “b”, c: { d: “e” ... }, f: [“g”, “h”, “i”], j: [ { k: “l” }, { m: “n” } ] } { a: “b”, c: { d: “e” ... }, f: [“g”, “h”, “i”], j: [ { k: “l” }, { m: “n” } ] }
  • 83.
  • 84.
    Tread carefully with transactions Relyingon transactions is a bad design smell. { ... } { ... } { ... } { ... } { ... } { ... } { ... } @Lauren_Schaefer
  • 85.
    Change your mindsetin 3 key ways Embrace document diversity Data that is accessed together should be stored together Tread carefully with transactions @Lauren_Schaefer
  • 86.
    The mental journeyfrom tables to documents @Lauren_Schaefer @Lauren_Schaefer
  • 87.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents @Lauren_Schaefer @Lauren_Schaefer Row Column Table Database Index View Join Transaction Document Field Collection Database Index View Embedding Transaction
  • 88.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents Discover the 4 major advantages of documents @Lauren_Schaefer @Lauren_Schaefer
  • 89.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents Discover the 4 major advantages of documents Scale cheaper @Lauren_Schaefer @Lauren_Schaefer
  • 90.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents Discover the 4 major advantages of documents Scale cheaper Query faster @Lauren_Schaefer @Lauren_Schaefer { ... a: “b”, ... c: { d: “e” ... }, ... }
  • 91.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents Discover the 4 major advantages of documents Scale cheaper Query faster Pivot easier @Lauren_Schaefer @Lauren_Schaefer { first_name: “Lauren”, … } { first_name: “Lauren”, School: “Pawnee Elementary”, … }
  • 92.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents Discover the 4 major advantages of documents Scale cheaper Query faster Pivot easier Program faster @Lauren_Schaefer @Lauren_Schaefer
  • 93.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents Discover the 4 major advantages of documents Change your mindset in 3 key ways @Lauren_Schaefer @Lauren_Schaefer
  • 94.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents Discover the 4 major advantages of documents Change your mindset in 3 key ways Embrace document diversity @Lauren_Schaefer @Lauren_Schaefer { "_id": 1, "first_name": "Leslie", "last_name": "Yepp", "cell": "8125552344", "city": "Pawnee", "location": [ -86.536632, 39.170344 ], "hobbies": [ "scrapbooking", "eating waffles", "working” ], "jobHistory": [ { "title": "Deputy Director", "yearStarted": 2004 }, { "title": "City Councillor", "yearStarted": 2012 }, { "title": "Director, National Parks Service, Midwest Branch", "yearStarted": 2014 } ] } { "_id": 1, "first_name": "Ron", "last_name": "Swandaughter", "cell": ”8125559347", "city": "Pawnee", "hobbies": [ ”woodworking", ”fishing" ], "jobHistory": [ { "title": "Director", "yearStarted": 2002 }, { "title": ”CEO, Kinda Good Building Company", "yearStarted": 2014 } ] } { "_id": 3, "first_name": "Lauren", "last_name": "Burhug", "city": "Pawnee", "hobbies": [ "soccer" ], "school": "Pawnee Elementary" }
  • 95.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents Discover the 4 major advantages of documents Change your mindset in 3 key ways Embrace document diversity Data that is accessed together should be stored together @Lauren_Schaefer @Lauren_Schaefer { a: “b”, c: { d: “e” ... }, f: [“g”, “h”, “i”], j: [ { k: “l” }, { m: “n” } ] }
  • 96.
    The mental journeyfrom tables to documents Map terms & concepts from tables to documents Discover the 4 major advantages of documents Change your mindset in 3 key ways Embrace document diversity Data that is accessed together should be stored together Tread carefully with transactions @Lauren_Schaefer @Lauren_Schaefer { ... } { ... } { ... } { ... } { ... } { ... } { ... }
  • 97.
    Don’t be Ron Swanson (inthis particular case) @Lauren_Schaefer
  • 98.
    Change your mindset andget the full value of document databases @Lauren_Schaefer
  • 99.
    Additional resources SQL toMongoDB Blog (blog series) Quick Start: MongoDB and Node.js (blog series & video series) Advanced Schema Design Patterns (webinar) Building with Patterns: A Summary (blog series) A Summary of Schema Design Anti-Patterns and How to Spot Them (blog series & video series) M320: Data Modeling (MongoDB University Course) JSON Schema Validation – Locking down your model the smart way (blog) @Lauren_Schaefer
  • 100.
    Give document databasesa try using MongoDB Atlas Get the slides on my Twitter page: @Lauren_Schaefer @Lauren_Schaefer