Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
データ履歴管理のための
テンポラルデータモデルと
Reladomoの紹介
株式会社FOLIO 伊藤博志
JJUG CCC 2017 Spring 2017.5.20
#ccc_g3
Reladomo is an open source soft...
1
株式会社FOLIOの紹介 hashtag: #ccc_g3
https://www.wantedly.com/companies/folio/projectsエンジニア募集中!
2
Agenda
1. 自己紹介
2. RDBMSで履歴データを扱う
 スナップショットデータモデル
 トランザクション時間データモデル
 有効時間データモデル
 バイテンポラルデータモデル
3. Javaからバイテンポラルモデルを容易...
3
自己紹介
趣味:ドラム演奏
JavaOneコミュニティバンド
Null Pointersで演奏経験あり(日本人初)
Tech Lead @ FOLIO
伊藤 博志
Eclipse Collections:共同プロジェクトリード兼コミッター
...
4
RDBMSで変更履歴をどう扱うか
hashtag: #ccc_g3
5
RDBMSで履歴データを扱う
単純なシナリオを考えてみましょう
シンプルな人事システム。扱う情報は姓名のみ。
 4月1日に「鈴木花子」さん入社。3月1日にシステムに登録
 6月6日に結婚し、姓が「斎藤」に変更。同日システム上に
間違えて...
6
RDBMSで履歴データを扱う
 シナリオをよく観察すると、2種類の履歴が存在
hashtag: #ccc_g3
3/1 4/1 6/6 6/8 12/1
鈴木花子
事実情報の
履歴
システムに
反映された
履歴
入社🎉
「鈴木花子」を
シ...
7
RDBMSで履歴データを扱う
最新の情報さえ
分かれば良い
いつシステムに
反映されたか履
歴が知りたい
2種類の履歴から考えうる4種類の要件
事実情報の履歴
が知りたい
事実情報と、い
つシステムに反
映されたか両方
の履歴が知りた
い
...
8
RDBMSで履歴データを扱う
スナップショットデータモデル
トランザクション時間データモデル
有効時間データモデル
バイテンポラルデータモデル
各要件を満たすために、4つのデータモデルが考えられる
hashtag: #ccc_g3
9
スナップショットデータモデル
hashtag: #ccc_g3
最新の情報さえ
分かれば良い
10
スナップショットデータモデル
 スナップショットデータモデルで表現できるのは、最新
の情報のみ(履歴は表現できない)
hashtag: #ccc_g3
3/1 4/1 6/6 6/8 12/1
鈴木花子
事実情報の
履歴
システムに
反...
11
スナップショットデータモデル
姓 名 inserted_at updated_at
鈴木 花子 2017/3/1 2017/3/1
 4月1日に「鈴木花子」さん入社。3月1日にシステムに登録
鈴木さん入社!
入社日というカラムが
あって...
12
スナップショットデータモデル
 6月6日に結婚し、姓が「斎藤」に変更。同日システム
上に間違えて「斉藤」と登録
間違えて「斉藤」と入
力してしまいました
姓 名 inserted_at updated_at
斉藤 花子 2017/3/1...
13
スナップショットデータモデル
 6月8日にシステム上で修正(斉藤=>斎藤)
正しい姓は「斎藤」さ
んですね。。。
姓 名 inserted_at updated_at
斎藤 花子 2017/3/1 2017/6/8
hashtag: #...
14
スナップショットデータモデル
 12月1日、退職にともない同日に人事情報をシステム上
で無効化
_人人人人人人人人人人人_
> 物理削除 <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
物理削除がイヤ
なら禁断の論理
削除フラグとい
う...
15
スナップショットデータモデル
 スナップショットデータモデルで履歴を実装しようと
すると、バージョンカラムや履歴テーブルを別に用意
するなど、力技が求められる
 世に存在する履歴系のデータは、この力技で実装され
ていることが多い(印象...
16
トランザクション時間データモデル
hashtag: #ccc_g3
いつシステムに
反映されたか履
歴が知りたい
17
トランザクション時間データモデル
 トランザクション時間データモデルで表現できるのは、
「システムに反映された」履歴
hashtag: #ccc_g3
3/1 4/1 6/6 6/8 12/1
鈴木花子
事実情報の
履歴
システムに
反...
18
トランザクション時間データモデル
姓 名 IN OUT
鈴木 花子 2017/3/1 9999/12/1
鈴木さん入社!
INはデータベースに挿入された日付、
OUTはその行が無効になった(なる)日付、
OUTはデフォルトでINFINIT...
19
トランザクション時間データモデル
姓 名 IN OUT
鈴木 花子 2017/3/1 2017/6/6
斉藤 花子 2017/6/6 9999/12/1
鈴木さん姓が2017/6/6に無効(OUT)
になり、斉藤さん姓が同日入力(IN)
...
20
トランザクション時間データモデル
姓 名 IN OUT
鈴木 花子 2017/3/1 2017/6/6
斉藤 花子 2017/6/6 2017/6/8
斎藤 花子 2017/6/8 9999/12/1
斉藤さん姓が2017/6/8に無効(...
21
トランザクション時間データモデル
姓 名 IN OUT
鈴木 花子 2017/3/1 2017/6/6
斉藤 花子 2017/6/6 2017/6/8
斎藤 花子 2017/6/8 2017/12/1
2017/12/1日付で無効化(OU...
22
トランザクション時間データモデル
履歴データをどう検索するのか?
hashtag: #ccc_g3
23
トランザクション時間データモデル
 任意の時間Xにデータベース上で最新だった情報を
とってくる
select * from EMPLOYEE
where IN < X
and OUT >= X
hashtag: #ccc_g3
24
トランザクション時間データモデル
姓 名 IN OUT
鈴木 花子 2017/3/1 2017/6/6
 3月15日時点でデータベース上で最新だった情報を
とってくる
select * from EMPLOYEE
where IN < ...
25
トランザクション時間データモデル
姓 名 IN OUT
斉藤 花子 2017/6/6 2017/6/8
select * from EMPLOYEE
where IN < “2017/6/7”
and OUT >= “2017/6/7”
...
26
トランザクション時間データモデル
姓 名 IN OUT
斎藤 花子 2017/6/8 2017/12/1
姓 名 IN OUT
鈴木 花子 2017/3/1 2017/6/6
斉藤 花子 2017/6/6 2017/6/8
斎藤 花子 2...
27
トランザクション時間データモデル
姓 名 IN OUT
select * from EMPLOYEE
where IN < “2017/12/5"
and OUT >= “2017/12/5”
姓 名 IN OUT
鈴木 花子 2017/...
28
トランザクション時間データモデル
 ある時点でデータベース上で最新だった情報を一意に
取得することができる
 過去の履歴を一気に取得することもでき、時間軸で
ソートも可
 最新の行を無効化するにはOUTコラムを更新するだけ
でOK(...
29
有効時間データモデル
hashtag: #ccc_g3
事実情報の履歴
がほしい
30
有効時間データモデル
 有効時間データモデルで表現できるのは、「事実情報」
の履歴
hashtag: #ccc_g3
3/1 4/1 6/6 6/8 12/1
鈴木花子
事実情報の
履歴
システムに
反映された
履歴
入社🎉
「鈴木花子...
31
有効時間データモデル
姓 名 FROM THRU
鈴木 花子 2017/4/1 9999/12/1
 4月1日に「鈴木花子」さん入社。3月1日にシステムに登録
鈴木さん入社!
FROMは当該データが事実として有効である最初の日、
THR...
32
有効時間データモデル
姓 名 FROM THRU
鈴木 花子 2017/4/1 2017/6/6
斉藤 花子 2017/6/6 9999/12/1
 6月6日に結婚し、姓が「斎藤」に変更。同日システム
上に間違えて「斉藤」と登録
事実と...
33
有効時間データモデル
姓 名 FROM THRU
鈴木 花子 2017/4/1 2017/6/6
斎藤 花子 2017/6/6 9999/12/1
2017/6/6(FROM)から正しい「斎藤」さん
姓になった。間違えた「斉藤」姓は上書き...
34
有効時間データモデル
姓 名 FROM THRU
鈴木 花子 2017/4/1 2017/6/6
斎藤 花子 2017/6/6 2017/12/1
 12月1日、退職にともない同日に人事情報をシステム上
で無効化
これで
鈴木さんが20...
35
有効時間データモデル
検索方法はトランザクション時間
データモデルの場合と同様なので省略
hashtag: #ccc_g3
36
有効時間データモデル
 ある時点での「事実情報」を一意に取得することがで
きる
 過去の事実の履歴を一気に取得することもでき、時間
軸でソートも可
 最新の行を無効化するにはTHRUコラムを更新するだ
けでOK(物理削除も論理削除フ...
37
バイテンポラルデータモデル
hashtag: #ccc_g3
事実情報と、い
つシステムに反
映されたか両方
の履歴が知りた
い
38
バイテンポラルデータモデル
 バイテンポラルデータモデルで表現できるのは、「シス
テムに反映された」履歴と「事実情報」の履歴両方
hashtag: #ccc_g3
3/1 4/1 6/6 6/8 12/1
鈴木花子
事実情報の
履歴
シ...
39
バイテンポラルデータモデル
姓 名 FROM THRU IN OUT
鈴木 花子 2017/4/1 9999/12/1 2017/3/1 9999/12/1
 4月1日に「鈴木花子」さん入社。3月1日にシステムに登録
鈴木さん入社!
4...
40
バイテンポラルデータモデル
姓 名 FROM THRU IN OUT
鈴木 花子 2017/4/1 9999/12/1 2017/3/1 2017/6/6
鈴木 花子 2017/4/1 2017/6/6 2017/6/6 9999/12/...
41
バイテンポラルデータモデル
姓 名 FROM THRU IN OUT
鈴木 花子 2017/4/1 9999/12/1 2017/3/1 2017/6/6
鈴木 花子 2017/4/1 2017/6/6 2017/6/6 9999/12/...
42
バイテンポラルデータモデル
姓 名 FROM THRU IN OUT
鈴木 花子 2017/4/1 9999/12/1 2017/3/1 2017/6/6
鈴木 花子 2017/4/1 2017/6/6 2017/6/6 9999/12/...
43
バイテンポラルデータモデル
 バイテンポラルデータモデルは「システム履歴」と
「事実情報の履歴」を同時に正しく表現することがで
きる非常に強力なモデル
バイテンポラルデータモデルの適用例
 監査履歴が重要な金融システムの基幹データ
...
44
どう実装する?
バイテンポラルデータモデル
の雰囲気はわかった
でも、ぱっと見複雑そう。
結局、実装するのが大変
なのでは。。。?
安心してください
Reladomoを使えば簡単です!
hashtag: #ccc_g3
45
Javaからバイテンポラルモデルを
容易に扱えるReladomoの紹介
hashtag: #ccc_g3
46
Reladomoとは
https://github.com/goldmansachs/reladomo
 ゴールドマン・サックス社が2016年10月にGitHubに
OSSとして公開したJava ORMフレームワーク
 Apache ...
47
Reladomoとは
Reladomoのコード生成
 xmlによるエンティティ定義を用いてコード生成
 同xmlからddlの生成も可能
 Abstract Classはxmlに変更のある都度生成される
 Concrete Clas...
48
Employeeエンティティ定義ファイル hashtag: #ccc_g3
<MithraObject objectType="transactional"
xmlns:xsi="http://www.w3.org/2001/XMLSch...
49
Employeeエンティティ hashtag: #ccc_g3
トランザクション時間
生成されたAbstract Class
50
Employeeエンティティ hashtag: #ccc_g3
Concrete Class (初回のみ生成)
さまざまなビジネスロジックを記述できる
51
DBトランザクション hashtag: #ccc_g3
テンポラルオブジェクトの挿入、更新はトランザクション内で
のみ可能
(以降のコード例では省略している場合も)
Employee hanako =
MithraManagerProvi...
52
ReladomoのFinder DSL
 型付けられた強力なクエリー言語
 自動生成されたフィールドを用いてOperationを構築
hashtag: #ccc_g3
Operation op = EmployeeFinder.las...
53
Reladomoでトランザクション時間
を扱う例
hashtag: #ccc_g3
54
Employeeエンティティ定義ファイル hashtag: #ccc_g3
<MithraObject objectType="transactional"
xmlns:xsi="http://www.w3.org/2001/XMLSch...
55
トランザクション時間データモデル
姓 名 IN OUT
鈴木 花子 2017/3/1 9999/12/1
hashtag: #ccc_g3
//3月1日にこのコードが実行される
Employee hanakoNew = new Emplo...
56
トランザクション時間データモデル
姓 名 IN OUT
鈴木 花子 2017/3/1 2017/6/6
斉藤 花子 2017/6/6 9999/12/1
 6月6日に結婚し、姓が「斎藤」に変更。同日システム
上に間違えて「斉藤」と登録
...
57
トランザクション時間データモデル
姓 名 IN OUT
鈴木 花子 2017/3/1 2017/6/6
斉藤 花子 2017/6/6 2017/6/8
斎藤 花子 2017/6/8 9999/12/1
 6月8日にシステム上で修正(斉藤...
58
トランザクション時間データモデル
姓 名 IN OUT
鈴木 花子 2017/3/1 2017/6/6
斉藤 花子 2017/6/6 2017/6/8
斎藤 花子 2017/6/8 2017/12/1
 12月1日、退職にともない同日に...
59
トランザクション時間データモデル hashtag: #ccc_g3
Timestamp mar5 = Timestamp.valueOf(LocalDateTime.of(2017, 3, 5, 0, 0));
Operation op ...
60
トランザクション時間データモデル hashtag: #ccc_g3
Timestamp jun7 = Timestamp.valueOf(LocalDateTime.of(2017, 6, 7, 0, 0));
Operation op ...
61
トランザクション時間データモデル hashtag: #ccc_g3
Timestamp jun8 = Timestamp.valueOf(LocalDateTime.of(2017, 6, 8, 0, 0));
Operation op ...
62
トランザクション時間データモデル
Reladomoのトランザクション時間データ操作
 IN/OUTカラムにまつわる処理はユーザーが気にするこ
となくフレームワークが吸収してくれる
 デフォルトで最新のデータが検索される(OUT =
I...
63
Reladomoでバイテンポラルデータ
モデルを扱う例
hashtag: #ccc_g3
64
<MithraObject objectType=“transactional”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:noNamespaceSchemaLoc...
65
バイテンポラルデータモデル
姓 名 FROM THRU IN OUT
鈴木 花子 2017/4/1 9999/12/1 2017/3/1 9999/12/1
 4月1日に「鈴木花子」さん入社。3月1日にシステムに登録
hashtag: ...
66
バイテンポラルデータモデル
 6月6日に結婚し、姓が「斎藤」に変更。同日システム
上に間違えて「斉藤」と登録
hashtag: #ccc_g3
//まずは6月6日付(有効時間)でフェッチ
Timestamp jun6 = Timesta...
67
バイテンポラルデータモデル
 名字の漢字が間違っており、6月8日にシステム上で修正
(斉藤=>斎藤)
hashtag: #ccc_g3
//まずは6月6日付(有効時間)でフェッチ
Timestamp jun6 = Timestamp.v...
68
バイテンポラルデータモデル
 12月1日、退職にともない同日に人事情報をシステム上
で無効化
hashtag: #ccc_g3
//まずは12月1日付(有効時間)でフェッチ
Timestamp dec1 = Timestamp.valu...
69
バイテンポラルデータモデル
Reladomoのバイテンポラルデータ操作
 オブジェクト作成の際は有効時間の開始時を引数に与
える
 更新の際は、まず更新したい日付(有効時間)で
フェッチする。フェッチしたオブジェクトを更新する
と自動...
70
Reladomoを用いたテンポラルデータモデルの操作
ここで挙げた例はReladomoの機能のさわりのみ
つづきはReladomo Kata / Reladomo Tourで
 Reladomo Kata GitHub (Reladom...
71
まとめ
 RDBで履歴を扱う際にはテンポラルデータモデルを用
いると素直に表現できる
 トランザクション時間と有効時間を組み合わせたテン
ポラルデータモデルが存在
 Reladomoを使うとテンポラルデータモデルの扱いが
抽象化でき...
72
株式会社FOLIOの紹介 hashtag: #ccc_g3
https://www.wantedly.com/companies/folio/projectsエンジニア募集中!
73
APPENDIX
74
テンポラルデータモデル hashtag: #ccc_g3
 Temporal Data Models(ppt)
 Temporal Databases - Richard T. Snodgrass 1998
 Temporal Da...
75
Reladomo hashtag: #ccc_g3
 Reladomo GitHub
 Reladomo Kata GitHub (Reladomo チュートリアル)
 Guided Tour of Reladomo
 Relad...
Upcoming SlideShare
Loading in …5
×

データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3

41,715 views

Published on

データ履歴管理のためのテンポラルデータモデルとReladomoの紹介

Published in: Engineering
  • Be the first to comment

データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3

  1. 1. データ履歴管理のための テンポラルデータモデルと Reladomoの紹介 株式会社FOLIO 伊藤博志 JJUG CCC 2017 Spring 2017.5.20 #ccc_g3 Reladomo is an open source software Licensed under Apache 2.0 License, Copyright 2016 Goldman Sachs, Its name may be a trademark of its owner.
  2. 2. 1 株式会社FOLIOの紹介 hashtag: #ccc_g3 https://www.wantedly.com/companies/folio/projectsエンジニア募集中!
  3. 3. 2 Agenda 1. 自己紹介 2. RDBMSで履歴データを扱う  スナップショットデータモデル  トランザクション時間データモデル  有効時間データモデル  バイテンポラルデータモデル 3. Javaからバイテンポラルモデルを容易に扱うReladomoの紹介 hashtag: #ccc_g3
  4. 4. 3 自己紹介 趣味:ドラム演奏 JavaOneコミュニティバンド Null Pointersで演奏経験あり(日本人初) Tech Lead @ FOLIO 伊藤 博志 Eclipse Collections:共同プロジェクトリード兼コミッター Reladomo:コントリビューター OpenJDK:コントリビューター JJUG CCC、Java Day Tokyo、JavaOne San Francisco登壇 2017年5月17日に株式会社FOLIO入社。 hashtag: #ccc_g3
  5. 5. 4 RDBMSで変更履歴をどう扱うか hashtag: #ccc_g3
  6. 6. 5 RDBMSで履歴データを扱う 単純なシナリオを考えてみましょう シンプルな人事システム。扱う情報は姓名のみ。  4月1日に「鈴木花子」さん入社。3月1日にシステムに登録  6月6日に結婚し、姓が「斎藤」に変更。同日システム上に 間違えて「斉藤」と登録  6月8日にシステム上で修正(斉藤=>斎藤) 。事実としては 6月6日づけで直したい  12月1日、退職にともない同日にシステム上で情報を無効化 hashtag: #ccc_g3
  7. 7. 6 RDBMSで履歴データを扱う  シナリオをよく観察すると、2種類の履歴が存在 hashtag: #ccc_g3 3/1 4/1 6/6 6/8 12/1 鈴木花子 事実情報の 履歴 システムに 反映された 履歴 入社🎉 「鈴木花子」を システムに登録 結婚して 斎藤になる👰 名字を 「斉藤」に変更 名字を 「斎藤」に変更 退職† データを無効化
  8. 8. 7 RDBMSで履歴データを扱う 最新の情報さえ 分かれば良い いつシステムに 反映されたか履 歴が知りたい 2種類の履歴から考えうる4種類の要件 事実情報の履歴 が知りたい 事実情報と、い つシステムに反 映されたか両方 の履歴が知りた い hashtag: #ccc_g3
  9. 9. 8 RDBMSで履歴データを扱う スナップショットデータモデル トランザクション時間データモデル 有効時間データモデル バイテンポラルデータモデル 各要件を満たすために、4つのデータモデルが考えられる hashtag: #ccc_g3
  10. 10. 9 スナップショットデータモデル hashtag: #ccc_g3 最新の情報さえ 分かれば良い
  11. 11. 10 スナップショットデータモデル  スナップショットデータモデルで表現できるのは、最新 の情報のみ(履歴は表現できない) hashtag: #ccc_g3 3/1 4/1 6/6 6/8 12/1 鈴木花子 事実情報の 履歴 システムに 反映された 履歴 入社🎉 「鈴木花子」を システムに登録 結婚して 斎藤になる👰 名字を 「斉藤」に変更 名字を 「斎藤」に変更 退職† データを無効化
  12. 12. 11 スナップショットデータモデル 姓 名 inserted_at updated_at 鈴木 花子 2017/3/1 2017/3/1  4月1日に「鈴木花子」さん入社。3月1日にシステムに登録 鈴木さん入社! 入社日というカラムが あってもいいような気がする hashtag: #ccc_g3
  13. 13. 12 スナップショットデータモデル  6月6日に結婚し、姓が「斎藤」に変更。同日システム 上に間違えて「斉藤」と登録 間違えて「斉藤」と入 力してしまいました 姓 名 inserted_at updated_at 斉藤 花子 2017/3/1 2017/6/6 hashtag: #ccc_g3
  14. 14. 13 スナップショットデータモデル  6月8日にシステム上で修正(斉藤=>斎藤) 正しい姓は「斎藤」さ んですね。。。 姓 名 inserted_at updated_at 斎藤 花子 2017/3/1 2017/6/8 hashtag: #ccc_g3
  15. 15. 14 スナップショットデータモデル  12月1日、退職にともない同日に人事情報をシステム上 で無効化 _人人人人人人人人人人人_ > 物理削除 <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄ 物理削除がイヤ なら禁断の論理 削除フラグとい う手もあるよ。 フフッ 姓 名 inserted_at updated_at hashtag: #ccc_g3
  16. 16. 15 スナップショットデータモデル  スナップショットデータモデルで履歴を実装しようと すると、バージョンカラムや履歴テーブルを別に用意 するなど、力技が求められる  世に存在する履歴系のデータは、この力技で実装され ていることが多い(印象)  さらにスナップショットデータモデルでは、データを 無効化するのに「論理削除」か「物理削除」か、と悩 むケースも hashtag: #ccc_g3
  17. 17. 16 トランザクション時間データモデル hashtag: #ccc_g3 いつシステムに 反映されたか履 歴が知りたい
  18. 18. 17 トランザクション時間データモデル  トランザクション時間データモデルで表現できるのは、 「システムに反映された」履歴 hashtag: #ccc_g3 3/1 4/1 6/6 6/8 12/1 鈴木花子 事実情報の 履歴 システムに 反映された 履歴 入社🎉 「鈴木花子」を システムに登録 結婚して 斎藤になる👰 名字を 「斉藤」に変更 名字を 「斎藤」に変更 退職† データを無効化
  19. 19. 18 トランザクション時間データモデル 姓 名 IN OUT 鈴木 花子 2017/3/1 9999/12/1 鈴木さん入社! INはデータベースに挿入された日付、 OUTはその行が無効になった(なる)日付、 OUTはデフォルトでINFINITY(この場合9999年)とするよ やっぱり入社日カラムが欲しくなる。。  4月1日に「鈴木花子」さん入社。3月1日にシステムに登録 hashtag: #ccc_g3
  20. 20. 19 トランザクション時間データモデル 姓 名 IN OUT 鈴木 花子 2017/3/1 2017/6/6 斉藤 花子 2017/6/6 9999/12/1 鈴木さん姓が2017/6/6に無効(OUT) になり、斉藤さん姓が同日入力(IN) されたということだね  6月6日に結婚し、姓が「斎藤」に変更。同日システム 上に間違えて「斉藤」と登録 hashtag: #ccc_g3
  21. 21. 20 トランザクション時間データモデル 姓 名 IN OUT 鈴木 花子 2017/3/1 2017/6/6 斉藤 花子 2017/6/6 2017/6/8 斎藤 花子 2017/6/8 9999/12/1 斉藤さん姓が2017/6/8に無効(OUT) になり、斎藤さん姓が同日入力(IN) されたということだね  6月8日にシステム上で修正(斉藤=>斎藤) 。事実として は6月6日づけで直したい 「斎藤」姓がシステム上有効なのは6/8 からか。。 hashtag: #ccc_g3
  22. 22. 21 トランザクション時間データモデル 姓 名 IN OUT 鈴木 花子 2017/3/1 2017/6/6 斉藤 花子 2017/6/6 2017/6/8 斎藤 花子 2017/6/8 2017/12/1 2017/12/1日付で無効化(OUT)!  12月1日、退職にともない同日に人事情報をシステム上 で無効化 hashtag: #ccc_g3
  23. 23. 22 トランザクション時間データモデル 履歴データをどう検索するのか? hashtag: #ccc_g3
  24. 24. 23 トランザクション時間データモデル  任意の時間Xにデータベース上で最新だった情報を とってくる select * from EMPLOYEE where IN < X and OUT >= X hashtag: #ccc_g3
  25. 25. 24 トランザクション時間データモデル 姓 名 IN OUT 鈴木 花子 2017/3/1 2017/6/6  3月15日時点でデータベース上で最新だった情報を とってくる select * from EMPLOYEE where IN < “2017/3/15” and OUT >= “2017/3/15” 姓 名 IN OUT 鈴木 花子 2017/3/1 2017/6/6 斉藤 花子 2017/6/6 2017/6/8 斎藤 花子 2017/6/8 2017/12/1 hashtag: #ccc_g3
  26. 26. 25 トランザクション時間データモデル 姓 名 IN OUT 斉藤 花子 2017/6/6 2017/6/8 select * from EMPLOYEE where IN < “2017/6/7” and OUT >= “2017/6/7” 姓 名 IN OUT 鈴木 花子 2017/3/1 2017/6/6 斉藤 花子 2017/6/6 2017/6/8 斎藤 花子 2017/6/8 2017/12/1  6月7日時点でデータベース上で最新だった情報を とってくる hashtag: #ccc_g3
  27. 27. 26 トランザクション時間データモデル 姓 名 IN OUT 斎藤 花子 2017/6/8 2017/12/1 姓 名 IN OUT 鈴木 花子 2017/3/1 2017/6/6 斉藤 花子 2017/6/6 2017/6/8 斎藤 花子 2017/6/8 2017/12/1  6月9日時点でデータベース上で最新だった情報を とってくる select * from EMPLOYEE where IN < “2017/6/9" and OUT >= “2017/6/9” hashtag: #ccc_g3
  28. 28. 27 トランザクション時間データモデル 姓 名 IN OUT select * from EMPLOYEE where IN < “2017/12/5" and OUT >= “2017/12/5” 姓 名 IN OUT 鈴木 花子 2017/3/1 2017/6/6 斉藤 花子 2017/6/6 2017/6/8 斎藤 花子 2017/6/8 2017/12/1 2017/12/1以降に有効な行が存在しな いので、論理削除フラグを使わなく てもシステム上で無効化されてい る!  12月5日時点でデータベース上で最新だった情報を とってくる hashtag: #ccc_g3
  29. 29. 28 トランザクション時間データモデル  ある時点でデータベース上で最新だった情報を一意に 取得することができる  過去の履歴を一気に取得することもでき、時間軸で ソートも可  最新の行を無効化するにはOUTコラムを更新するだけ でOK(物理削除も論理削除フラグも不要)  監査情報を自然な形でモデリングできる トランザクション時間データモデルの適用例  ドキュメントの履歴管理  状態遷移の履歴管理  etc. hashtag: #ccc_g3
  30. 30. 29 有効時間データモデル hashtag: #ccc_g3 事実情報の履歴 がほしい
  31. 31. 30 有効時間データモデル  有効時間データモデルで表現できるのは、「事実情報」 の履歴 hashtag: #ccc_g3 3/1 4/1 6/6 6/8 12/1 鈴木花子 事実情報の 履歴 システムに 反映された 履歴 入社🎉 「鈴木花子」を システムに登録 結婚して 斎藤になる👰 名字を 「斉藤」に変更 名字を 「斎藤」に変更 退職† データを無効化
  32. 32. 31 有効時間データモデル 姓 名 FROM THRU 鈴木 花子 2017/4/1 9999/12/1  4月1日に「鈴木花子」さん入社。3月1日にシステムに登録 鈴木さん入社! FROMは当該データが事実として有効である最初の日、 THRUは当該データが事実として有効である最終日の翌日*、 THRUはデフォルトでINFINITY(この場合9999年)とするよ これで入社日がわかる。。 *ここではTHRUを最終日翌日としていますが、FROMを最初の日の前日とする方法もあります hashtag: #ccc_g3 *Throughの略
  33. 33. 32 有効時間データモデル 姓 名 FROM THRU 鈴木 花子 2017/4/1 2017/6/6 斉藤 花子 2017/6/6 9999/12/1  6月6日に結婚し、姓が「斎藤」に変更。同日システム 上に間違えて「斉藤」と登録 事実として「鈴木」姓の最終日が2017/6/5 (THRU-1)になり、2017/6/6(FROM)から 間違った「斉藤」姓が有効に hashtag: #ccc_g3
  34. 34. 33 有効時間データモデル 姓 名 FROM THRU 鈴木 花子 2017/4/1 2017/6/6 斎藤 花子 2017/6/6 9999/12/1 2017/6/6(FROM)から正しい「斎藤」さん 姓になった。間違えた「斉藤」姓は上書きさ れたので、システム上の履歴はわからないね。  6月8日にシステム上で修正(斉藤=>斎藤) 。事実として は6月6日づけで直したい hashtag: #ccc_g3
  35. 35. 34 有効時間データモデル 姓 名 FROM THRU 鈴木 花子 2017/4/1 2017/6/6 斎藤 花子 2017/6/6 2017/12/1  12月1日、退職にともない同日に人事情報をシステム上 で無効化 これで 鈴木さんが2017/4/1に入社、 2017/6/6に斎藤姓に代わり、 2017/12/1に退社した、 という事実情報がすべて表現されるね! hashtag: #ccc_g3
  36. 36. 35 有効時間データモデル 検索方法はトランザクション時間 データモデルの場合と同様なので省略 hashtag: #ccc_g3
  37. 37. 36 有効時間データモデル  ある時点での「事実情報」を一意に取得することがで きる  過去の事実の履歴を一気に取得することもでき、時間 軸でソートも可  最新の行を無効化するにはTHRUコラムを更新するだ けでOK(物理削除も論理削除フラグも不要)  事実の履歴を自然な形でモデリングできる 有効時間データモデルの適用例  変更履歴を気にしないビジネスデータ  etc. hashtag: #ccc_g3
  38. 38. 37 バイテンポラルデータモデル hashtag: #ccc_g3 事実情報と、い つシステムに反 映されたか両方 の履歴が知りた い
  39. 39. 38 バイテンポラルデータモデル  バイテンポラルデータモデルで表現できるのは、「シス テムに反映された」履歴と「事実情報」の履歴両方 hashtag: #ccc_g3 3/1 4/1 6/6 6/8 12/1 鈴木花子 事実情報の 履歴 システムに 反映された 履歴 入社🎉 「鈴木花子」を システムに登録 結婚して 斎藤になる👰 名字を 「斉藤」に変更 名字を 「斎藤」に変更 退職† データを無効化
  40. 40. 39 バイテンポラルデータモデル 姓 名 FROM THRU IN OUT 鈴木 花子 2017/4/1 9999/12/1 2017/3/1 9999/12/1  4月1日に「鈴木花子」さん入社。3月1日にシステムに登録 鈴木さん入社! 4月1日に入社したことも わかるし、3月1日にシス テムに反映されたこともわ かる! hashtag: #ccc_g3
  41. 41. 40 バイテンポラルデータモデル 姓 名 FROM THRU IN OUT 鈴木 花子 2017/4/1 9999/12/1 2017/3/1 2017/6/6 鈴木 花子 2017/4/1 2017/6/6 2017/6/6 9999/12/1 斉藤 花子 2017/6/6 9999/12/1 2017/6/6 9999/12/1  6月6日に結婚し、姓が「斎藤」に変更。同日システム 上に間違えて「斉藤」と登録 最初の行が「システム上」無効になり、新し い「事実」が2つの期間にわたって挿入されて いるね。 hashtag: #ccc_g3
  42. 42. 41 バイテンポラルデータモデル 姓 名 FROM THRU IN OUT 鈴木 花子 2017/4/1 9999/12/1 2017/3/1 2017/6/6 鈴木 花子 2017/4/1 2017/6/6 2017/6/6 9999/12/1 斉藤 花子 2017/6/6 9999/12/1 2017/6/6 2017/6/8 斎藤 花子 2017/6/6 9999/12/1 2017/6/8 9999/12/1  名字の漢字が間違っており、6月8日にシステム上で修正 (斉藤=>斎藤) 間違えた行が「システム上」無効になり、正しい 「事実」が挿入されているね。 3つ目の行は「斉藤」という間違った事実が 「システム上有効だった」期間が6/6から6/8の 間存在するという情報を表しているよ。 hashtag: #ccc_g3
  43. 43. 42 バイテンポラルデータモデル 姓 名 FROM THRU IN OUT 鈴木 花子 2017/4/1 9999/12/1 2017/3/1 2017/6/6 鈴木 花子 2017/4/1 2017/6/6 2017/6/6 9999/12/1 斉藤 花子 2017/6/6 9999/12/1 2017/6/6 2017/6/8 斎藤 花子 2017/6/6 9999/12/1 2017/6/8 2017/12/1 斎藤 花子 2017/6/6 2017/12/1 2017/12/1 9999/12/1  12月1日、退職にともない同日に人事情報をシステム上 で無効化 無事、事実情報(入社、姓変更、退社)と変 更履歴がすべて記録されました! hashtag: #ccc_g3
  44. 44. 43 バイテンポラルデータモデル  バイテンポラルデータモデルは「システム履歴」と 「事実情報の履歴」を同時に正しく表現することがで きる非常に強力なモデル バイテンポラルデータモデルの適用例  監査履歴が重要な金融システムの基幹データ  その他、時系列に紐づくビジネスデータで変更履歴が 重要なユースケース  etc. hashtag: #ccc_g3
  45. 45. 44 どう実装する? バイテンポラルデータモデル の雰囲気はわかった でも、ぱっと見複雑そう。 結局、実装するのが大変 なのでは。。。? 安心してください Reladomoを使えば簡単です! hashtag: #ccc_g3
  46. 46. 45 Javaからバイテンポラルモデルを 容易に扱えるReladomoの紹介 hashtag: #ccc_g3
  47. 47. 46 Reladomoとは https://github.com/goldmansachs/reladomo  ゴールドマン・サックス社が2016年10月にGitHubに OSSとして公開したJava ORMフレームワーク  Apache License 2.0  バイテンポラルデータモデルをネイティブサポート  強力に型付けられたクエリー言語  シャーディングのネイティブサポート  ユニットテストのフルサポート  etc. hashtag: #ccc_g3
  48. 48. 47 Reladomoとは Reladomoのコード生成  xmlによるエンティティ定義を用いてコード生成  同xmlからddlの生成も可能  Abstract Classはxmlに変更のある都度生成される  Concrete Classは初回のみ生成しVCSにコミット、ビ ジネスロジックを記述。コード生成で上書きされない。 hashtag: #ccc_g3
  49. 49. 48 Employeeエンティティ定義ファイル hashtag: #ccc_g3 <MithraObject objectType="transactional" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="reladomoobject.xsd"> <PackageName>sample.domain</PackageName> <ClassName>Employee</ClassName> <DefaultTable>EMPLOYEE</DefaultTable> <Attribute name="employeeId" javaType="int" columnName="EMPLOYEE_ID" primaryKey="true" primaryKeyGeneratorStrategy="SimulatedSequence"> <SimulatedSequence sequenceName="Employee" sequenceObjectFactoryName="sample.util.ObjectSequenceObjectFactory" hasSourceAttribute="false" batchSize="1" initialValue="1" incrementSize="1"/> </Attribute> <Attribute name="firstName" javaType="String" columnName="FIRST_NAME" nullable="false" maxLength="64"/> <Attribute name="lastName" javaType="String" columnName="LAST_NAME" nullable="false" maxLength="64"/> </MithraObject>
  50. 50. 49 Employeeエンティティ hashtag: #ccc_g3 トランザクション時間 生成されたAbstract Class
  51. 51. 50 Employeeエンティティ hashtag: #ccc_g3 Concrete Class (初回のみ生成) さまざまなビジネスロジックを記述できる
  52. 52. 51 DBトランザクション hashtag: #ccc_g3 テンポラルオブジェクトの挿入、更新はトランザクション内で のみ可能 (以降のコード例では省略している場合も) Employee hanako = MithraManagerProvider.getMithraManager().executeTransactionalCommand(tx -> { Employee hanakoNew = new Employee(); hanakoNew.setLastName(“鈴木”); hanakoNew.setFirstName(“花子”); hanakoNew.insert(); return hanakoNew; //トランザクション終了後に使用したいオブジェクトを返り値とし て与えることができる。 });
  53. 53. 52 ReladomoのFinder DSL  型付けられた強力なクエリー言語  自動生成されたフィールドを用いてOperationを構築 hashtag: #ccc_g3 Operation op = EmployeeFinder.lastName().eq("鈴木") .and(EmployeeFinder.firstName().eq("花子")); final Employee hanako = EmployeeFinder.findOne(op);
  54. 54. 53 Reladomoでトランザクション時間 を扱う例 hashtag: #ccc_g3
  55. 55. 54 Employeeエンティティ定義ファイル hashtag: #ccc_g3 <MithraObject objectType="transactional" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="reladomoobject.xsd"> <PackageName>sample.domain</PackageName> <ClassName>Employee</ClassName> <DefaultTable>EMPLOYEE</DefaultTable> <AsOfAttribute name="processingDate" fromColumnName="IN_Z" toColumnName="OUT_Z" toIsInclusive="false" isProcessingDate="true" infinityDate="[com.gs.fw.common.mithra.util.DefaultInfinityTimestamp.getDefaultInfinity()]" defaultIfNotSpecified="[com.gs.fw.common.mithra.util.DefaultInfinityTimestamp.getDefaultInfinity()]" /> <Attribute name="employeeId" javaType="int" columnName="EMPLOYEE_ID" primaryKey="true" primaryKeyGeneratorStrategy="SimulatedSequence"> <SimulatedSequence sequenceName="Employee" sequenceObjectFactoryName="sample.util.ObjectSequenceObjectFactory" hasSourceAttribute="false" batchSize="1" initialValue="1" incrementSize="1"/> </Attribute> <Attribute name="firstName" javaType="String" columnName="FIRST_NAME" nullable="false" maxLength="64"/> <Attribute name="lastName" javaType="String" columnName="LAST_NAME" nullable="false" maxLength="64"/> </MithraObject> トランザクション時間
  56. 56. 55 トランザクション時間データモデル 姓 名 IN OUT 鈴木 花子 2017/3/1 9999/12/1 hashtag: #ccc_g3 //3月1日にこのコードが実行される Employee hanakoNew = new Employee(); //メモリ上にオブジェクト作成 hanakoNew.setLastName("鈴木"); hanakoNew.setFirstName("花子"); hanakoNew.insert(); // データベースに挿入  4月1日に「鈴木花子」さん入社。3月1日にシステムに登録
  57. 57. 56 トランザクション時間データモデル 姓 名 IN OUT 鈴木 花子 2017/3/1 2017/6/6 斉藤 花子 2017/6/6 9999/12/1  6月6日に結婚し、姓が「斎藤」に変更。同日システム 上に間違えて「斉藤」と登録 hashtag: #ccc_g3 //6月6日にこのコードが実行される hanako.setLastName("斉藤"); // アップデート
  58. 58. 57 トランザクション時間データモデル 姓 名 IN OUT 鈴木 花子 2017/3/1 2017/6/6 斉藤 花子 2017/6/6 2017/6/8 斎藤 花子 2017/6/8 9999/12/1  6月8日にシステム上で修正(斉藤=>斎藤) 。事実として は6月6日づけで直したい hashtag: #ccc_g3 //6月8日にこのコードが実行される hanako.setLastName(“斎藤"); // アップデート
  59. 59. 58 トランザクション時間データモデル 姓 名 IN OUT 鈴木 花子 2017/3/1 2017/6/6 斉藤 花子 2017/6/6 2017/6/8 斎藤 花子 2017/6/8 2017/12/1  12月1日、退職にともない同日に人事情報をシステム上 で無効化 hashtag: #ccc_g3 //12月1日にこのコードが実行される hanako.terminate(); // OUT = NOW
  60. 60. 59 トランザクション時間データモデル hashtag: #ccc_g3 Timestamp mar5 = Timestamp.valueOf(LocalDateTime.of(2017, 3, 5, 0, 0)); Operation op = EmployeeFinder.firstName().eq("花子") .and(EmployeeFinder.processingDate().eq(mar5)); Employee hanakoMar5 = EmployeeFinder.findOne(op); logger.info("Mar 5: " + hanakoMar5.getFullName());  3月5日時点の花子さんを検索 [main] INFO sample.HelloReladomoApp - Mar 5: 鈴木 花子 select t0.EMPLOYEE_ID,t0.FIRST_NAME,t0.LAST_NAME,t0.IN,t0.OUT from EMPLOYEE t0 where t0.FIRST_NAME = '花子' and t0.IN <= '2017-03-05 00:00:00.000' and t0.OUT > '2017-03-05 00:00:00.000'
  61. 61. 60 トランザクション時間データモデル hashtag: #ccc_g3 Timestamp jun7 = Timestamp.valueOf(LocalDateTime.of(2017, 6, 7, 0, 0)); Operation op = EmployeeFinder.firstName().eq("花子") .and(EmployeeFinder.processingDate().eq(jun7)); Employee hanakoJum7 = EmployeeFinder.findOne(op); logger.info(”Jun 7: " + hanakoJun7.getFullName());  6月7日時点の花子さんを検索 [main] INFO sample.HelloReladomoApp - June 7: 斉藤 花子 select t0.EMPLOYEE_ID,t0.FIRST_NAME,t0.LAST_NAME,t0.IN,t0.OUT from EMPLOYEE t0 where t0.FIRST_NAME = '花子' and t0.IN <= '2017-06-07 00:00:00.000' and t0.OUT > '2017-06-07 00:00:00.000'
  62. 62. 61 トランザクション時間データモデル hashtag: #ccc_g3 Timestamp jun8 = Timestamp.valueOf(LocalDateTime.of(2017, 6, 8, 0, 0)); Operation op = EmployeeFinder.firstName().eq("花子") .and(EmployeeFinder.processingDate().eq(jun8)); Employee hanakoJum8 = EmployeeFinder.findOne(op); logger.info(”Jun 8: " + hanakoJun8.getFullName());  6月8日時点の花子さんを検索 [main] INFO sample.HelloReladomoApp - June 8: 斎藤 花子 select t0.EMPLOYEE_ID,t0.FIRST_NAME,t0.LAST_NAME,t0.IN,t0.OUT from EMPLOYEE t0 where t0.FIRST_NAME = '花子' and t0.IN <= '2017-06-08 00:00:00.000' and t0.OUT > '2017-06-08 00:00:00.000'
  63. 63. 62 トランザクション時間データモデル Reladomoのトランザクション時間データ操作  IN/OUTカラムにまつわる処理はユーザーが気にするこ となくフレームワークが吸収してくれる  デフォルトで最新のデータが検索される(OUT = INFINITY)  データをある日付(トランザクション時間)から無効 化するにはterminate()を使う  過去の履歴の検索の際はprocessingDate()を明示的に 指定してやる hashtag: #ccc_g3
  64. 64. 63 Reladomoでバイテンポラルデータ モデルを扱う例 hashtag: #ccc_g3
  65. 65. 64 <MithraObject objectType=“transactional” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=“reladomoobject.xsd”> <PackageName>sample.domain</PackageName> <ClassName>Employee</ClassName> <DefaultTable>EMPLOYEE</DefaultTable> <AsOfAttribute name=“processingDate” fromColumnName=“IN_Z” toColumnName=“OUT_Z” toIsInclusive=“false” isProcessingDate=“true” timezoneConversion=“none” infinityDate=“[com.gs.fw.common.mithra.util.DefaultInfinityTimestamp.getDefaultInfinity()]” defaultIfNotSpecified=“[com.gs.fw.common.mithra.util.DefaultInfinityTimestamp.getDefaultInfinity()]” /> <AsOfAttribute name=“businessDate” fromColumnName=“FROM_Z” toColumnName=“THRU_Z” toIsInclusive=“false” isProcessingDate=“false” timezoneConversion=“none” infinityDate=“[com.gs.fw.common.mithra.util.DefaultInfinityTimestamp.getDefaultInfinity()]” futureExpiringRowsExist=“true” /> ・・・省略・・・ </MithraObject> Employeeエンティティ定義ファイル hashtag: #ccc_g3 有効時間
  66. 66. 65 バイテンポラルデータモデル 姓 名 FROM THRU IN OUT 鈴木 花子 2017/4/1 9999/12/1 2017/3/1 9999/12/1  4月1日に「鈴木花子」さん入社。3月1日にシステムに登録 hashtag: #ccc_g3 Timestamp apr1 = Timestamp.valueOf(LocalDateTime.of(2017, 4, 1, 0, 0)); Employee hanakoNew = new Employee(apr1); //メモリ上にオブジェクト作成 hanakoNew.setLastName("鈴木"); hanakoNew.setFirstName("花子"); hanakoNew.insert(); // データベースに挿入
  67. 67. 66 バイテンポラルデータモデル  6月6日に結婚し、姓が「斎藤」に変更。同日システム 上に間違えて「斉藤」と登録 hashtag: #ccc_g3 //まずは6月6日付(有効時間)でフェッチ Timestamp jun6 = Timestamp.valueOf(LocalDateTime.of(2017, 6, 6, 0, 0)); Operation opJun6 = EmployeeFinder.firstName().eq(“花子”). and(EmployeeFinder.businessDate().eq(jun6)); //6月6日付でフェッチ final Employee hanakoJun6 = EmployeeFinder.findOne(opJun6); //遅延ロードされるのでこの時点ではまだフ ェッチされていない //6月6日付(有効時間)でフェッチしたオブジェクトをアップデート MithraManagerProvider.getMithraManager().executeTransactionalCommand(tx -> { //6月6日(トランザクション時間)にこのコードが実行される hanakoJun6.setLastName("斉藤"); // この時点で遅延フェッチ&アップデート return null; }); *スペースの都合上、以降テーブルは省略
  68. 68. 67 バイテンポラルデータモデル  名字の漢字が間違っており、6月8日にシステム上で修正 (斉藤=>斎藤) hashtag: #ccc_g3 //まずは6月6日付(有効時間)でフェッチ Timestamp jun6 = Timestamp.valueOf(LocalDateTime.of(2017, 6, 6, 0, 0)); Operation opJun6 = EmployeeFinder.firstName().eq(“花子”). and(EmployeeFinder.businessDate().eq(jun6)); //6月6日付でフェッチ final Employee hanakoJun6 = EmployeeFinder.findOne(opJun6); //遅延ロードされるのでこの時点ではまだフ ェッチされていない //6月6日付(有効時間)でフェッチしたオブジェクトをアップデート MithraManagerProvider.getMithraManager().executeTransactionalCommand(tx -> { //6月8日(トランザクション時間)にこのコードが実行される hanakoJun6.setLastName(“斎藤"); // この時点で遅延フェッチ&アップデート return null; });
  69. 69. 68 バイテンポラルデータモデル  12月1日、退職にともない同日に人事情報をシステム上 で無効化 hashtag: #ccc_g3 //まずは12月1日付(有効時間)でフェッチ Timestamp dec1 = Timestamp.valueOf(LocalDateTime.of(2017, 12, 1, 0, 0)); Operation opDec1 = EmployeeFinder.firstName().eq(“花子”). and(EmployeeFinder.businessDate().eq(dec1)); //12月1日付でフェッチ final Employee hanakoDec1 = EmployeeFinder.findOne(opDec1); //遅延ロードされ るのでこの時点ではフェッチされない //12月1日付(有効時間)でフェッチしたオブジェクトをアップデート MithraManagerProvider.getMithraManager().executeTransactionalCommand(tx -> { //12月1日(トランザクション時間)にこのコードが実行される hanakoDec1.terminate(); // THRU = 12/1 return null; });
  70. 70. 69 バイテンポラルデータモデル Reladomoのバイテンポラルデータ操作  オブジェクト作成の際は有効時間の開始時を引数に与 える  更新の際は、まず更新したい日付(有効時間)で フェッチする。フェッチしたオブジェクトを更新する と自動でIN/OUT/FROM/THRUが更新・挿入される  データをある日付(有効時間)から無効化するには terminate()を使う  バイテンポラルデータモデルのテーブル構造を意識す ることなく処理を記述することが可能 hashtag: #ccc_g3
  71. 71. 70 Reladomoを用いたテンポラルデータモデルの操作 ここで挙げた例はReladomoの機能のさわりのみ つづきはReladomo Kata / Reladomo Tourで  Reladomo Kata GitHub (Reladomo チュートリアル)  Guided Tour of Reladomo hashtag: #ccc_g3
  72. 72. 71 まとめ  RDBで履歴を扱う際にはテンポラルデータモデルを用 いると素直に表現できる  トランザクション時間と有効時間を組み合わせたテン ポラルデータモデルが存在  Reladomoを使うとテンポラルデータモデルの扱いが 抽象化できる ぜひ、みなさんも試してみてください! hashtag: #ccc_g3
  73. 73. 72 株式会社FOLIOの紹介 hashtag: #ccc_g3 https://www.wantedly.com/companies/folio/projectsエンジニア募集中!
  74. 74. 73 APPENDIX
  75. 75. 74 テンポラルデータモデル hashtag: #ccc_g3  Temporal Data Models(ppt)  Temporal Databases - Richard T. Snodgrass 1998  Temporal Databases - Richard T. Snodgrass and Ilsoo Ahn 1986  Temporal and Real-Time Databases: A Survey(ppt)  Temporal Data and The Relational Model
  76. 76. 75 Reladomo hashtag: #ccc_g3  Reladomo GitHub  Reladomo Kata GitHub (Reladomo チュートリアル)  Guided Tour of Reladomo  Reladomo Documentations

×