For the Rest of Us
How NoSQL databases work
Why they are thought about in the wrong way
Using Dynamo as a case study
Martin McKeaveney
TODO
Co-founder @
Amazon DynamoDB is a fully managed, multi region key-value and document database, providing single digit millisecond performance at any scale.
NoSQL is not "worse" - people give up because they aren't used to it and try to apply relational patterns to it
"Flexibility" is ultimately a sales pitch for NoSQL
Extra work upfront.
Define your access patterns
OLAP vs OLTP - Aggregations and rollups
You know what’s really good at maintaining referential integrity and optimizing JOINs? A relational database.
Amazon built dynamo in house
Dynamo serves over 1 trillion requests per day
DynamoDB is used by Lyft to store GPS locations for all their rides,
Tinder to store millions of user profiles and make billions of matches
BMW to run its car-as-a-sensor service that can scale up and down by two orders of magnitude within 24 hours
Under Armour to support its connected fitness community of 200 million users
Toyota Racing to make real time decisions on pit-stops, tire changes, and race strategy, and another 100,000+ AWS customers for a wide variety of high-scale, high-performance use cases.
DynamoDB won't let you write a bad query"
A grouping of data records.
Think Tables in SQL
An item is a single data record in a table.
uniquely identified by the stated primary key of the table.
Think Rows in SQL
Attributes are pieces of data attached to a single item.
Attributes must have a type.
Think columns in SQL
Scalar − These types represent a single value, and include number, string, binary, Boolean, and null.
Document − These types represent a complex structure possessing nested attributes, and include lists and maps.
Set − These types represent multiple scalars, and include string sets, number sets, and binary sets.
2 Types
Simple or Composite
"Give me all the MOT appointments at the Belfast test centre, gate 2 ordered by time."
// async function abstraction
async function queryItems(centreGate){
const params = {
TableName: 'MOTAppointment',
ExpressionAttributeNames: { '#key': 'CentreGate' },
ExpressionAttributeValues: { ':centregate': centreGate },
// this is the actual query
KeyConditionExpression: '#key = :centregate',
}
try {
const data = await docClient.query(params).promise()
return data
} catch (err) {
return err
}
}
queryItems("Belfast:2");
// returns all MOT appointments in at gate 2 in Belfast
// ordered by time ascendingRead request unit: A strongly consistent read request of up to 4 KB requires one read request unit. For items up to 4 KB in size, an eventually consistent read request requires one-half read request unit.
Write request unit: A standard write request unit can write an item up to 1 KB. For items larger than 1 KB, additional write request units are required.
You can only QUERY indexed data in dynamo. This is how it stays fast and scalable.
We can't query non-key attributes without doing a filter.
A filter will filter down the results AFTER a query, meaning you are paying for all the rows you query before the filter.
Can only be used on a table with a composite primary key.
You specify an index with the same PARTITION key but a different SORT key for a table.
Must be defined on table creation
Global secondary indexes can be used to specify a completely different key structure for a table.
Eg. Engineering#Dublin#VP
// async function abstraction
async function queryItems(company, depOfficeRole) {
const params = {
TableName: "WorldwideEmployees",
ExpressionAttributeNames: {
"#company": "Company",
"#depOfficeRole": "DepartmentOfficeRole",
},
KeyConditionExpression:
"#company = :company and begins_with(#depOfficeRole, :depOfficeRole)",
ExpressionAttributeValues: {
":company": company,
":depOfficeRole": officeDepartmentRole,
},
};
try {
const data = await docClient.query(params).promise();
return data;
} catch (err) {
return err;
}
}
// Give me everyone who works at Stripe,
// organised by department office and job role
queryItems("Stripe");
// Give me everyone who works in Engineering at Googles Zurich Office
queryItems("Google", "Engineering#Zurich");
// Give me all the Designers in Intercoms San Francisco Office
queryItems("Intercom", "UX#SanFrancisco#Designer");