0131NAME IS NULL2023/05/22(月) 11:19:17.69ID:???>>127 ベストな設計なんて世の中に存在しないから ベターな設計で開発を始めたほうが良いのは至極当たり前のことなんだけど 何を持ってベターな設計と判断するかという判断基準を持ち合わせてないはどうしようもないよね 持ち合わせてたら>>123のような質問しないでしょ?
勉強用の架空の要件に対する設計であっても 考えうる選択肢を出してみてそれぞれどういうメリット・デメリットがあるのかを 自分なりに細かい要件を想定しながらしっかり考えないと設計能力はつかないよ 0132NAME IS NULL2023/05/22(月) 11:20:12.26ID:???>>130 そうそうこういう項目をどう管理するかのほうがDB設計的には重要だったりするよね 0133NAME IS NULL2023/05/22(月) 12:17:34.06ID:??? 試しにChatGPTに設計サンプル出してもらったら概ね>>124の形で出てきた 要件をもっと細かく伝えればたたき台としてなら実用可能なものを作ってくれそう
Users: user_id(PK), username, email, password, other user-related fields MembershipRanks: rank_id(PK), rank_name, rank_description, annual_fee RankConditions: condition_id(PK), rank_id(FK to MembershipRanks), condition_description, min_purchases RankBenefits: benefit_id(PK), rank_id(FK to MembershipRanks), benefit_description, increased_points, discount_percentage, free_shipping_enabled UserMembership: user_id(FK to Users), rank_id(FK to MembershipRanks), acquired_date, expiration_date 0134NAME IS NULL2023/05/22(月) 13:31:32.85ID:??? 言うほど>>124と一緒か? >>129が言うように会員に会員ランクを定義するのとも違うし、 ベストとかベターの前に色々ありすぎて答えなんて出ないだろ 0135NAME IS NULL2023/05/22(月) 14:10:47.79ID:???>>134 >言うほど>>124と一緒か? ほぼ一緒でしょ Usersテーブルが>>123の会員テーブルで UserMembershipが>>123の会員ランクテーブルに相当 特典、加入条件はランクテーブル(MembershipRanks)とは別テーブル管理にして 年会費だけランクテーブルに組み入れてる
といっても俺は124じゃないから124の意図した内容が俺の理解と違ってたら知らんけど 0136NAME IS NULL2023/05/22(月) 14:12:37.98ID:??? users:id(PK),rank_id(FK),name ranks:id(PK),name,annual_fee,min_purchases,discount_percentage user_ranks:id(PK),rank_id(FK),acquired_date, expiration_date
■会員のランクを取得 SELECT users.name,ranks.name FROM users INNER JOIN ranks ON users.rank_id=ranks.id
■会員ランクが有効なユーザーを取得 SELECT users.name FROM user_ranks INNER JOIN users ON user_ranks.user_id=users.id WHERE acquired_date <= '2023-05-22' AND expiration_date >= '2023-05-22'
■特定の会員(user_id:1)への特典を取得 SELECT ranks.discount_percentage FROM ranks INNER JOIN users ON ranks.id=users.rank_id WHERE rand_id='1'
■そのランク(rank_id:1)になる条件を取得 SELECT annual_fee,min_purchases FROM ranks WHERE rand_id='1'
これで良くないか?SQLの実行数も少ないし、わかりやすいと思うんだが。 user_ranksはログみたいな扱いにして、最新のレコードをinsertした後に usersのrank_idをupdateすればJOIN回数も減るし、サブクエリも必要ない。 0137NAME IS NULL2023/05/22(月) 14:34:27.93ID:???>>136 ビジネスルールや運用次第でそれで良い場合もあれば良くない場合もある 主にusers.rank_idをどのタイミングでどう更新するかという問題 お金を払うタイミングと会員ランクを変更するタイミングを常に一致させるようなルールならそれでも可 じゃなければシステム停止してバッチで更新みたいなことが必要になるから普通はDB設計を変える 0138NAME IS NULL2023/05/22(月) 14:55:13.80ID:??? ポオントサイトだと夜間バッチが普通だと思う 購入額合計が基準値越えたからってランクがその場で上がった経験は無いな 0139NAME IS NULL2023/05/22(月) 15:12:49.13ID:??? 夜間バッチに、参照テーブルみたいなのを用意するのが普通だと思うが。 >>133だと常にUserMembershipを判定しなければいけないし、排他ロックもかかる。 >>136だとユーザー情報にランク情報を紐づけているわけだから、 同時に更新するタイミングはない。 お金を払うタイミングで現在のランクを参照できるわけだから、 お金を払ってる時にランクが変わるという問題もない 0140NAME IS NULL2023/05/22(月) 15:22:45.15ID:???>>138 それはバッチで更新されてるかのように見えてるだけでしょ 0141NAME IS NULL2023/05/22(月) 15:24:47.54ID:???>>137 たとえば販売管理なら月次のテーブルをもって特定月の売上金額や入金額なんかを持つことがある ランク付けが月毎に確定するような話なら上の例と同じように特定月のランクがどうなるかを持つような話じゃないかと思う なので実際のテーブル設計は要件をふまえてするわけだし ここはそういうスレだから「じゃあこんな場合はどうだろう」とかいろいろ話を膨らませてもいいと思うけど 攻撃的なやりとりはできる限りないほうがいいんじゃないかねぇ 0142NAME IS NULL2023/05/22(月) 16:09:37.41ID:???>>141 >ランク付けが月毎に確定するような話なら ランク付けが基本的に年単位で確定するような話をしてるんだから同じでしょ 0143NAME IS NULL2023/05/22(月) 16:16:29.57ID:???>>139 >>>133だと常にUserMembershipを判定しなければいけないし、排他ロックもかかる。 排他ロック?はよくわからないけど必要なロックがかかったところで何か問題がある?