MongoDB Days Silicon Valley: From Story to Document: Applying MongoDB Thinking to Business...

Post on 06-Jan-2017

929 views 0 download

Transcript of MongoDB Days Silicon Valley: From Story to Document: Applying MongoDB Thinking to Business...

From Story to DocumentAPPLYING MONGO ORIENTED THINKING TO BUSINESS REQUIREMENTS

NURI HALPERIN | MONGODB DAYS SILICON VALLEY 2015

Why are we here?

MongoDB SQL

Square pegs, round holes

Experience

Habits

Document

From Tables to Documents

Document

A team story

Good News Everyone!

"Maker Space"

"Victory!"

Let's plan this!

Tables!Constraints!

Normalization!

Person

id UUID

first_name nvarchar(32)

last_name nvarchar(32)

Makers are People!

Person

id UUID

first_name nvarchar(32)

last_name nvarchar(32)

Maker

person_id UUID

status_id Int (not null)

Maker Status

id int

status varchar(16)

Tool

id UUID

name nvarchar(32)

Tool

id UUID

name nvarchar(32)

tool_type_id int

Tool Type

id int

name vharchar

"hand" | "power"

Is everything a tool?

Tool

asset_id UUID

tool_type_id int

Tool Type

id int

name vharchar

is_certifiable bit (not null)

Asset

id UUID

name nvarchar(32)

is_stationary bit

Certification

id UUID

tool_type_id int

date datetime

Maker Certification

member_id UUID

certification_id UUID

date datetime

Person

id UUID

first_name nvarchar(32)

last_name nvarchar(32)

Tool Type

id int

name vharchar

is_certifiable bit (not null)

Tool

asset_id UUID

tool_type_id int

Tool Type

id int

name vharchar

Asset

id UUID

name nvarchar(32)

is_stationary bit

Certificationperson_id UUIDtool_type_id UUIDname varchar(16)

Member Certification

member_id UUIDcertification_id UUIDdate datetime

Member Tool Log

asset_id UUID

type_id int

Person

id UUID

first_name nvarchar(32)

last_name nvarchar(32)

Maker

person_id UUID

status_id Int (not null)

Maker Status

id int

status varchar(16)

Must. Not. Overthink.

Maker gets certified

Borrow & return tool

Report tool usage

Thinking Document

Key interactions drivesdocument design.

Tool

asset_id UUID

type_id int

Tool Type

id int

name vharchar

Asset

id UUID

name nvarchar(32)

is_stationary bit

Certificationperson_id UUIDasset_id UUIDname varchar(16)

Member Certification

member_id UUIDcertification_id UUID

Member Tool Logasset_id UUIDtype_id int

date datetime

Person

id UUID

first_name nvarchar(32)

last_name nvarchar(32)

Maker

person_id UUID

status_id Int (not null)

Maker Status

id int

status varchar(16)

We can do anything!

Generic Purpose-Built

Speed

Efficiency

Scale

Agility

Complexity

Performance

Cost

{_id: ObjectId('…'),name: 'Martha',

}

"Person"

{_id: ObjectId('…'),name: 'Martha',status: 'paid'

}

"Person"

"Maker"

{_id: ObjectId('…'),name: 'Martha',status: 'paid',certified: [{t:'cnc', d:'2015-11-

26'}],}

Get Certified

{_id: ObjectId('…'),name: 'Martha',status: 'paid',certified: [{t:'cnc', d:'2015-11-

26'}],}

db.maker.update({name: 'Martha', 'certified.t':

{$ne:'cnc'}},{ $push:

{certified: {t:'cnc', d: ISODate()} }

}

{_id: ObjectId('…'),name: 'Martha',status: 'paid',certified: [{t:'cnc', d:'2015-11-

26'}],}

Certification

id UUID

person_id UUID

tool_type_id int

date datetime

Maker Certification

member_id UUID

certification_id UUID

Person

id UUID

first_name nvarchar(32)

last_name nvarchar(32)

Thinking Document

Data that works together lives together.

Tables!Constraints!

Normalization!

if ( tool.type != 'hand') {alert('Certification

Required');}

{ _id: 1, name: 'knife', type: 'hand'}{ _id: 2, name: 'drill', type: 'power'}{ _id: 3, name: 'lathe', type: 'stationary'}

if ( tool.type != 'hand') {alert('Certification

Required');}

{ _id: 1, name: 'knife', type: 'hand'}{ _id: 2, name: 'drill', type: 'power'}{ _id: 3, name: 'lathe', type: 'stationary'}{ _id: 4, name: 'scope', type: 'instrument'}

Careful!

X

{ _id: 1, name: 'knife', …, req: false}{ _id: 2, name: 'drill', …, req: true}{ _id: 3, name: 'lathe', …, req: true}{ _id: 4, name: 'scope', …, req: true}

There, I fixed it!

if (tool.requiresCertification) {alert('Certification

Required');}

{ _id: 1, name: 'knife', type: 'hand'}{ _id: 2, name: 'drill', type: 'power'}{ _id: 3, name: 'lathe', type: 'stationary'}{ _id: 4, name: 'scope', type: 'instrument'}X

public enum ToolType {HAND, POWER, STATIONARY

};

OOP, Oops!

Extra Field :: TablesDOWN TIME? COORDINATED DEPLOYMENT?

ALTER TABLE [x]

ADD COLUMN [is_certifiable] bit

DEFAULT 0

Extra Field :: MongoDBFLEXIBLE SCHEMA, CODE FIRST

> db.x.insert({ …, is_certifiable: true})

> db.x.update( {_id: 123}, {$set:{is_certifiable: true}})

On the fly!

Thinking Document

Embed immutable data.

{_id: 1, name: 'scope', borrows: [

{ maker_id: 1, dt: ISODate('2015-06-12'), type: 'out'},

{ maker_id: 1, dt: ISODate('2015-07-04'), type: 'in'},

] }

{ _id: 1, name: 'scope', borrows: [

{ maker_id: 1, dt: ISODate('2015-06-12'), type: 'out'},

{ maker_id: 1, dt: ISODate('2015-07-04'), type: 'in'}, ] }

Embed?Ownership?

Work together?

Bound growth?

Lifetime?

{_id: …,maker: { _id: 17, name: 'bob' }tool : { _id: 1, name: 'scope'},date: ISODate('2015-11-26 18:30Z'),action: 'out'

}

Check tool in / out

Ledger

Maker gets certified

Borrow & return tool

Report tool usage?

db.toolLog.aggregate([{$match: {action: 'out', date: {$gte: ISODate('2015-09-01')

}}},{$group: {_id: "$tool.name", count: {$sum: 1}}},{$sort: {count: -1}}

]);

{ "_id" : "hammer", "count" : 2 }{ "_id" : "torch", "count" : 1 }

db.toolLog.aggregate([{$match: {action: 'out', date: {$gte: ISODate('2015-09-01') }}},

{$group: {_id: "$maker.name", count: {$sum: 1}}},{$sort: {count: -1}}

]);

{ "_id" : "bob", "count" : 2 }{ "_id" : "kim", "count" : 1 }

{ "maker" : "kim", "has" : "hammer", "since" : ISODate("2015-10-03…"), "days" : 31

}

{ "maker" : "bob", "has" : "torch", "since" : ISODate("2015-09-03…"), "days" : 61

}

"Audit Report"

db.toolLog.aggregate([{$sort: {date: -1}},{$group: {

_id: "$tool", action: {$first: "$action"}, at: {$first: "$date"}, by: {$first: "$maker"} }

},{$match: {action: "out"}},{$project: {

_id: 0,"maker": "$by.name", "has": "$_id.name",since: "$at",days: {$divide:[{$subtract: [{$literal: ISODate()}, "$at"]},

1000*60*60*24]}}}

]);

"Audit Report"

{_id: …,maker: { _id: 17, name: 'bob' }tool : { _id: 123, name: 'hammer'},date: ISODate('2015-11-26 18:30Z'),action: 'check-out'

}

db.toolLog.createindex({date: 1,

"tool.name": 1})

Thinking Document

Let the engine work for you

Toolasset_id UUIDtype_id int

Tool Typeid intname vharchar

Assetid UUIDname nvarchar(32)is_stationary bit

TableLand

Certificationperson_id UUIDasset_id UUIDname varchar(16)

Member Certificationmember_id UUIDcertification_id UUID

Personid UUIDfirst_name nvarchar(32)last_name nvarchar(32)

Maker

person_id UUID

status_id Int (not null)

Maker Statusid intstatus varchar(16)

Member Tool Logasset_id UUIDtype_id int

date datetime

maker

tool

toolLog

{_id: 17,name: 'bob',status: 'paid',certified: [

{t:'cnc', d:'2015-11-26'}

],}

{_id: 2,name: 'drill',type: 'power',

}

{_id: 789234,maker: { _id: 17, name:

'bob' }tool : { _id: 2, name:

'drill'},date: ISODate('2015-11-26

18:30Z'),action: 'check-out'

}

Thinking Document

Key interactions drivesdocument design.

Thinking Document

Data that works together lives together.

Thinking Document

Embed immutable data.

Thinking Document

Let the engine work for you

Thinking Document

*Rules enforced by application.

Thank you! Nuri Halperin +N Consulting nuri@plusnconsulting.com nurih @nurih