

会員制の学習支援サイトをcakephp2.7で作りたいのですが、具体的にどういうテーブル設計にすればよいかよくわかりません。

まず会員制なので会員テーブル(usersテーブル)でusernameカラムとpasswordカラムを用意。  
cookbookのチュートリアルにあるようにこの命名規則に従うと「ユーザーログインを 実装するにあたってほとんどのことを CalePHP
が自動的に設定します」ということでチュートリアルを進めた結果確かにログイン機能はできました。

次に、問題演習のための問題文テーブル(questionsテーブル)。  
カラムは問題IDカラム、q_body(問題文)カラム。  
この問題文テーブルに10問(10行)データが入っているとします。

やりたいことは、会員登録したユーザ毎の進捗度の管理です。

今考えているのは、ユーザ毎に進捗度テーブルを作って管理する方法です。  
進捗度テーブルには、問題IDカラム、1回目の結果を書き込むtry1カラム。2回目の結果を書き込むtry2カラム。…を用意するつもりです。  
ユーザーが、初めて問題1を解いたら進捗度テーブルの問題1の行のtry1カラムに結果を書き込む。  
ユーザーが、再び問題1を解いたら進捗度テーブルの問題1の行のtry2カラムに結果を書き込む。  
というようなことを実現したいです。

この場合会員1人につき進捗度テーブルを一つ用意することになると思うのですが、具体的にやるとなるとどうしていいかよくわかりません。

  1. 会員登録時にその人用の進捗度テーブルを作る方法。
  2. ①ができない場合、あらかじめ進捗度テーブルを連番でいっぱい作っておいて、会員登録した順に会員番号と進捗度テーブルを結びつける。

と、いうことも考えたのですが、いずれにしても会員番号とその人用の進捗度テーブルを結びつける方法が必要。  
つまり会員Aは会員A用進捗度テーブルには書き込めるが、他の会員用の進捗度テーブルには書き込めないような仕組みが必要。  
そのためには会員Aがログインした場合A用進捗度テーブルに書き込むためのフォーム(ページ)が表示されるようにする必要がある。  
これって会員制サイトのいわゆるマイページにあたるものだと思うのですが、どうすれば実現できるでしょうか？

とりあえずテーブル設計の考え方は上記の方針で問題ないでしょうか(これでやりたいことが実現可能でしょうか？)  
上記の方法では無理あるいは著しく非効率なので普通はこうする、みたいなのがあればお願いします。


CC BY-SA 3.0
2015-10-28T16:39:47.203
18184
2015-10-29T14:12:09.097
2015-10-29T07:40:05.967
7290
13018
question
cakephp データベース設計
会員制サイトのテーブル設計


進捗度テーブルは一つ作れば十分だと思います。私ならそうします。

進捗度テーブルに、ユーザーid（username）を格納するカラムを用意すればいいのです。  
（ユーザーidは会員テーブルの主キーだと思うので、進捗度テーブルからしたら、外部キーということになります。が、外部キーはデータベースエンジンによっては、必ずしも実装されているわけでもないので、それほどこだわる点ではないかもしれません。）

カラム構造としては以下の4種

[code]

    年月日時分秒，ユーザーid，問題番号，結果
    
[/code]

同じユーザーが同じ年月日時分秒で2問以上解けることは考えにくいので、年月日時分秒とユーザーidをセットにすれば、一意性のある primary key
として機能します。

* * *

リレーショナル・データベースでは、クエリー（検索）時に、テーブルの写像（部分集合）を取り出すことができるので、

> つまり会員Aは会員A用進捗度テーブルには書き込めるが、他の会員用の進捗度テーブルには書き込めないような仕組みが必要。

このようなことも、一つの進捗度テーブルで実現できます。一般的に DBMS では

[code]

    SELECT * FROM 進捗度テーブル WHERE username='ユーザー名';
    
[/code]

といったような SQL を使うなりする形になります。これにより、特定のユーザー名をもったエントリーのみの集合を結果として得ることができます。

SQL の`WHERE`句は CakePHP
なら[`find`](http://book.cakephp.org/2.0/ja/models/retrieving-your-
data.html)メソッドで渡すパラメーターで、`conditions` を設定することに相当すると思います。

* * *

ある問題を解いた回数も、同じユーザーの同じ問題に関するエントリーがいくつあるかをクエリーで調べることで足るので、特に、Try1〜TryNまでの項目を「カラムとして用意する」必要はありません。カラムにする設計だとむしろ柔軟性に欠けます。

* * *

CakePHP 自体は特に Web の UI
の部分をフレームワークとして提供してくれていますが、データベースに関する理解は前提条件として求められていると思います。suzukisさんが既にコメントで言及されているように、まずは
CakePHP
といった特定のフレームワーク・実装を扱う以前に、一度、リレーショナル・データベースについてせめて初級程度の勉強は別途済ませておくことをお勧めします。


CC BY-SA 3.0
2015-10-29T13:55:35.307
18211
2015-10-29T13:55:35.307
7290
18184
answer


cakeの問題ではなく、リレーショナルデータベース(RDB)の使い方のイメージが付いていないのだと思います。  
想定されているのは、以下のようなイメージですよね？

[code]

    UserA結果Table
      問題ID 1回目結果 2回目結果 3回目結果 …
      1      ng        ng        ok
      2      ok
      3      ng        ok
    
[/code]

[code]

    UserB結果Table
      問題ID 1回目結果 2回目結果 3回目結果 …
      1      ok
      2      ok
    
[/code]

まず、  
・ユーザ毎にtableを作るのは現実的では有りません。  
・n回目の結果のように回数が変わる可能性があるものをカラムとして用意するのも現実的ではありません。

RDBでは、正規化を行ってデータを効率良く格納する必要があります。  
※『DB 正規化』でググるとたくさん出てきます。

以下は、あくまで1つの例ですので、こうしなければならないというものではありませんので、参考として受け取ってください。

結果tableは以下のように定義します。

[code]

    結果テーブル
      ユーザID 問題ID 解いた回数 結果 実施日時
      A        1      2          ok   2015-10-29 12:59
      A        1      1          ng   2015-10-29 12:41
      B        10     1          ng   2015-10-29 12:01
      C        2      1          ok   2015-10-29 12:33
      A        2      1          ok   2015-10-29 13:15
      C        1      1          ok   2015-10-29 12:11
      C        3      1          ok   2015-10-29 12:41
    
[/code]

このようなtableを用意して、ユーザAの結果が知りたい場合は、ユーザIDが『A』のレコードだけ絞り込みます。※`where
ユーザID='A'`で以下のような結果が得られます。

[code]

    結果テーブル
      ユーザID 問題ID 解いた回数 結果 実施日時
      A        1      2          ok   2015-10-29 12:59
      A        1      1          ng   2015-10-29 12:41
      A        2      1          ok   2015-10-29 13:15
    
[/code]

更に、ユーザAの問題1の結果が知りたい場合は、ユーザIDが『A』で問題IDが『1』のレコードだけ絞り込みます。※`where ユーザID='A' and
問題ID='1'`で以下のような結果が得られます。

[code]

    結果テーブル
      ユーザID 問題ID 解いた回数 結果 実施日時
      A        1      2          ok   2015-10-29 12:59
      A        1      1          ng   2015-10-29 12:41
    
[/code]

上記のような実行結果を利用してやるのがRDBの使い方です。  
『RDB 選択』『RDB 射影』『RDB 結合』のようなキーワードでググッてみてください。

このようなRDBの使い方を理解してからcakePHPの勉強をしないと、どちらの勉強も進まないと思います。  
がんばってみてください。


CC BY-SA 3.0
2015-10-29T14:12:09.097
18212
2015-10-29T14:12:09.097
2383
18184
answer