functional database strategies

101
Functional Database Strategies Scalæ by the Bay 2016

Upload: jason-swartz

Post on 05-Apr-2017

89 views

Category:

Engineering


0 download

TRANSCRIPT

Page 1: Functional Database Strategies

Functional Database Strategies

Scalæ by the Bay 2016

Page 2: Functional Database Strategies

YesQL

Page 3: Functional Database Strategies

by Jason Swartz@swartzrock

Page 4: Functional Database Strategies
Page 5: Functional Database Strategies

Functional Database Strategies

Page 6: Functional Database Strategies

Step One

Buy A Functional Database

Page 7: Functional Database Strategies

Silly! Databases Aremutable, not

functional!

Page 8: Functional Database Strategies

Well?Aren’t they?

Page 9: Functional Database Strategies

1. Immutable Rows2. Window Functions3. Events, Not State4. DB Interactions

Agenda

Page 10: Functional Database Strategies

1. Immutable Rows2. Window Functions3. Events, Not State4. DB Interactions

Agenda

Page 11: Functional Database Strategies

Let’s Talk AboutImmutable Tables

Page 12: Functional Database Strategies
Page 13: Functional Database Strategies
Page 14: Functional Database Strategies

Create-Read-Update-Delete

Page 15: Functional Database Strategies

GET /issuesGET /issues/{id}POST /issuesPUT /issues/{id}

Issue Endpoints

Page 16: Functional Database Strategies

How Do These EventsAffect The Database?

Page 17: Functional Database Strategies

1. POST /issues title=’Config ELB’

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:13 | Config ELB | NULL | false |+------+-------------+------------+----------+-------+

Page 18: Functional Database Strategies

1. POST /issues title=’Config ELB’2. PUT /issues/1 assignee=10

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:16 | Config ELB | 10 | false |+------+-------------+------------+----------+-------+

Page 19: Functional Database Strategies

1. POST /issues title=’Config ELB’2. PUT /issues/1 assignee=103. PUT /issues/1 done=true

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:24 | Config ELB | NULL | true |+------+-------------+------------+----------+-------+

Page 20: Functional Database Strategies

1. POST /issues title=’Config ELB’2. PUT /issues/1 assignee=103. PUT /issues/1 done=true

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:24 | Config ELB | NULL | true |+------+-------------+------------+----------+-------+

Not Bad.

Page 21: Functional Database Strategies

1. POST /issues title=’Config ELB’2. PUT /issues/1 assignee=103. PUT /issues/1 done=true

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:24 | Config ELB | NULL | true |+------+-------------+------------+----------+-------+

Do You Know How We Got Here?

Page 22: Functional Database Strategies

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:24 | Config ELB | NULL | true |+------+-------------+------------+----------+-------+

Do You Know How We Got Here?

Page 23: Functional Database Strategies

1. POST /issues title=’Config ELB’2. PUT /issues/1 assignee=103. PUT /issues/1 done=true

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:24 | Config ELB | NULL | true |+------+-------------+------------+----------+-------+

Do You Know How We Got Here?

Page 24: Functional Database Strategies

1. POST /issues title=’Config ELB’2. PUT /issues/1 assignee=103. PUT /issues/1 done=true

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:24 | Config ELB | NULL | true |+------+-------------+------------+----------+-------+

Why is ‘assignee’ NULL?

Page 25: Functional Database Strategies

Mutable Table Rows Lose History

Page 26: Functional Database Strategies

Immutable Table Rows Keep Their History

Page 27: Functional Database Strategies

Let’s Try To Lock Down

Our State

Page 28: Functional Database Strategies

1. POST /issues title=’Config ELB’

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:13 | Config ELB | NULL | false |+------+-------------+------------+----------+-------+

Page 29: Functional Database Strategies

1. POST /issues title=’Config ELB’2. PUT /issues/1 assignee=10

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:13 | Config ELB | NULL | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:16 | Config ELB | 10 | false |+------+-------------+------------+----------+-------+

Page 30: Functional Database Strategies

1. POST /issues title=’Config ELB’2. PUT /issues/1 assignee=103. PUT /issues/1 done=true

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:13 | Config ELB | NULL | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:16 | Config ELB | 10 | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:19 | Config ELB | NULL | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:24 | Config ELB | NULL | true |+------+-------------+------------+----------+-------+

Page 31: Functional Database Strategies

1. POST /issues title=’Config ELB’2. PUT /issues/1 assignee=103. PUT /issues/1 done=true

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:13 | Config ELB | NULL | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:16 | Config ELB | 10 | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:19 | Config ELB | NULL | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:24 | Config ELB | NULL | true |+------+-------------+------------+----------+-------+

Page 32: Functional Database Strategies

1. GET /issues/1

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:13 | Config ELB | NULL | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:16 | Config ELB | 10 | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:19 | Config ELB | NULL | false |+------+-------------+------------+----------+-------+

+------+-------------+------------+----------+-------+| 1 | 09-18 18:24 | Config ELB | NULL | true |+------+-------------+------------+----------+-------+

Page 33: Functional Database Strategies

Tables Are Mutable, But Table Rows Should Be

Immutable

Page 34: Functional Database Strategies

In Other Words, Tables Should Be

Append-Only

Page 35: Functional Database Strategies

How Do You Make An Append-Only

Table?

Page 36: Functional Database Strategies

One: Don’t Let Your DB User Make

Changes

Page 37: Functional Database Strategies

Grant select, insert on issues to my-db-user;

-- tested on Postgresql

Page 38: Functional Database Strategies

Thank You! Goodbye!

Page 39: Functional Database Strategies

Two: Pick The RightColumns

Page 40: Functional Database Strategies

1. GET /issues/1

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:13 | Config ELB | NULL | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:16 | Config ELB | 10 | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:19 | Config ELB | NULL | false |+------+-------------+------------+----------+-------+

+------+-------------+------------+----------+-------+| 1 | 09-18 18:24 | Config ELB | NULL | true |+------+-------------+------------+----------+-------+

Page 41: Functional Database Strategies

create table issues ( id serial, created timestamp default now(), issue_id int default nextval(‘iseq’), title text, assignee int, done boolean default false)

Page 42: Functional Database Strategies

1. GET /issues/1

+------+-------------+------------+------------+----------+-------+| id | created | issue_id | title | assignee | done |+------+-------------+------------+------------+----------+-------+| 1 | 09-18 18:13 | 1 | Config ELB | NULL | false |+------+-------------+------------+------------+----------+-------+| 2 | 09-18 18:16 | 1 | Config ELB | 10 | false |+------+-------------+------------+------------+----------+-------+| 3 | 09-18 18:19 | 1 | Config ELB | NULL | false |+------+-------------+------------+------------+----------+-------+

+------+-------------+------------+------------+----------+-------+| 4 | 09-18 18:24 | 1 | Config ELB | NULL | true |+------+-------------+------------+------------+----------+-------+

Page 43: Functional Database Strategies

select * from issueswhere issue_id = :issue_idorder by id desc limit 1;

Page 44: Functional Database Strategies

That’s The Basics Of Immutability

In Table Rows

Page 45: Functional Database Strategies

1. Immutable Rows2. Window Functions3. Events, Not State4. DB Interactions

Agenda

Page 46: Functional Database Strategies

1. Immutable Rows2. Window Functions3. Events, Not State4. DB Interactions

Agenda

Page 47: Functional Database Strategies

SQL:2003 expands Groups into Windows

Page 48: Functional Database Strategies

Works Great InPostgresql

Page 49: Functional Database Strategies

● Aggregation functions, eg sum(), rank(), avg()● Window definitions with over()● Grouping with partition by, order

Window Functions

Page 50: Functional Database Strategies

+------+------------+------------+----------+-------+| id | issue_id | title | assignee | done |+------+------------+------------+----------+-------+| 1 | 1 | Config ELB | NULL | false |+------+------------+------------+----------+-------+| 2 | 1 | Config ELB | 10 | false |+------+------------+------------+----------+-------+| 3 | 2 | Bug to fix | 11 | false |+------+------------+------------+----------+-------+| 4 | 2 | Bug to fix | 11 | true |+------+------------+------------+----------+-------+

Page 51: Functional Database Strategies

+------+------------+------------+----------+-------+| id | issue_id | title | assignee | done |+------+------------+------------+----------+-------+| 1 | 1 | Config ELB | NULL | false |+------+------------+------------+----------+-------+| 2 | 1 | Config ELB | 10 | false |+------+------------+------------+----------+-------+| 3 | 2 | Bug to fix | 11 | false |+------+------------+------------+----------+-------+| 4 | 2 | Bug to fix | 11 | true |+------+------------+------------+----------+-------+

Page 52: Functional Database Strategies

with latest_issues as ( select *, row_number() over ( partition by issue_id order by id desc ) from issues where created > now() - interval '7 day')select * from latest_issues where row_number = 1

Page 53: Functional Database Strategies

with latest_issues as ( select *, row_number() over ( partition by issue_id order by id desc ) from issues where created > now() - interval '7 day')select * from latest_issues where row_number = 1

Page 54: Functional Database Strategies

with latest_issues as ( select *, row_number() over ( partition by issue_id order by id desc ) from issues where created > now() - interval '7 day')select * from latest_issues where row_number = 1

Page 55: Functional Database Strategies

with latest_issues as ( select *, row_number() over ( partition by issue_id order by id desc ) from issues where created > now() - interval '7 day')select * from latest_issues where row_number = 1

Page 56: Functional Database Strategies

+------+------------+------------+----------+-------+------------+| id | issue_id | title | assignee | done | row_number |+------+------------+------------+----------+-------+------------+| 1 | 1 | Config ELB | NULL | false | 2 |+------+------------+------------+----------+-------+------------+| 2 | 1 | Config ELB | 10 | false | 1 |+------+------------+------------+----------+-------+------------+| 3 | 2 | Bug to fix | 11 | false | 2 |+------+------------+------------+----------+-------+------------+| 4 | 2 | Bug to fix | 11 | true | 1 |+------+------------+------------+----------+-------+------------+

Page 57: Functional Database Strategies

+------+------------+------------+----------+-------+------------+| id | issue_id | title | assignee | done | row_number |+------+------------+------------+----------+-------+------------+| 1 | 1 | Config ELB | NULL | false | 2 |+------+------------+------------+----------+-------+------------+| 2 | 1 | Config ELB | 10 | false | 1 |+------+------------+------------+----------+-------+------------+| 3 | 2 | Bug to fix | 11 | false | 2 |+------+------------+------------+----------+-------+------------+| 4 | 2 | Bug to fix | 11 | true | 1 |+------+------------+------------+----------+-------+------------+

Page 58: Functional Database Strategies

+------+------------+------------+----------+-------+------------+| id | issue_id | title | assignee | done | row_number |+------+------------+------------+----------+-------+------------+| 1 | 1 | Config ELB | NULL | false | 2 |+------+------------+------------+----------+-------+------------+| 2 | 1 | Config ELB | 10 | false | 1 |+------+------------+------------+----------+-------+------------+| 3 | 2 | Bug to fix | 11 | false | 2 |+------+------------+------------+----------+-------+------------+| 4 | 2 | Bug to fix | 11 | true | 1 |+------+------------+------------+----------+-------+------------+

Page 59: Functional Database Strategies

That WasWindow

Functions

Page 60: Functional Database Strategies

1. Immutable Rows2. Window Functions3. Events, Not State4. DB Interactions

Agenda

Page 61: Functional Database Strategies

1. Immutable Rows2. Window Functions3. Events, Not State4. DB Interactions

Agenda

Page 62: Functional Database Strategies

You Know How To Maintain State

Page 63: Functional Database Strategies

Do We Still Need State?

Page 64: Functional Database Strategies

Let’s Talk AboutEvent-Sourcing

Page 65: Functional Database Strategies

1. POST /issues title=’Config ELB’2. PUT /issues/1 assignee=103. PUT /issues/1 done=true

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:13 | Config ELB | NULL | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:16 | Config ELB | 10 | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:24 | Config ELB | 10 | true |+------+-------------+------------+----------+-------+

Page 66: Functional Database Strategies

1. POST /issues title=’Config ELB’2. PUT /issues/1 assignee=103. PUT /issues/1 done=true

+------+-------------+------------+----------+-------+| id | updated | title | assignee | done |+------+-------------+------------+----------+-------+| 1 | 09-18 18:13 | Config ELB | NULL | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:16 | Config ELB | 10 | false |+------+-------------+------------+----------+-------+| 1 | 09-18 18:24 | Config ELB | 10 | true |+------+-------------+------------+----------+-------+

Events

States

Page 67: Functional Database Strategies
Page 68: Functional Database Strategies
Page 69: Functional Database Strategies
Page 70: Functional Database Strategies
Page 71: Functional Database Strategies

Now We’re Storing Events,

Not States

Page 72: Functional Database Strategies

create table issue_events ( id serial, created timestamp default now(), issue_id int default nextval(‘iseq’), originator text, payload text)

Page 73: Functional Database Strategies

1. POST /issue/1/event ‘Originator: 4a48239-8a..’ payload=’<Update val=”done=true”>’

+----+-------------+----------+------------+---------+| id | created | issue_id | originator | payload |+----+-------------+----------+------------+---------+| 14 | 09-18 18:50 | 1 | 4a482... | <...> |+----+-------------+----------+------------+---------+

Page 74: Functional Database Strategies

Create Events AndSimulate The State

Page 75: Functional Database Strategies

1. Create-Issue

Issue(“Config ELB”, null, false);

Real Events

Virtual States

Page 76: Functional Database Strategies

1. Create-Issue2. Assign-Issue

Issue(“Config ELB”, 10, false);

Real Events

Virtual States

Page 77: Functional Database Strategies

1. Create-Issue2. Assign-Issue3. Complete-Issue

Issue(“Config ELB”, 10, true);

Real Events

Virtual States

Page 78: Functional Database Strategies

So Why UseEvent-Sourcing?

Page 79: Functional Database Strategies

1. High Write Performance2. Potential for Command/Query Separation3. Auditable4. Replayable5. Undo-able6. Monitorable

Reasons For Event-Sourcing

Page 80: Functional Database Strategies

It’s Like Having Control Over The Versions Of

Your State Changes

Page 81: Functional Database Strategies

It’s Like Having Control Over The Versions Of

Your Data

Page 82: Functional Database Strategies

It’s Like GitFor Your Data

Page 83: Functional Database Strategies

1. Frankly, It’s Weird2. Requires Events. No Events, No Event-Sourcing.3. As Of November 2016, It’s Still Non-Standard

Reasons Against Event-Sourcing

Page 84: Functional Database Strategies

Wait! We’reScala

developers!

Page 85: Functional Database Strategies

Who Cares About BeingNon-Standard?

Page 86: Functional Database Strategies

That About Sums Up Event Sourcing

Page 87: Functional Database Strategies

1. Immutable Rows2. Window Functions3. Events, Not State4. DB Interactions

Agenda

Page 88: Functional Database Strategies

1. Immutable Rows2. Window Functions3. Events, Not State4. DB Interactions

Agenda

Page 89: Functional Database Strategies

Remember That YourDatabase

is mutable.

Page 90: Functional Database Strategies

Avoid SharingYour State

Page 91: Functional Database Strategies

● Avoid shared mutable SESSIONS ● Avoid shared mutable CURSORS ● Mutating state? Cool! But MODEL IT FIRST● Execute state changes at THE EDGE

Safe Database Interactions

Page 92: Functional Database Strategies

DoobieA Typelevel Project

Page 93: Functional Database Strategies

Are these steps? Or a Monad?

Page 94: Functional Database Strategies
Page 95: Functional Database Strategies

That About Sums Up Database

Interactions

Page 96: Functional Database Strategies

Okay, Actually That’s The Entire Talk

Unless There’s More Time

Page 97: Functional Database Strategies

Functional Database Strategies

Scalæ by the Bay 2016

Page 98: Functional Database Strategies

by Jason Swartz@swartzrock

Page 99: Functional Database Strategies

Thank You For Attending

Page 100: Functional Database Strategies

Fin

Page 101: Functional Database Strategies

THIS SPACELEFT BLANK