Top Banner
Functional Database Strategies Scalæ by the Bay 2016
101

Functional Database Strategies

Apr 05, 2017

Download

Engineering

Jason Swartz
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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