Slide 1

Slide 1 text

失敗から学ぶRDBの正しい歩き方 オープンセミナー2018@香川

Slide 2

Slide 2 text

What is it? みなさん失敗したことありますか?

Slide 3

Slide 3 text

What is it? みなさん失敗したことありますか? ↓ 私は沢山あります

Slide 4

Slide 4 text

What is it? あの時、どうすればよかったか…

Slide 5

Slide 5 text

What is it? “愚者は経験に学び、賢者は歴史に学ぶ。” --オットー・ビスマルク

Slide 6

Slide 6 text

What is it? 他人の失敗を知ることで 自分の失敗を未然に防ぐことが出来る

Slide 7

Slide 7 text

本を書きました https://www.amazon.co.jp/exec/obidos/ASIN/4297104083/maple036-22/

Slide 8

Slide 8 text

What is it? RDBMSの失敗例集

Slide 9

Slide 9 text

What is it? 今日はこの本の中から 厳選された内容をお伝えします

Slide 10

Slide 10 text

あじぇんだ 1 自己紹介 2 失われた事実 3 簡単すぎる不整合 4 隠された状態 5 まとめ

Slide 11

Slide 11 text

あじぇんだ 1 自己紹介 2 失われた事実 3 簡単すぎる不整合 4 隠された状態 5 まとめ

Slide 12

Slide 12 text

自己紹介 曽根 壮大(34歳) 株式会社オミカレ 副社長/CTO • 日本PostgreSQLユーザ会 勉強会分科会 座長 • 3人の子供がいます • 技術的にはWeb/LL言語/RDBが好きです そ ね た け と も

Slide 13

Slide 13 text

自己紹介 曽根 壮大(34歳) 株式会社オミカレ 副社長/CTO • 日本PostgreSQLユーザ会 勉強会分科会 座長 • 3人の子供がいます • 技術的にはWeb/LL言語/RDBが好きです そ ね た け と も

Slide 14

Slide 14 text

婚活といえばオミカレ https://party-calendar.net/

Slide 15

Slide 15 text

あじぇんだ 1 自己紹介 2 失われた事実 3 簡単すぎる不整合 4 隠された状態 5 まとめ

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

失われた事実 RDBは、“時間軸と直行するような設計”が大切です。 ですがそれを使ったサービスとしては、 時間軸と直行しないデータ=履歴を保存することが同じくらい 重要です。履歴の保存を怠ると、 • このデータがどのようにして今の値になったかわからない • ある日を境に売上データと商品マスタの単価データが合わない • 払い戻しの処理が特別対応となる このようなケースと戦うことになります -- 失敗から学ぶRDBの正しい歩き方 – 第2章 失われた事実

Slide 18

Slide 18 text

失われた事実 失われた事実の例

Slide 19

Slide 19 text

売上id 売上金額 売上日 配送状態 1 29,522 2014-03-31 23:59:59 配送済み 2 6,480 2014-04-01 00:00:00 発注中 ︙ ︙ ︙ ︙ 名前 値 消費税率 0.05 売上id 商品id 個数 購入者 1 1 3 sone 1 2 3 sone 1 3 3 sone 2 4 3 sone ︙ ︙ ︙ ︙ 商品id 商品名 価格 1 SQL実践入門 2,580 2 リーダブルコード 2,592 3 プログラマのためのSQL 4,200 4 データベースリファクタリング 3,000 日付が変わるタイミングで消費税率 を5%から8%に変えることで対応 消費税率*商品.価格*カート.個数=売上金額 カート 売上 設定マスタ 商品

Slide 20

Slide 20 text

失われた事実 4/3に返品があったら?

Slide 21

Slide 21 text

失われた事実 4/3に返品があったら? ↓ 該当の商品の個数を減らして、 再計算を実施して売上を更新する

Slide 22

Slide 22 text

売上id 売上金額 売上日 配送状態 1 27,579 2014-03-31 23:59:59 配送済み 2 6,480 2014-04-01 00:00:00 発注中 ︙ ︙ ︙ ︙ 名前 値 消費税率 0.08 売上id 商品id 個数 購入者 1 1 2 sone 1 2 3 sone 1 3 3 sone 2 4 3 sone ︙ ︙ ︙ ︙ 商品id 商品名 価格 1 SQL実践入門 2,580 2 リーダブルコード 2,592 3 プログラマのためのSQL 4,200 4 データベースリファクタリング 3,000 商品id=1の個数を3から2へ カート 売上 設定マスタ 商品 再計算

Slide 23

Slide 23 text

失われた事実 サポート担当者 「数日前にsoneさんという方が購入された 『SQL実践入門』、1冊だけ返品処理したら 売上がズレるんですけど。」

Slide 24

Slide 24 text

売上id 売上金額 売上日 配送状態 1 27,579 2014-03-31 23:59:59 配送済み 2 6,480 2014-04-01 00:00:00 発注中 ︙ ︙ ︙ ︙ 名前 値 消費税率 0.08 売上id 商品id 個数 購入者 1 1 2 sone 1 2 3 sone 1 3 3 sone 2 4 3 sone ︙ ︙ ︙ ︙ 商品id 商品名 価格 1 SQL実践入門 2,580 2 リーダブルコード 2,592 3 プログラマのためのSQL 4,200 4 データベースリファクタリング 3,000 カート 売上 設定マスタ 商品 売上id=1の返品処理をする場合、 カートの値のみを変更して再計算 すると、本来有るべき値から誤差 が生まれる

Slide 25

Slide 25 text

失われた事実 • 最初の計算 (2,580 × 3 + 2,592 × 3 + 4,200 × 3) × 1.05 = 29,522円 • 返品で個数が、日付で消費税率が変わる (2,580 × 2 + 2,592 × 3 + 4,200 × 3) × 1.08 = 27,579円 • 本来あるべき計算 (2,580 × 2 + 2,592 × 3 + 4,200 × 3) × 1.05 = 26,813円

Slide 26

Slide 26 text

失われた事実 • 商品名が変わったら? • 商品の価格が変わったら? • 購入日と支払日が違ったら? • 配送状況の過程は? …etc

Slide 27

Slide 27 text

商品id 商品名 価格 1 SQL実践入門 2,580 2 リーダブルコード 2,592 3 プログラマのためのSQL 4,200 過去の事実と不整合が生まれてしまう 商品id 商品名 価格 1 SQL実践入門 第二版 2,480 2 リーダブルコード 2,592 3 プログラマのためのSQL 4,200 過去の事実(値)が失われる

Slide 28

Slide 28 text

過去の事実(過程)が失われる 配送状況の履歴が無いため 下記の区別がつかない 1. 発注済 → キャンセル → 再発注 → 配送済 2. 発注済 → 配送済み

Slide 29

Slide 29 text

失われた事実 過去の事実は非常時に必要になる

Slide 30

Slide 30 text

アンチパターンを防ぐには? 履歴を保存する

Slide 31

Slide 31 text

アンチパターンを防ぐには? 消費税率 有効日 失効日 0.05 1997-04-01 2014-03-31 0.08 2014-04-01 null 消費税率に履歴を持たせる ・消費税率テーブルを新規に作る ・有効期限をもたせることで、 売上日から消費税率を遡ることができる ・自動切り替えにも対応出来る

Slide 32

Slide 32 text

アンチパターンを防ぐには? 購入時の消費税率の履歴を持たせる 売上id 売上金額 消費税率 売上日 配送状態 1 29,522 0.05 2014-03-31 23:59:59 配送済み 2 6,480 0.08 2014-04-01 00:00:00 発注中 ︙ ︙ ︙ ︙ ︙ ・売上テーブルに購入時の消費税率を持たせる ・消費税率テーブルがない場合、 この列が無いと返品処理が出来ない

Slide 33

Slide 33 text

アンチパターンのポイント 履歴の保存はトレードオフ

Slide 34

Slide 34 text

アンチパターンのポイント 履歴の保存はトレードオフ ↓ パフォーマンスが落ちる データの保存とパフォーマンスのトレードオフ

Slide 35

Slide 35 text

アンチパターンのポイント 後からデータを遡りたいときに 事実が失われている設計をしてしまう

Slide 36

Slide 36 text

アンチパターンのポイント 知らない事実を読み解くことは出来ない

Slide 37

Slide 37 text

アンチパターンのポイント 知らない事実を読み解くことは出来ない ↓ 失った事実は取り戻せない

Slide 38

Slide 38 text

アンチパターンのポイント 初期設計から事実の履歴については しっかりと検討すること

Slide 39

Slide 39 text

アンチパターンのポイント その他の対策方法 1. 最新のレコードを有効なレコードとする 2. 更新、削除もINSERTして、集計する (イベントソーシング) 詳しくは書籍で!

Slide 40

Slide 40 text

あじぇんだ 1 自己紹介 2 失われた事実 3 簡単すぎる不整合 4 隠された状態 5 まとめ

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

簡単すぎる不整合 本書では度々データを守る重要性を説いていますが、 逆に最も簡単にデータを壊す方法は非正規化を行うことです。 しかしながら、パフォーマンスの問題などで 非正規化を利用したくなるケースは実際にあります。 非正規化は劇薬であるということを理解したうえで利用する のであればいいのですが、最初から検討するのは間違いです。 -- 失敗から学ぶRDBの正しい歩き方 – 第15章 簡単すぎる不整合

Slide 43

Slide 43 text

簡単すぎる不整合 非正規化したいタイミング

Slide 44

Slide 44 text

簡単すぎる不整合 • テーブルを作って正規化をするのが面倒な時 • 外部キー制約によってデッドロックなどが発生してる時 • 正規化によってJOINのコストが高くなり、 パフォーマンスに問題が出ている時

Slide 45

Slide 45 text

簡単すぎる不整合 • テーブルを作って正規化をするのが面倒な時 • 外部キー制約によってデッドロックなどが発生してる時 • 正規化によってJOINのコストが高くなり、 パフォーマンスに問題が出ている時 ダメ!絶対!! 手間を惜しんで大きな技術的負債を産む

Slide 46

Slide 46 text

簡単すぎる不整合 • テーブルを作って正規化をするのが面倒な時 • 外部キー制約によってデッドロックなどが発生してる時 • 正規化によってJOINのコストが高くなり、 パフォーマンスに問題が出ている時 適切に親テーブルにロックを取れば防げる 外部キー制約を外したり、非正規化するのはアンチパターン

Slide 47

Slide 47 text

簡単すぎる不整合 • テーブルを作って正規化をするのが面倒な時 • 外部キー制約によってデッドロックなどが発生してる時 • 正規化によってJOINのコストが高くなり、 パフォーマンスに問題が出ている時 ケース・バイ・ケースといえる難しい問題 しかし多くの場合、正規化したほうがパフォーマンスは有利

Slide 48

Slide 48 text

非正規化の例 postgres=# SELECT * FROM reserve; id | party_di | 申込者 | 同伴者1 | 同伴者2 | 同伴者3 | 予約日 ----+----------+--------+---------+---------+---------+---------------------------- 1 | 1 | hoge | fuga | | | 2019-01-14 13:54:14.517217 2 | 2 | foo | bar | hoge1 | hoge2 | 2019-01-14 13:54:14.517217 3 | 1 | hoge2 | fuga | | | 2019-01-14 13:54:14.517217 4 | 1 | test | | test | | 2019-01-14 13:54:14.517217 (4 rows) -- 同伴者fugaを検索するクエリ postgres=# SELECT * FROM reserve WHERE ("同伴者1"='fuga' OR "同伴者2"='fuga' OR "同伴者3"='fuga’); id | party_di | 申込者 | 同伴者1 | 同伴者2 | 同伴者3 | 予約日 ----+----------+--------+---------+---------+---------+---------------------------- 1 | 1 | hoge | fuga | | | 2019-01-14 13:54:14.517217 3 | 1 | hoge2 | fuga | | | 2019-01-14 13:54:14.517217 (2 rows)

Slide 49

Slide 49 text

非正規化の例 postgres=# SELECT * FROM reserve; id | party_di | 申込者 | 同伴者1 | 同伴者2 | 同伴者3 | 予約日 ----+----------+--------+---------+---------+---------+---------------------------- 1 | 1 | hoge | fuga | | | 2019-01-14 13:54:14.517217 2 | 2 | foo | bar | hoge1 | hoge2 | 2019-01-14 13:54:14.517217 3 | 1 | hoge2 | fuga | | | 2019-01-14 13:54:14.517217 4 | 1 | test | | test | | 2019-01-14 13:54:14.517217 (4 rows) -- 同伴者fugaを検索するクエリ postgres=# SELECT * FROM reserve WHERE ("同伴者1"='fuga' OR "同伴者2"='fuga' OR "同伴者3"='fuga’); id | party_di | 申込者 | 同伴者1 | 同伴者2 | 同伴者3 | 予約日 ----+----------+--------+---------+---------+---------+---------------------------- 1 | 1 | hoge | fuga | | | 2019-01-14 13:54:14.517217 3 | 1 | hoge2 | fuga | | | 2019-01-14 13:54:14.517217 (2 rows) 更新の場合など、バグなどでデータが壊 れることが容易に想像できる

Slide 50

Slide 50 text

簡単すぎる不整合 データは壊れる

Slide 51

Slide 51 text

簡単すぎる不整合 データは壊れる ↓ 非正規化はそれをより簡単にする

Slide 52

Slide 52 text

アンチパターンを防ぐには? データの不整合と速度のトレードオフ

Slide 53

Slide 53 text

アンチパターンを防ぐには? データの不整合と速度のトレードオフ ↓ 非正規化するくらいなら キャッシュを活用すべき

Slide 54

Slide 54 text

アンチパターンを防ぐには? RDBMSの責務はデータを守ること 速度の課題はアーキテクチャで解決できる

Slide 55

Slide 55 text

アンチパターンを防ぐには? キャッシュの例 1. マテリアライズド・ビュー 2. アプリケーションキャッシュ 3. NoSQLなど高速なデータストアの活用 …etc 書籍では解説しています 今日は時間の都合で割愛

Slide 56

Slide 56 text

アンチパターンを防ぐには? キャッシュの活用は 参照整合性とのバランスで決まる

Slide 57

Slide 57 text

アンチパターンを防ぐには? しかし多用は禁物 第16章で「キャッシュ中毒」があるので詳しくは書籍で

Slide 58

Slide 58 text

アンチパターンを防ぐには? 非正規化がそれでも必要な時

Slide 59

Slide 59 text

アンチパターンを防ぐには? 非正規化がそれでも必要な時 ↓ 制約を使う

Slide 60

Slide 60 text

非正規化の例 postgres=# SELECT * FROM アンケート; id | 回答者 | 好きなデータベース | その他 ----+----------+--------------------+-------- 1 | soudai | PostgreSQL | 2 | sone | MySQL | 3 | taketomo | OracleDB | SQLite ←不整合 4 | test | SQL Server | 5 | hoge | その他 | Db2 id=3の「その他」列に不正な値 データが壊れるのは正規化出来ていない証拠

Slide 61

Slide 61 text

正規化の例 postgres=# SELECT * FROM アンケート; id | 回答者 | 好きなデータベース ----+----------+------------------- 1 | soudai | PostgreSQL 2 | sone | MySQL 3 | taketomo | OracleDB 4 | test | SQL Server 5 | hoge | Db2 postgres=# SELECT * FROM データベースの種類; id | DBの種類 | 回答 ----+------------+------------------- 1 | PostgreSQL | PostgreSQL 2 | MySQL | MySQL 3 | OracleDB | OracleDB 4 | SQL Server | SQL Server 5 | DB2 | その他 6 | SQLite | その他 正規化の例 アンケートテーブルの好きなデータベース列は、 データベースの種類テーブルを親とした 外部キー制約を作る

Slide 62

Slide 62 text

アンチパターンを防ぐには? 非正規化したまま CHECK制約を使ってデータを守る

Slide 63

Slide 63 text

CHECK制約の活用例 -- 想定したデータの登録 postgres=# INSERT INTO enquete ("id", "回答者", "好きなデータベース", "その他") VALUES (1, 'soudai', 'PostgreSQL', ''),(2, 'sone', 'MySQL', ''); INSERT 0 2 -- 正しくその他を登録する postgres=# INSERT INTO enquete ("id", "回答者", "好きなデータベース", "その他") VALUES (3, 'taketomo', 'その他', 'Db2'); INSERT 0 1 postgres=# SELECT * FROM enquete; id | 回答者 | 好きなデータベース | その他 ----+----------+--------------------+-------- 1 | soudai | PostgreSQL | 2 | sone | MySQL | 3 | taketomo | その他 | Db2 (3 rows) 非正規化されたテーブル

Slide 64

Slide 64 text

CHECK制約の活用例 postgres=# CREATE TABLE enquete postgres-# ( postgres(# id serial NOT NULL , postgres(# "回答者" text NOT NULL, postgres(# "好きなデータベース" text NOT NULL, postgres(# "その他" text NOT NULL CHECK postgres(# (CASE postgres(# WHEN "好きなデータベース"!='その他' AND "その他"='' THEN TRUE postgres(# WHEN "好きなデータベース"='その他' AND "その他"!='' THEN TRUE postgres(# ELSE FALSE postgres(# END) postgres(# ); CREATE TABLE 「好きなデータベースの列」に”その他”が設定された時のみ、 「その他の列」にデータを投入できる

Slide 65

Slide 65 text

CHECK制約の活用例 -- 好きなデータベースがその他の時以外はエラーになる postgres=# INSERT INTO enquete ("id", "回答者", "好きなデータベース", "その他") VALUES (3, 'taketomo', 'OracleDB', 'SQLite’); ERROR: new row for relation "enquete" violates check constraint "enquete_check" DETAIL: Failing row contains (3, taketomo, OracleDB, SQLite). -- 好きなデータベースがその他の時に空白でもエラーになる postgres=# INSERT INTO enquete ("id", "回答者", "好きなデータベース", "その他") VALUES (3, 'taketomo', 'その他', ''); ERROR: new row for relation "enquete" violates check constraint "enquete_check" DETAIL: Failing row contains (3, taketomo, その他, ). CHECK制約で守られる

Slide 66

Slide 66 text

https://soudai.hatenablog.com/entry/2019/01/15/014228

Slide 67

Slide 67 text

アンチパターンを防ぐには? CHECK制約で確実にデータを守りながら テーブルを一つ減らせる

Slide 68

Slide 68 text

アンチパターンを防ぐには? 類似例にENUM型がある

Slide 69

Slide 69 text

アンチパターンを防ぐには? しかしCASE式を使ったCHECK制約は メンテナンス性が低い

Slide 70

Slide 70 text

アンチパターンを防ぐには? 正規化出来るなら正規化したほうが良い

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

Tips なんとMySQL 8.0.16から CHECK制約が来ます!

Slide 73

Slide 73 text

アンチパターンのポイント 正規化出来るなら正規化したほうが良い

Slide 74

Slide 74 text

アンチパターンのポイント 正規化出来るなら正規化したほうが良い ↓ RDBは正規化に始まり、正規化に終る

Slide 75

Slide 75 text

アンチパターンのポイント 非正規化の技術的負債の利子は重い

Slide 76

Slide 76 text

アンチパターンのポイント 非正規化の技術的負債の利子は重い ↓ 代替手段があるのでそれを念頭に置き 論理設計を行うことが大切

Slide 77

Slide 77 text

https://soudai.hatenablog.com/entry/2018/08/31/222107 正規化の話

Slide 78

Slide 78 text

https://builderscon.io/tokyo/2018/session/ddba9bd5-819e-489e-9123-04d2291d506e 動画もあるよ

Slide 79

Slide 79 text

非正規化と履歴データ 非正規化と履歴データは違うの?

Slide 80

Slide 80 text

非正規化と履歴データ 非正規化と履歴データは違うの? ↓ 履歴データは非正規化に見えるが 非正規化ではない

Slide 81

Slide 81 text

非正規化と履歴データ 別々の事実の積み重ねが履歴データ 非正規化は事実の重複

Slide 82

Slide 82 text

あじぇんだ 1 自己紹介 2 失われた事実 3 簡単すぎる不整合 4 隠された状態 5 まとめ

Slide 83

Slide 83 text

No content

Slide 84

Slide 84 text

隠された状態 RDBに状態を持たせるのはたいへん危険です。 第2章「失われた事実」や第5章「フラグの闇」でも、RDB に事実のみを保存することの大切さと難しさをお話しました。 なぜ複数の章に渡って強調してきたかというと、 隠された状態には多くの罠が潜んでいるからです。 本章ではその理由と、それによって引き起こされる問題に ついて説明します。 -- 失敗から学ぶRDBの正しい歩き方 – 第7章 簡単すぎる不整合

Slide 85

Slide 85 text

隠された状態 データに状態を持たせることは危険

Slide 86

Slide 86 text

user_idを見てユーザを判断 if($this->is_admin($user->user_id)) { // 管理者用の処理へ } // user_id の先頭が 9 だった場合は管理者 function is_admin($user_id) { $role_id = mb_substr($user_id, 0, 1); return ($role_id == 9) ; } idに状態が隠れている

Slide 87

Slide 87 text

閲覧のみユーザ用の処理を追加 $role_id = $this->get_role_id($user->user_id); if ($role_id == 9) { // 管理者用の処理へ } elseif ($role_id == 8) { // 閲覧のみユーザの処理へ } function get_role_id($user_id) { return $role_id = mb_substr($user_id, 0, 1); } 仕様追加の度に複雑に

Slide 88

Slide 88 text

隠された状態 県番号(2桁) 部門ID(3桁) 支店ID(4桁) (例:330010012) よく見る例

Slide 89

Slide 89 text

隠された状態 今の会員数と管理者の人数って何人?

Slide 90

Slide 90 text

隠された状態 今の会員数と管理者の人数って何人? ↓ 検索時にuser_idを分割するSQLが必要 複雑+INDEXも効かないので即答できない

Slide 91

Slide 91 text

隠された状態 意味を含んだID データベースリファクタリングでは スマートカラム呼ばれるアンチパターン

Slide 92

Slide 92 text

隠された状態 ソースコードやクエリからは user_idだけでは意味がわからない

Slide 93

Slide 93 text

似たようなアンチパターン • EAV (エンティティ・アトリビュート・バリュー) • Polymorphic Associations (ポリモーフィック関連) SQLアンチパターン 本著でも説明している

Slide 94

Slide 94 text

まだ読んでないなら絶対読んだほうがいい 本著はSQLアンチパターンを読んでる前提の説明も多い

Slide 95

Slide 95 text

隠された状態 コードやデータから見えない状態の辛さ

Slide 96

Slide 96 text

隠された状態 コードやデータから見えない状態の辛さ ↓ 運用コストが激増する

Slide 97

Slide 97 text

アンチパターンを防ぐには? 正規化をする + 事実を保存する

Slide 98

Slide 98 text

アンチパターンを防ぐには? 事実のみを保存する

Slide 99

Slide 99 text

アンチパターンを防ぐには? IDとはidentification

Slide 100

Slide 100 text

アンチパターンを防ぐには? IDとはidentification ↓ 識別できる一意の値 以上の意味を持たせてはいけない

Slide 101

Slide 101 text

会員id 名前 900001 曽根 壮大 900002 曽根 徠楽 100003 曽根 煌楽 100004 曽根 朔楽 idから権限の責務をカラムに分割する 会員id 名前 権限 1 曽根 壮大 管理者 2 曽根 徠楽 管理者 3 曽根 煌楽 一般ユーザ 4 曽根 朔楽 一般ユーザ 意味を含んだIDの改善例

Slide 102

Slide 102 text

アンチパターンを防ぐには? 正しく正規化をすること

Slide 103

Slide 103 text

アンチパターンのポイント • データに複数の意味を持たせない • 1つのデータの責務を小さくする • 常に状態が見えるようにするために 事実のみを保存する

Slide 104

Slide 104 text

アンチパターンのポイント 交差テーブルをちゃんと作る

Slide 105

Slide 105 text

アンチパターンのポイント 交差テーブルをちゃんと作る ↓ JOINのコストを最初から危惧しない 失われた事実と同じく、パフォーマンスの問題は 別の方法で対応する

Slide 106

Slide 106 text

アンチパターンのポイント 正規化出来るなら正規化したほうが良い めちゃくちゃ大切なことなので何度も言います

Slide 107

Slide 107 text

おまけ

Slide 108

Slide 108 text

おまけ

Slide 109

Slide 109 text

あじぇんだ 1 自己紹介 2 失われた事実 3 簡単すぎる不整合 4 隠された状態 5 まとめ

Slide 110

Slide 110 text

まとめ “愚者は経験に学び、賢者は歴史に学ぶ。” --オットー・ビスマルク

Slide 111

Slide 111 text

まとめ データベースの寿命は アプリケーションよりも長い

Slide 112

Slide 112 text

まとめ データは失うと取り戻せないし、 情報はデータが無いと作れない

Slide 113

Slide 113 text

まとめ 他人の失敗から学び、 正しくRDBを使いこなす

Slide 114

Slide 114 text

まとめ 今、あるデータベースと向き合うには?

Slide 115

Slide 115 text

まとめ 今、あるデータベースと向き合うには? ↓ 自分たちで直すしかない

Slide 116

Slide 116 text

https://builderscon.io/tokyo/2017/session/c8f36693-32aa-4bf1-816a-4966f3859926

Slide 117

Slide 117 text

まとめ 諦めず、仕組みで解決していく

Slide 118

Slide 118 text

まとめ 諦めず、仕組みで解決していく ↓ 仕組みは技術力で解決できる

Slide 119

Slide 119 text

まとめ 数冊の本を読むだけで 充分な知識がつくのがRDB

Slide 120

Slide 120 text

まとめ 技術で問題を解決していく

Slide 121

Slide 121 text

まとめ 技術で問題を解決する ↓ 解決までの歩んだ轍が道になる

Slide 122

Slide 122 text

まとめ RDB THE Right Way

Slide 123

Slide 123 text

まとめ RDB THE Right Way ↓ あなたの道を歩くのはあなた自身

Slide 124

Slide 124 text

まとめ 自分自身で改善のサイクルを回していく

Slide 125

Slide 125 text

まとめ 技術で解決した問題の価値が エンジニアの価値

Slide 126

Slide 126 text

まとめ 自分自身で問題を解決していきましょう

Slide 127

Slide 127 text

ご清聴ありがとうございました