95481


最終的にやりたいこと  
・QAサイトで、質問者が回答者の中からベストアンサーを 1 件だけ選択できるようにしたい  
・ベストアンサーが選択されたQAページでは、複数回答の内、ベストアンサーを一番最初に表示したい

知りたいこと  
・A.選択したベストアンサーを、どういうDBカラム構成で保存するか  
・B.ベストアンサーを一番最初に表示するにはどうすればよいか

Aに対する案  
qテーブルにBOOLEAN型のbest_answerカラムを追加して、回答者がそのレコードを選択したら、trueを格納  
他に良い案はありますか？  
※一般的にはどういう実装になるか知りたい。

Bに対する案  
ベストアンサーだけをDBから取得して表示するだけなら問題ないと思われるのですが、回答を全件取得してベストアンサーだけを最初に表示する、というのはどう実装すればよいですか？  
複数カラムの単純な並べ替えではないので、order byでは無理ですか？

環境  
・MySQL  
・PHP


CC BY-SA 4.0
2023-06-12T15:28:33.313
95191
2023-07-05T11:08:18.687
2023-07-05T11:08:18.687
3060
7886
question
mysql データベース設計
QAサイトで、(1件だけ選択できる)ベストアンサーを実装したい時のDBカラム構成について


前提として，「質問テーブル」と「回答テーブル」が 1 : n で存在することとします．

# A について

案としては 3 つで，一つは既に挙げて頂いている「回答レコードに best_answer フラグを付ける」です．  
もう2つは

  * 別途 best_answers テーブルを作り回答テーブルと紐付ける
  * 質問テーブルに best_answer_id を作り回答テーブルと紐付ける

## best_answer フラグ案

一番ありがちな実装だと思いますし実現はできますが，ベストアンサーが変わったときにちょっとめんどくさいと思います．

  1. 質問 ID に紐づく回答の中から既に best_answer になっているやつを探してきてフラグを消す
  2. 新たに別レコードに best_answer フラグを立てる

というフローになるかと思います．

## best_answers テーブル案

最初は質問に対してベストアンサーが一つという制約があるため， Unique Key 制約などで制御して 1 : 1
になるようにする必要がありますが，（あるかどうか分かりませんが）将来的にベストアンサーを複数選べるようにしたいなどの変更に強いと思います．もしくは「最新 1
件」という取り方をすることで見せ方としてベストアンサーを 1 つにすることも可能です．  
また，ベストアンサーに対して負荷情報を追加したくなったときにも簡単に実装できると思います．  
ただし，管理するテーブルが1つ増えますし，join なども必要になってくるので実装は若干めんどくさいかもしれません．  
テーブルを分けておくと，ベストアンサーに選ばれた履歴がトランザクション的にそのまま保存できるのが便利かなと思います．（ただし要件的に必要ないのであまりこの時点で考えるべきことではないですね）

## 質問テーブルに best_answer_id 案

割りとこれが良い落とし所かなと思っています．  
テーブル分割ほど拡張性はありませんが，「質問に対してベストアンサーが一つ」という制約も簡単に満たせますし，ベストアンサーの変更も id
の更新だけで済みます．

# B について

これは A でどれを選択するかによって若干変わってしまいますが，一旦「best_answer フラグ案」で回答します．  
この場合， bool 型の best_answer カラムに対して降順で並べかえすれば true なカラムが上に来ますのでそれで大丈夫かと思います．


CC BY-SA 4.0
2023-07-05T09:31:32.853
95481
2023-07-05T09:31:32.853
58973
95191
answer