41から始めました

文字通り41歳から始めたブログです。DB(MySQL)を使ってお仕事してるので、DB周りの話を中心に最近始めたこととかをTwitterのノリで書いています。なお、本サイトにおいて示されている見解は私個人の見解であり、所属団体や組織を代表するものではありません。

DB設計したいNight #4 そーだいさんと失敗から学びながらDB設計したいnight参加してきました

募集内容

枠名 参加条件
通常参加枠 300円(会場払い)
本購入枠 無料。但し本を持参する
絶対来る枠 300円(会場払い)
ブログ枠 無料

最後のブログ枠って、参加報告ブログを書いて資料としてアップするってことかな?

とにかく、自分は本購入してる(フフフ、サインも入ってるぞ!)ので本購入枠で参加してきました。

スケジュール

開場

19時開場、19時半開始ということでなるべく早く行って良い席とろうと思ったが、当日定時で上がれず、 参加枠も本購入枠もまあまあ当日までいい感じで埋まってて、増席すらあったので

「これは微妙な席になっても仕方ないかも…」

と覚悟してましたが、まだ19時5分時点でそこまで混んでおらず、前から2列目の正面席を取れて自分的にはベストポジションでした。

(すでに@kaibaさん、@Nakunaruさん、@yuyasatさん、@bringer1092さん達が楽しそうに雑談されてましたが)

ゴザ席というなかなか初心者には 座りにくい 勇気のいる席があり、誰もそこには座れずw

あれはもしやるのであれば映画館形式の席の並べ方じゃなく、コロシアムというかスタジアムのようにメインの人を囲むような感じにしたほうが良かったのかなあ?なんて思ったりしました。

ちなみに会場はピクスタ株式会社から提供していただきました。ありがとうございました。

始めて来ましたが、とても綺麗なオフィスで羨ましいです。(うちも引越ししたい)

そーだいさん到着

19:25頃、本日のメインご登場。

本当に「ワタシ"ポスグレ"チョットデキル」 Tシャツが眩しいです。

イントロダクション

開場説明と今回の進め方について簡単にお話。

あとで懇親会で知ったが、過去の回とは今回の回の進め方全然違ったらしく、過去のやり方はお題があってそれに対してみんなでERDとか書きながら発表し合い、ゴールを探すやり方だったらしいけど、今回はお題の失敗談をいくつか用意しておき、それについてそーだいさんとNakunaruさんが答えていくというディスカッション形式でやりますよー、とのこと。

でも、イベントページの概要をもう一回よく見たら

迷えるDB設計初心者達のための勉強会です。 普段はハンズオン形式ですが、今回は そーだいさん と nakunaruさんのパネルディスカッション形式です。

って書いてあって、うん、なるほどw

一つ目のお悩み(お題①)

Kさんという匿名の方からのお悩みだそうでw

  • 電話帳のような企業向けアプリのお話
  • 支店、部署、人名のように絞り込みをする
  • 支店番号は数値か昇順にしてほしい
  • それなのに東京支店は30aと30bがあって文字列
  • 対応として支店コードを36進数にした

型変換に悩んでいる様子

一つ目の悩みへの回答

  • 支店名が入るマスターを作ればよかったのでは?
  • テーブル追加で対応できる
  • テクニックで逃げるのではなく、基本を大事に

といった回答がありました。

自分だったらどうしてただろう?

少なくとも36進数は思いつかないw

自分は正規化推進派(一回小さく、少なくとも第三正規化まではしておきたい)なので、おそらくテーブルを作って対応するだろうな、と思いました。

もちろん、それによりDBMSによっては結合回数が多くなって遅くなることも考えられるのですが、これはそーだいさんも言ってた通り、テーブルを合わせるのは分割するよりも簡単なので、その時は合体すればいいので、マスターテーブル化がベターなんだと思われます。

(そうすればあとはマスターみたいな情報なんだから、速度云々みたいな話になるんならAWSならS3みたいなところに入れといて、DB使わずにそこからキャッシュに入れるんでもいいんじゃとかもある)

二つ目のお悩み(お題②)

なんとこちらもKさんからのお悩みだそうでw

  • 賃貸物件と売買物件の両方を扱うサービス
  • 数多くの項目があるのだが、異なるのは一部
  • 現在は全く別のテーブル
  • 別のソースコードだが、処理はほぼ同じ
  • だがそれぞれ別のサービスなので、テーブルは分割されていたほうが使い勝手はよさそう
  • というわけでテーブル構造もSTI(単一テーブル継承)構造にした
  • そうしたら賃貸されてるのに売買されているという変なデータができた

というお話。

二つ目の悩みへの回答

  • 賃貸・売買物件を親にしてしまうのはどうか?
  • その二つの親から共通テーブルが見える形にすれば
  • そこで親テーブルのIDの排他を担保するためのCHECK制約(MySQLだと8.0.16から)を使う
  • もしくは共通テーブルのIDを親が持つ
  • この時、共通テーブルにフラグを持たせがちだが、1つのテーブルに複数のステータスや状態を持たせないほうがいい
    • そうなるのなら別テーブルに分割
  • 共通項目は本当に共通かはちゃんと考えたほうがいい

自分だったらどうしてただろう?

これ、うちも業種が同じなのでわかるんですが、基本的には元々設計した人がしっかりDB分かってる人だったんで既にそーだいさんが言ったようなことが自社のDBではなされててます。

それでも後から新規に作られるテーブルやカラムは上記のような基本を考えていないことがあるので、その辺に目を見張らせるのが今の自分の仕事だったりします。 (数が多すぎて見れてないこと多々ありますが・・・。)

まあ、Check制約については無い場合がMySQLの場合ほとんどだと思うので、API側にやらせるんでしょうね。

あとはJOINで速度が出ない場合はこの共通テーブルに色々入れていきたくなり、遅くなりがちになるので注意です。

三つ目のお悩み(お題③)

こちらはNさんからのお悩みだそうですw

KとかNとか、あれー、管理者さんのイニシャル…

  • 元々はこんな感じだった
    • 飲食店向け求人サイト
    • 店舗テーブル
      • 店舗情報、掲載期間、審査ステータス、編集ステータス
    • 現行、エリア、路線、駅
      • 店舗テーブルとJOINして検索
    • 店舗ビュー
      • 店舗テーブルと関連があるすべてのテーブルをJOINする
  • パフォーマンスが悪い!
  • というわけでなんでも取れるビューはダメだ、分割しよう!と考えた
  • 画面上のブロックで必要なデータだけを取るビューを作成
  • その結果ビュー同士の依存が4階層になり、ビューの数が200以上に
  • どのビューを変更するとどこが壊れるかわからない!!!
  • 開発速度が遅くなってしまった

三つ目の悩みへの回答

  • サマリテーブルやマテリアライズドビューを作ろう
  • キャッシュも使おう
    • 更新頻度が少ないマスター系データはキャッシュに入れたり、S3にファイルを置いといてそこから見よう
    • とはいえ、キャッシュ中毒の章(16章)はよく読んで使いましょう
  • ビューの多段は絶対ダメ(2階層以上)
  • ビューは1段構成(Not 多段)であれば作る順番は気にしなくて済む
  • ビューでビューを作ったりすると、更新順序を守らないと古いキャッシュが残り、ビューのデータがおかしくなる
  • 分けたものをくっつけるのは楽だけど、くっついたものを分けるのはツライ
  • 論理設計を最初にちゃんとやって、細かく割ってから、とりあえず動かしてチューニングするのがいい
  • ちなみにビューやマテビューを使いたくなったら、それは設計をミスってて、それをDBMSで直す飛び道具としてビューやMビューを考える
  • あと、ビューの使いどころとしては、以下の3つがある
    • テーブルを分けたいときに、その分割前の状態をビューにしておくパターン
    • ビューに参照権限付与して、元のテーブルを見せない
    • 設計が悪いパターンで変えづらいやつに対し、結合した結果を見せたビューを作る(前述のやつ)

自分だったらどうしてただろう?

まあ、やっぱり正規化して細かくテーブル分割して、見たかったらJOINしたり、パフォーマンス出ないなら結合テーブルっていうのでいいんじゃないかな?

ビューをそもそもアプリ側が吸収してくれるならそれで良くて、それがツライっていうんなら仕方なくビューを用意するって意識なので、それを多段にするってのは考えない。

MySQLここ2年半ほど触ってきて、思った以上にちゃんと作ったりちゃんとSQL組まないとすぐ遅くなるので(Oracleとは大違い)、その辺は全然意識が変わった。

それでもビューを多段にするのは20代で一回失敗してからOracleでもやらないようにしてるけど。

ライトな質問①

ここからはお悩みというか、質問タイム。 まずは、

不要になったカラムは消すか?

これに対してはいらないという判断がつきづらいので消せないという話が多かったけど、そういう人も要らないのが判ってたら消すんでしょ?と思いきやそうでもなかった。

怖いから念のため取っておくという人が結構いた。

OracleMariaDBではinvisible columnができるから、そういうので試したらいいと思うし、インデックスでも同様の話があるのでそれも確認する方法を使って消せばいい。

ログテーブルって作ってる?

作ってる人はほとんどいなかった。

RDBに入れておくと便利だけど、そのメンテがめんどくさい。

不要になったログデータをS3などにファイル化して退避させてから削除する仕組みを作ればDBに入れとくのもありでは?という話。

懇親会

フード・ドリンク等の費用サポートのForkwell様ありがとうございました。

お酒飲めないんですが、コーラをたくさん飲みましたw

同じテーブルにいた人達が結構個性的で、その人たちとも交流できて面白かったです。

本当はそーだいさんや最近DBREという言葉を教えてくれた@_awacheさんとお話したかったんですが、あまり動き回るのもアレかな~、と思ってるうちに家族都合のタイムアップ。

次回は積極的に動こうかな?と思ってます。

あ、でも帰りにそーだいさんがぐーぜんエレベーターホールまで一緒になって、帰りに色々温かい言葉かけてくれたり、握手までしてもらったりしたし、

@_awacheさんからも

こんな優しい言葉かけてもらって、

行って良かったDB設計したいnight!でした。