# 2021/5/30 メンター相談 ###### tags: `メンター相談`,`5月` ### 154.【質問】リレーションが、直接的に無いテーブルどうしでも、結合していいのか (質問全文) https://airtable.com/tblA4yYGHwaqDYKwx/viwAUwNVsR9rOkW6u/reccqH32mLeb1lgQV?blocks=hide 結合すること自体は可能。 NULLが許容できるなら、外部キーがないといけないという制約はない。 今回のように同じPK同士をみているなら問題はないと思います。 自分が上記のような設計をしたことがないのは、 おそらく、この場合UserInfoなどのテーブルを作ってしまうためだと思います。 ### 155.注文明細に顧客IDを持たせる設計にした場合、ユーザー登録なしで注文できる仕様をどのように表現すればいいのか (質問全文) https://airtable.com/tblA4yYGHwaqDYKwx/viwAUwNVsR9rOkW6u/recBX6cXeaUe0Ra6P?blocks=hide 顧客IDと注文の関係が1対多の場合、顧客IDが必ず存在していることが前提となる。 そのため、1つ目の多対多の中間テーブルを設ける。 2つ目の場合、プログラマーの暗黙の了解で作ってしまうと、そのプログラムマーがいなくなってしまうと分からなくなってしまう。 3つ目について、アプリケーション側で扱いが違うなら、テーブルを分けるケースも有り得る。 ただ今回はユーザー登録の有無によって扱いは変わらないはずなので、中間テーブルを用いるのが良いと思った。 -- 仕様書を見ないとわからないようなテーブル構造はやめる。 [1=男性]がみたいな。仕様書が燃えたらわからなくなってしまう。 性別テーブルを持たせて、そこに追加していくだけで良いようにする。 ### 156.商品マスタや顧客マスタが変更されてしまうことをどのように記録するのか (質問全文) https://airtable.com/tblA4yYGHwaqDYKwx/viwAUwNVsR9rOkW6u/recBX6cXeaUe0Ra6P?blocks=hide 履歴を辿りたいかどうかによって作り方を変えると思います。 例: 商品 - レシート - ユーザー のテーブル ![](https://i.imgur.com/KIisgBG.jpg) - ① 注文時の情報を変更させたくない場合、 レシートテーブルに商品名、商品価格を重複してもたせる - ② 商品情報の変更履歴を管理したい場合、それとは別に producthistoryテーブルを作る - ① productには idしかもたせない (情報が一箇所にまとまるので、松原さんはこちらのほうが好み) - ② productには name, price, id を重複してもたせる (最新の情報を取りやすいように) - parent_history_idがnullなら最新とする方法もある ### 157.適用開始日や適用終了日などの期間を有するテーブルを設計した場合に、データベースのトリガー機能を使用したりすることはありますか? (質問全文) https://airtable.com/tblA4yYGHwaqDYKwx/viwAUwNVsR9rOkW6u/recJuEHg4tOn1DK87?blocks=hide postgressを使用して解決する。 以下2つのpostgress機能を組み合わせる。 ・TSRANGE(いつからいつという型:範囲型) ・EXCLUDE(同じテーブル内でレンジ重複チェック:範囲の制約) この問題についてはトリガーを使ってもいいんじゃないかと思います。 ### 158.セールや特売時の商品価格を別テーブルにモデリングする際の方法はどうすればいいでしょうか (質問全文) https://airtable.com/tblA4yYGHwaqDYKwx/viwAUwNVsR9rOkW6u/recZOFraGflpiHNSV?blocks=hide これで良いと思います。 一律ならSaleテーブルに持たせますが、 個別なら今回いただいてる中間テーブルに持たせてしまうで良いと思います。 セールイベントごとに個別IDを持たせて、中間テーブルで紐づけるのが良いと思います。 ### 159.DBモデリング2で設計したテーブルについての疑問です。 (質問全文) https://airtable.com/tblA4yYGHwaqDYKwx/viwAUwNVsR9rOkW6u/recWVglgng1F1m67C?blocks=hide #### ① ある属性をイベントとして捉えて別テーブルに切り出すことの利点はどのようなものになるでしょうか? メリットは、リソースとイベントで分けるとモデリングしやすい。 今回は無理にイベントとリソースを分ける必要はいかなと感じました。 リソース:参照される側、所属(リソース同士が互いに参照することもある) イベント:参照する側 #### ② ユーザーがチャネルから脱退する場合は `UserJoinChannel` テーブルから該当レコードを削除する想定ですが、問題ないでしょうか? アプリケーションの仕様次第かと思います。 物理削除は、正しくモデリングができているのか注意が必要。 休会になっているだけではないか、復活する可能性は無いかなど。 (補足)より具体的なテーブル名にするのか、汎用的なテーブル名にするのか。 基本的には具体的なテーブル名にする。クエリはエイリアスで短くもできるため。 都度今後の拡張性を考慮するとかは基本的にはさける。どんなにアジャイルな開発でもDBは変更が入らないように、想定しうる今後の拡張性はテーブル設計の段階でしっかり考慮しておく。 UserJoinChannelテーブルだと、ユーザーが抜けた時の情報を保持するのは変かも。かといってUserLeaveChannelテーブルみたいな別テーブルで管理すると、最新状態を追いづらくなる。何かいい方法がないか。UserBelongChannelとかどうか。良さそう。 ### 160.ユーザーが自由に並び替えできるデータの並び順は、どのようにDBに保存するのが良いでしょうか? https://airtable.com/tblA4yYGHwaqDYKwx/viwAUwNVsR9rOkW6u/recu7Oiy67urRqLQC?blocks=hide 設定系は事前にどのような設定になるか分からないのがポイント そもそもRDBで実現するか ・RDBを使用する場合  ① 設定ごとにカラムを増やしていく  (Trelloなどでは不可能、ユーザごとに設定内容が殆ど同じ場合だけ使用できる)   → 推奨しない  ② アンチパターン(Entity Attribute Value)を敢えて使う   → 推奨しない ③ JSON型のカラムに入れてしまう → RDBならこれが良いと考える ・ドキュメントDB(MongoDB等)を使用する場合   → RDBへの参照をもち、実体はドキュメントDBで管理 ※この場合、ドキュメント系DBのデータが消えてもRDB上消えていないなどの不整合が出る可能性あり 松原さんとしては、RDB且つJSONでもつ 並び順自体をどう言う風に持つのが良いか Trelloでは間に差し込みやすいように敢えて大きい数字を振っていると推測