『失敗から学ぶ RDBの正しい歩き方』発刊記念!そーだいさんから直接学ぶ会 に参加してきました
行ってきました
先日、『失敗から学ぶ RDBの正しい歩き方』発刊記念!そーだいさんから直接学ぶ会 に参加してきたのでそのレポートというか雑記です。
https://mixi.connpass.com/event/124948/
3部構成で、最初にこの会を開いてくれたミクシィの担当者(しょっさん)さんから会社説明と会場説明、そしてこの会を開くきっかけが5分ほど話され、 次にミクシィの2年目のエンジニアであるさのひろゆきさんから今年の新人研修資料の発表が同じく5分ほどあり、 最後に1時間ほどそーだいさんの話という流れでした。
内容についてはありがたいことに動画をミクシィさんがアップしてくれているのでそちらを見たほうが 自分が書くよりも確実なものが得られると思うので大半は割愛しますが、メモ的な感じでとった感想等を 書いておきたいと思います。
1部
開催小話
そーだいさんが本を出されて、それがいい本だったので社内のSlackで話題に挙がった ⇒しょっさんがTwitterで今回の会についてつぶやいてみたら本人が快諾してくれた
奇跡の上に成り立った会!
引き受けてくれたそーだいさんにしょっさんさんが感謝してましたが、それを実現したしょっさんさんとミクシィ社にも感謝です。
2部
新卒DB研修
さのひろゆきさん 出てきた瞬間、ベテラン感あふれる風貌なのに、プロフィールで「2017年度新卒」ってマジか!(失礼)
2年目に研修資料作らせてるのはまあいいとして、その内容が
- SQLチュートリアル
- Jupyter Notebookを用いてSQLの機能確認 ⇒わかる
- インデックスの演習
- ISUCONの過去問題を題材にpt-query-digest/EXPLAIN/インデックスの使い方を学ぶ …うん、まあわかる。(ISUCONの過去問題を題材にするところとpt-query-digestはちょっと早い気もするが)
- ストレージエンジンの実装
- MySQLのストレージエンジンの実装を通してデータベースの基本機能を自作してみる
ミクシィの新人研修、新人のレベルが凄すぎる気がするの自分だけ? 俺もストレージエンジンの実装なんてしたことないわ…。
3部
そーだいさんのお話
序 なぜこの本を書いたか
https://soudai.hatenablog.com/entry/2019/03/06/080000
『失敗から学ぶ RDBの正しい歩き方』 この本、とてもわかりやすいし『SQLアンチパターン』を参考にしつつも内容が被らないように気を付けてていい本だなあと思ってましたが 作るのに「2年くらいかかった」というコメントからもこういう良書を作るにはやはりそれだけの労力が必要なのには納得でした。
何のためにこの本を書いたかという目的として「知識をつないでいくため」というフレーズはハッとさせられました。
- インターネットに置いておくと、古い話や失敗事例なんかは色々なパターンで消えていく
- サイトがなくなったり
- 著者がなくなるとクレジットカードを止めてサイトがとまるとか
言われてみると確かにそうです。 (ネット上の情報は生き物じゃないから永遠に残ってそうだと思ってたけど、それを管理するのは生身の人間なので永遠じゃない)
先日Microsoft Storeで電子書籍の終了があったが、書籍という形であれば書店はもちろん、電子書籍も複数のメディアで販売できるのでブログという形よりは確実に次につなげられる。
データベースのノウハウは10年レベルで使えるし、必要であれば改定すればいい。
今回のこの本はSQLアンチパターンと同じように定期的に読んで、自分の血肉にしていかなければ意味がないなと思いました。
本題
https://speakerdeck.com/soudai/learn-from-failure-1
今回は『失敗から学ぶ RDBの正しい歩き方』の中の2章、15章、7章についての話でしたが、Q&Aではそこ以外の章とも絡んだ話がされました。(8章 JSONの甘い罠)
失われた事実
- 履歴の保存をすることで過去の情報が失われることを防ぐ
- But、履歴の保持はパフォーマンスに影響する
- 設計時に事実の履歴をしっかり検討することが大事
簡単すぎる不整合
- 正しく正規化することが大事
隠された状態
アンチパターンのポイント
- データに複数の意味を持たせない
- 削除フラグ・・・フラグなのに0,1,2,...99,NULLってあったことがある。
例
- 友人のyoku0825さんがTwitterでこんなことをつぶやいてました
SQL> SELECT COUNT(*) FROM t1 WHERE c1 = 'null'; COUNT(*) ---------- 1231 SQL> SELECT COUNT(*) FROM t1 WHERE c1 IS NULL; COUNT(*) ---------- 3531
(これはよく見るw)
- テーブルやレコードを分ければシンプルになります。
- 一つのデータの責務を小さくする
- 正規化すると自然とそうなる。パフォーマンスも上がる。
- 常に状態が見えるようにするために事実のみを保存する
- こちらを参考にしてください⇒https://speakerdeck.com/soudai/rdb-the-right-way
Q&A
Q:JSONについての章と隠された状態の話ってつながりがありますか?
A:あります
Q:隠された状態でユーザテーブルが作られていた場合ユーザごとにカラムを分解した方が良いのか?それとも管理者と普通のユーザのようにテーブルを分けたほうがいいのか?
A:結論ケースバイケースです。
- ユーザを設計するときに、というブログを書きました。
- https://soudai.hatenablog.com/entry/2018/05/01/204442
そこでは - ステータス,フラグごとにカラムを二つ、三つ作って管理するのは絶対にダメ。 - ステータスカラムを持つべきだが、その場合はテーブルが肥大化しやすい。 - テーブルを分解すると肥大化が抑えられるが、同じユーザが存在するテーブルが複数存在する形になる - 会員はどれくらいで考えているか?を元に最初に設計しましょう。 - テーブルを増やすのは楽だけど、分けるのはしんどいです。
追加で自分が質問した内容
本にサインをもらいに行ったんですが、その際に以下の質問をしてみました。
Q:正規化した場合のパフォーマンスはどのように上げられるのか?
MySQLで正規化を進めていくとJOIN結合が発生した場合に遅くなりがちと言われるが、それでも正規化はすべきで、それ以上のパフォーマンス劣化はRDBの責務の範囲外に来ているから別の対応をした方が良いといわれましたが、具体的にはどのような方法がありますか?
A:レプリケーション・必要な情報を集めたテーブル作成・NoSQLを活用してみてください
- レプリケーションで必要なデータだけを特定のスレーブに集める
- 必要なデータを結合したビューテーブルを作る
- NoSQL上にキャッシュしておく
最後に
懇親会に家族都合で最後までいられませんでしたが、非常に有意義な時間を過ごせました。(そーだいさんに追加質問できたり、懇親会で知人ができたり) 現場を提供してくださったミクシィ様、スピーチに立ったミクシィのさのさん、この会を企画してくださったしょっさんさん、そして10年物のノウハウを残してくれたそーだいさんには本当に感謝しています。