質問: 現在Djangoをつかってwebアプリを作っている途中なのですが、以下の状況で質問をしたいです(Djangoに関係なくテーブル設計の仕方についても質問があるのでそこだけでもよろしくお願いします)。 アプリのデータとして、ユーザーが読んだ本を入力してもらいたいのですが、現状は入力フォームが、 読んだ本の数 _ 冊 とまず入力するところがあって入れた数だけ ◯ ジャンル ____ ◯ 読んだ時期 ___ 月 という入力フォームが冊数分出てくるという風になっています。 ここでこの入力フォームに入力されたデータをデータベースに保存したいのですが、今は次のように考えて保存しようとしています。 * キー : ユーザーID, 整数 * 読んだデータ : '(ジャンルA, 5月), (ジャンルB, 7月)', 文字列 といった感じで読んだ本のリストを文字列にして保存しようとしています。 つまり、ユーザーの入力したいくつかの本のデータをまとめて文字列にして1つのデータとして保存しようと考えています。 ここで以下の質問をしたいです。 * そもそもデータベースのテーブルの設計の仕方(文字列にして1つに押し込んでしまう)でいいのか。こういうユーザーによってデータの量が変わる場合はどうしたらいいのか。 * もし上記の設計にしたとして、入力フォームでバラバラに入っているデータをDjangoの汎用ビューで保存できるのでしょうか(CreateViewを使おうとしましたが、素のCreateViewだとそ入力フォームのままバラバラに保存してしまいます)。 また、上記では本にしていますが、実際は本ではなく、データの性質として、 ユーザー1 に対して 複数の (選択肢から選ばれるデータ, 整数) といった形のデータが紐づくものとなっています(データの数は多くても10程度です)。上では本を例にして質問を書きました。 拙い内容で申し訳ないのですが、2つの質問のうちどちらかで良いので、ご教授よろしくお願いします。
回答: Djangoには詳しくないのでテーブル設計について。 テーブル設計に絶対の正解というものはありませんが、私ならこうします。 ``` 冊数テーブル ( ユーザID 整数 PRIMARY KEY, 冊数 数値 ) 読書詳細テーブル ( ユーザID 整数 PRIMARY KEY, 連番 整数 PRIMARY KEY, ジャンル 文字列, 読んだ時期 整数 ) ``` `読書詳細テーブル.連番`は、1ユーザが複数の本を登録した場合に1, 2, 3, ... と連番を振ってキーにします。 ジャンルが手入力じゃなく選択式なのだとしたら、ジャンルマスタテーブルも作ってジャンルCDで紐づけるような感じです。 また、場合によっては`冊数テーブル`はなくてもいいです。 > > 入力フォームが冊数分出てくる > > > ということなので、これがもしすべて必須入力なのだとしたら`読書詳細テーブル.ユーザID`をキーにしてcountを取得すれば冊数が取得できます。(任意入力なのだとしたら冊数は別で保存する必要がありますが) テーブル設計は、システムに必要になるデータを全部洗い出し、「正規化」していくことで整理していきます。 「正規化」にも第一から第三までレベルがあり、どのレベルまで正規化して設計するかはどういう使い方をしたいかで変わってきます。 絶対に第三正規形にしなければならないというわけではありませんし、そこまで極端にやると正直とても使いづらいデータベースになることも多いです。 ただ、ひとつ言えることは、複数の文字列を連結して1カラムに詰め込み、使うときはまたバラして使うというのは、あまりオススメしません。