Más contenido relacionado Similar a Functional Database Strategies at Scala Bay (20) Functional Database Strategies at Scala Bay10. 1. Functional DB’s In Scala
a. Doobie
2. Functional DB’s In The Database
a. Immutable Rows
b. Window Functions
c. Events, Not State
Agenda
11. 1. Functional DB’s In Scala
a. Doobie
2. Functional DB’s In The Database
a. Immutable Rows
b. Window Functions
c. Events, Not State
Agenda
12. 1. Functional DB’s In Scala
a. Doobie
2. Functional DB’s In The Database
a. Immutable Rows
b. Window Functions
c. Events, Not State
Agenda
15. ● Avoid shared mutable SESSIONS
● Avoid shared mutable CURSORS
● Mutating state? Cool! But MODEL IT FIRST
● Execute state changes at THE EDGE
Safe Database Interactions
18. val xa: Transactor[Task] =
DriverManagerTransactor[Task](
"org.postgresql.Driver",
"jdbc:postgresql://localhost/issues",
"u", "p"
)
19. case class Issue(id: Int, issueId: Int, title: String,
assignee: Int, status: String)
val issue: Issue = sql"""
select id, issue_id, title, assignee, status
from issues where issue_id = ${req.issue_id}
order by id desc limit 1
"""
.query[Issue]
.unique
.transact(xa)
.unsafePerformSync
20. ● ResultSet to Case Class Conversion
● Async IO modeling with Task (scalaz version)
● Think in SQL, not an ORM
● Plain SQL with sql"" interpolation
● SQL functions supported
Why Doobie?
21. 1. Functional DB’s In Scala
a. Doobie
2. Functional DB’s In The Database
a. Immutable Rows
b. Window Functions
c. Events, Not State
Agenda
22. 1. Functional DB’s In Scala
a. Doobie
2. Functional DB’s In The Database
a. Immutable Rows
b. Window Functions
c. Events, Not State
Agenda
29. 1. POST /issues title=’Config ELB’
+------+-------------+------------+----------+-------+
| id | updated | title | assignee | done |
+------+-------------+------------+----------+-------+
| 1 | 09-18 18:13 | Config ELB | NULL | false |
+------+-------------+------------+----------+-------+
30. 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 |
+------+-------------+------------+----------+-------+
31. 1. POST /issues title=’Config ELB’
2. PUT /issues/1 assignee=10
3. PUT /issues/1 done=true
+------+-------------+------------+----------+-------+
| id | updated | title | assignee | done |
+------+-------------+------------+----------+-------+
| 1 | 09-18 18:24 | Config ELB | NULL | true |
+------+-------------+------------+----------+-------+
32. 1. POST /issues title=’Config ELB’
2. PUT /issues/1 assignee=10
3. PUT /issues/1 done=true
+------+-------------+------------+----------+-------+
| id | updated | title | assignee | done |
+------+-------------+------------+----------+-------+
| 1 | 09-18 18:24 | Config ELB | NULL | true |
+------+-------------+------------+----------+-------+
Not Bad.
33. 1. POST /issues title=’Config ELB’
2. PUT /issues/1 assignee=10
3. 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?
35. 1. POST /issues title=’Config ELB’
2. PUT /issues/1 assignee=10
3. 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?
36. 1. POST /issues title=’Config ELB’
2. PUT /issues/1 assignee=10
3. PUT /issues/1 done=true
+------+-------------+------------+----------+-------+
| id | updated | title | assignee | done |
+------+-------------+------------+----------+-------+
| 1 | 09-18 18:24 | Config ELB | NULL | true |
+------+-------------+------------+----------+-------+
Why is ‘assignee’ NULL?
40. 1. POST /issues title=’Config ELB’
+------+-------------+------------+----------+-------+
| id | updated | title | assignee | done |
+------+-------------+------------+----------+-------+
| 1 | 09-18 18:13 | Config ELB | NULL | false |
+------+-------------+------------+----------+-------+
41. 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 |
+------+-------------+------------+----------+-------+
42. 1. POST /issues title=’Config ELB’
2. PUT /issues/1 assignee=10
3. 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 |
+------+-------------+------------+----------+-------+
43. 1. POST /issues title=’Config ELB’
2. PUT /issues/1 assignee=10
3. 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 |
+------+-------------+------------+----------+-------+
44. 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 |
+------+-------------+------------+----------+-------+
52. 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 |
+------+-------------+------------+----------+-------+
53. create table issues (
id serial,
created timestamp default now(),
issue_id int default nextval(‘iseq’),
title text,
assignee int,
done boolean default false
)
54. 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 |
+------+-------------+------------+------------+----------+-------+
55. select * from issues
where issue_id = :issue_id
order by id desc limit 1;
57. ISSUES
+------+-------------+------------+------------+----------+-------+
| 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 |
+------+-------------+------------+------------+----------+-------+
58. create table issues (
id serial,
created timestamp default now(),
issue_id int default nextval(‘iseq’),
title text,
assignee int,
done boolean default false )
create table notifications (
id serial,
created timestamp default now(),
issue_row_id int references issues )
59. ISSUES
+------+-------------+------------+------------+----------+-------+
| 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 |
+------+-------------+------------+------------+----------+-------+
NOTIFICATIONS
+------+-------------+--------------+
| id | created | issue_row_id |
+------+-------------+--------------+
| 1 | 09-18 19:13 | 2 |
+------+-------------+--------------+
60. ISSUES
+------+-------------+------------+------------+----------+-------+
| 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 |
+------+-------------+------------+------------+----------+-------+
NOTIFICATIONS
+------+-------------+--------------+
| id | created | issue_row_id |
+------+-------------+--------------+
| 1 | 09-18 19:13 | 2 |
+------+-------------+--------------+
63. 1. Functional DB’s In Scala
a. Doobie
2. Functional DB’s In The Database
a. Immutable Rows
b. Window Functions
c. Events, Not State
Agenda
64. 1. Functional DB’s In Scala
a. Doobie
2. Functional DB’s In The Database
a. Immutable Rows
b. Window Functions
c. Events, Not State
Agenda
67. ● Aggregation functions, eg sum(), rank(), avg()
● Window definitions with over()
● Grouping with partition by, order
Window Functions
68. +------+------------+------------+----------+-------+
| 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 |
+------+------------+------------+----------+-------+
69. +------+------------+------------+----------+-------+
| 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 |
+------+------------+------------+----------+-------+
70. 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
71. 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
72. 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
73. 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
74. +------+------------+------------+----------+-------+------------+
| 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 |
+------+------------+------------+----------+-------+------------+
75. +------+------------+------------+----------+-------+------------+
| 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 |
+------+------------+------------+----------+-------+------------+
76. +------+------------+------------+----------+-------+------------+
| 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 |
+------+------------+------------+----------+-------+------------+
78. 1. Functional DB’s In Scala
a. Doobie
2. Functional DB’s In The Database
a. Immutable Rows
b. Window Functions
c. Events, Not State
Agenda
79. 1. Functional DB’s In Scala
a. Doobie
2. Functional DB’s In The Database
a. Immutable Rows
b. Window Functions
c. Events, Not State
Agenda
83. 1. POST /issues title=’Config ELB’
2. PUT /issues/1 assignee=10
3. 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 |
+------+-------------+------------+----------+-------+
84. 1. POST /issues title=’Config ELB’
2. PUT /issues/1 assignee=10
3. 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
90. create table issue_events (
id serial,
created timestamp default now(),
issue_id int default nextval(‘iseq’),
originator text,
payload text
)
91. 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... | <...> |
+----+-------------+----------+------------+---------+
97. 1. High Write Performance
2. Potential for Command/Query Separation
3. Auditable
4. Replayable
5. Undo-able
6. Monitorable
Reasons For Event-Sourcing
101. 1. Frankly, It’s Weird
2. Requires Events. No Events, No Event-Sourcing.
3. As Of March 2017, It’s Still Non-Standard
Reasons Against Event-Sourcing