# 2021/5/23 メンター相談 ###### tags: `メンター相談`,`5月` ## DBモデリング1の課題で設計したテーブルについて。中間テーブルを多用しているため、少しテーブル数が多く、クエリにJOINが増えてしまうような気がするのですがどうでしょうか? 実務ではどのような点を考慮して設計しますか? - 松原さんの想定回答 - ProductとProductSetがあり、ProductSetがProductに対して2つFKが向いている - OrderDetailとOrderがあった場合、Productの単位で扱うことができる - 例えばどのネタが月に幾つ売れたかを知りたい場合、Productをみて、OrderDetailからJOINしてくれば良い - ねたの数量管理もできるし、Aセットがハッピーセットみたいなのに含まれるネストが深くなった場合に、対応できる - セットに柔軟に対応できる ![](https://i.imgur.com/hnHTtC7.jpg) - ちなみに使っていたiPadのアプリは「[コンセプト](https://apps.apple.com/jp/app/%E3%82%B3%E3%83%B3%E3%82%BB%E3%83%97%E3%83%88/id560586497)」 - 書く場所が無限に広がるので良い - 石原さん作成で気になったこと - 松原さんは名前と電話番号はOrderに持たせた - 電話番号をいつ使うか→注文できた場合の連絡用だろう(仮説) - 家族で買い物に来ていた場合、注文した人と連絡先が別になる可能性があるので、Orderに持っても良いかと思った - オンライン注文になった場合、ユーザーのテーブルにあるその人のテーブルしかわからない - オンラインになったら、ユーザーにもOrderにも電話番号を持つようにする - 全ての寿司が何らかのサブカテゴリに属している構造 - 今回の注文表であればそれでも大丈夫そう - もっと値段を細かくしようとしたときに(ネタごとに値段が異なる)、毎回カテゴリを作らないといけなくなる - 今後お店の運用が変わった場合に、運用上の制約が出てきそう - 松原さんテーブルはそれにも対応できるようにしている - OrderTypeIDがあるが、それを参照しているのは、RegisterTypeID? - 持ち帰りや店内などの注文情報はMENUに紐づく? - Yes(石原さん) - ならOKそう(松原さん) - 中間テーブルを使うとJOINが増えてしまうが - 増えたテーブルのレコード数がどれだけ増えたかを気にする - 寿司ネタはせいぜい100とかなので、そこまでJOINに時間がかからない - Orderとかはすごい増えるので、そこは悩む - わけてもレコード数がそんなに増えないなら、そこまで気にしない - NULLだらけになるよりは、こちらの方が良い - 複雑なアプリケーションのためにテーブルが増えるのは、仕方ない - 閉包テーブルの方が良かったか? - 2階層しかないことが確定しているなら、ナイーブツリーでも良い - 松原さんのは閉包テーブルに近い - 仕様変更あった場合に困りそうなこと - 設計上めっちゃ困るのは電話番号と、カテゴリの件以外、思いつかない - セールを行うときに、カテゴリごとにやりたい場合はどうする - 条件と値が多様なバリエーションがある - 期間 - 決算手段 - マグロは2割引き - 今回はセール対象ごとにセールごとに分ける - にぎりセールテーブルなどを作って、アプリケーション側で判断する - セールはバリエーションがあるので、セールごとにテーブル分ける - にぎりとマグロフェアなど複数のキャンペーンがあった場合の優先順位が出て場合に、テーブルを分けておいた方が良い - 履歴情報は別テーブルで取っておくのはあり - クレーム対応用とか - 消費税のテーブルは? - 作っておいた方が良い - 適用期間をテーブルに入れるべきかという議論がある - 8→10%になった場合、8%を10にUPDATEすると、過去の税率が分からなくなるので、適用期間があった方が後々辿りやすい - 遡及系が必要ない場合は、消費税のレコードは1つのみでそれをUPDATEしていくのでも、問題はない気がする - MySQLが子テーブルを更新したときに親テーブルのロックをとった気がするので、本番を止める可能性はあるかも - 適用期間があれば、止める必要はなくなる - Orderに価格を保持するのは良い - 価格はよく変わるので - 今回は意外と複雑なテーブル - さびがありorなしなのが今後怖い - ワサビテーブルがあった方が良くなるかも - お支払い済みか否かは、絶対ヒアリングする - 地元に生まれた味の化粧箱入りも番号ないのが気になる - 寿司ネタの集計で、セットの時は一貫のみの時もあるので、どうやって集計するかが気になる - その他も気になる - 何を書くんだろう ## 生徒テーブルに対してステータスIDをそのまま持たせる設計は、生徒のステータスが排他関係にある場合にのみ使用するのでしょうか。 - 生徒に対して、複数のステータスが割り当てられる可能性があるかで考えれば良い - 設計2の交差テーブルの方が良い - 個人的には全て交差でも良い - 交差でできないことがない - JOINが一回増えるくらい - Uniqueキーを貼ってしまえば、サロゲートキーで交差テーブル作れば良いと思う - 生徒に対してステータスがない状態を想定するか ## 論理設計の段階ではサロゲートキーがないほうが設計しやすいとありましたが、実務でDB設計を行う際には実際に論理設計のときにはサロゲートキーを考慮せずに設計しているのでしょうか - 論理や物理の厳密な定義はあまりないので、使いやすいように使い分けるのが良い - 混ぜても良いのでは - 寿司の件は論理で考えたが、外部きーやデータも実際に入れて考えてみている - 論理はこれを入れてはいけないというのはないので、チームによっても違う - キーがあっても消しにいく必要はない - リソースやイベントを書き出すときには、その状態では外部キーなどは考えていない ## 課題「DBモデリング1」について質問です。ペアレビューで、商品の税込み金額を商品テーブルに持たせるパターンと税率テーブルを新たに作って、多 : 1 (注文 : 税率)として注文時に税込み金額を計算するパターンの2つの意見が出ました。それぞれ以下のようなメリット・デメリットが考えられるのですが、どちらを選択した方が良いでしょうか? - 個人的には税率テーブルあった方が安心 - 税率の適用期間も欲しい - テストもしやすい - 消費税変わった時や軽減税率が発生した場合に辛い - 商品に紐づくと辛い - 肉だとx%とかものによって税率が異なるとなおわけた方が良い ## その他 - モデリングの段階で、JOINの仕方やクエリについて考慮した方が良いか? - JOINは外部キーがあるかくらい - 外部キーがないと繋げようがないので - トランザクションに関しては、テーブルを跨いだら、1つにしないといけなそうとは考えるが、最終的にトランザクション大きそうだから分けるのやめようと思っているが - 迷ったら、細かく分けるようにしている - 困るのは、JOINくらいなので - まとめるのは簡単 - マテリアライズドビューでなんとかできないかを考えたりする - 正規化して、SQLが複雑になるのではと思ってしまう - JOINに慣れる - ORMを使っていれば、こっちでJOINを考える必要はなくなる - Prismaでは、ネストして書いていけば、勝手にJOINしてくれるので、ORM使ってるとあまり辛さは感じなくなる - あまりにも遅いと言われたら考えるが - 閉包テーブルのrelation関係を作るテーブルに、毎回自分自身のレコードを作る意味は何だろう。 - ルートを取ってくるとき? - 何かのクエリを書くときに自己参照があって役立った気がする - 後で松原さん調査 - ツリーにないと、そもそもツリーに存在するのかどうなのか分からなくなる(古川さん?) - https://stackoverflow.com/questions/22416571/when-inserting-why-does-a-closure-table-point-to-itself