toke04 / ruby-flash-card

3 stars 0 forks source link

データ設計 #22

Closed toke04 closed 1 year ago

toke04 commented 1 year ago

現在のDB構造(2023/11/08時点)

スクリーンショット 2023-07-14 10 17 46

users

No 論理名称 物理名称 データ型 PK UQ NN 備考
1 id id integer ユーザーのid
2 ユーザーid uid string Githubのuser_id
3 ユーザー名 name string Githubのユーザー名
4 画像url avatar_url string Githubのアバター写真
5 管理者 admin boolean 管理者の場合、ruby_methodsへのアクセス権全てが手に入る。
一般ユーザーは閲覧 & 操作不可
6 登録日 created_at datetime
7 更新日 updated_at datetime

ruby_modules

No 論理名称 物理名称 データ型 PK FK UQ NN 備考
1 id id integer
2 モジュール名 name string rubyのモジュールの名前。
rubyではクラスもモジュールに含まれる
3 登録日 created_at datetime
4 更新日 updated_at datetime

ruby_methods

No 論理名称 物理名称 データ型 PK FK UQ NN 備考
1 id id integer
3 モジュールid ruby_module_id integer rubyのメソッドは、どれかのモジュールに紐づく
2 メソッド名 name string メソッドの名前。
4 公式サイトのurl official_url string 公式サイトのURLを貼る。自動で入るようにする
5 登録日 created_at datetime
6 更新日 updated_at datetime

user_ruby_methods

No 論理名称 物理名称 データ型 PK FK UQ NN 備考
1 id id integer
2 user_id user_id integer usersテーブルのidを持つ。中間テーブルとしての役割
3 ruby_method_id ruby_method_id integer ruby_methodsテーブルのidを持つ。中間テーブルとしての役割
4 説明 memo text 紐づいているrubyのメソッドの説明をする
5 覚えた remembered integer integerだが、メソッドを覚えたかどうかの管理フラグ。
3択で管理する
0: not_yet (未着手)
1: yes (覚えた)
2: no (覚えてない)
6 登録日 created_at datetime
7 更新日 updated_at datetime
toke04 commented 1 year ago

[初期バージョン]

スクリーンショット 2023-06-26 18 44 33

users

No 論理名称 物理名称 データ型 PK UQ NN 備考
1 id id integer ユーザーのid
2 ユーザーid uid string Githubのuser_id
3 ユーザー名 name string
4 画像url avatar_url string
5 登録日 created_at datetime
6 更新日 updated_at datetime

methods

No 論理名称 物理名称 データ型 PK FK UQ NN 備考
1 id id integer
2 user_id user_id integer nameとのユニークな組み合わせにする
3 言語 language integer メソッドは、どれかの言語に属する。
languagesテーブルは作らず、
選択肢はモデルでenumで持たせる
4 メソッド名 name string user_idとのユニークな組み合わせにする
5 動作内容 operation_detail text
6 使用ケース use_case text
7 覚えた remembered boolean メソッドを覚えたかどうかの管理フラグ
8 公式サイトのurl official_url string 公式サイトのURLを貼る
9 登録日 created_at datetime
10 更新日 updated_at datetime
yuuu commented 1 year ago

@syo-tokeshi 確認しました 👍 ミニマムな仕様という意味ではこのテーブル設計で実現できそうです。以下は気になった点です。

toke04 commented 1 year ago

Rubyだとメソッドはクラスに属していますし、同じメソッドでもクラスが変わると仕様も変わりますが、このあたりはどう表現されるのでしょうか? メソッド名に Array#map のように入力する想定でしょうか? クラスというテーブルを作るのもアリかもしれません。一方、他言語ではクラスに属さないメソッド(関数)という概念もあるので悩ましいところです。

はい、ここはユーザーに任せようと思っており、Array#mapのように入力してもらう事も可能です😊、という形にしようと思います🙇‍♂️

メソッドに対して「クラスの選択を必須にする」を導入すると、気楽さが減って良くない気がしました。

例えば、each_with_indexはクラスではなく、Enumerableモジュールで定義されているメソッドですし、メソッドを登録する時に、「これはどこのクラス or モジュールのメソッドか」を意識させると勉強にはなるのですが、登録するのが億劫になる気がするので、ユーザーに任せようと思います🙇‍♂️

toke04 commented 1 year ago

複数のユーザーが同じ名前のメソッドを登録した場合も、DBとしては別のレコードを表す認識であっていますか?

はい!🙇‍♂️ 気づいておりませんでした、、🙇‍♂️ めちゃくちゃ大事ですね、、🙇‍♂️

ユニークインデックスは user_id と メソッド名 の複合インデックスにするようにします🙇‍♂️

マイグレーションファイルを発行する際に、以下を記入します

class CreateMethods < ActiveRecord::Migration[7.0]
  def change
    create_table :methods do |t| 
       ~~略~~
       t.index [:user_id, :name], unique: true

今回は「やらない」という判断でも良いですが、ユーザー間でメソッドに対して記述した内容を共有できると面白いなーと思いました

はい、実はその機能を、ファーストリリースの後に実装しようと思っています🙇‍♂️

GET /users/1/methodsのような形でアクセスしたら、ユーザー1の登録したメソッド一覧が確認できて

という機能を作る可能性があります🙇‍♂️

ただ、ファーストリリースでは、基本的にこのままで行こうと思ってます🙇‍♂️

toke04 commented 1 year ago

@yuuu お疲れ様です。 methodsテーブルにofficial_urlというカラムを追加します🙇‍♂️

理由とつきまして、

というのを考えまして、追加します🙇‍♂️ NULLを許容します(登録しないケースもあると思うので)

スクリーンショット 2023-06-26 18 44 33
No 論理名称 物理名称 データ型 PK FK UQ NN 備考
1 id id integer
2 user_id user_id integer nameとのユニークな組み合わせにする
3 言語 language string メソッドは、どれかの言語に属する。
languagesテーブルは作らず、
選択肢はモデルでenumで持たせる
4 メソッド名 name string user_idとのユニークな組み合わせにする
5 動作内容 operation_detail text
6 使用ケース use_case text
7 覚えた remembered boolean メソッドを覚えたかどうかの管理フラグ
8 公式サイトのurl official_url string 公式サイトのURLを貼る
9 登録日 created_at datetime
10 更新日 updated_at datetime
toke04 commented 1 year ago

お疲れ様です。 methodsテーブルにcategory というカラムを追加したいです🙇‍♂️ 以下でよろしいでしょうか?

No 論理名称 物理名称 データ型 PK FK UQ NN 備考
1 id id integer
2 user_id user_id integer nameとのユニークな組み合わせにする
3 言語 language string メソッドは、どれかの言語に属する。
languagesテーブルは作らず、
選択肢はモデルでenumで持たせる
4 カテゴリー category string メソッドが何かのカテゴリーに属する、という概念を表す。
[例]
find_by: ActiveRecord
fileter : Array
each_with_index : Enumerable
5 メソッド名 name string user_idとのユニークな組み合わせにする
6 動作内容 operation_detail text
7 使用ケース use_case text
8 覚えた remembered boolean メソッドを覚えたかどうかの管理フラグ
9 公式サイトのurl official_url string 公式サイトのURLを貼る
10 登録日 created_at datetime
11 更新日 updated_at datetime
スクリーンショット 2023-06-27 12 22 27
toke04 commented 1 year ago

画面はそれに伴い、以下のようなUIに一部が変更されます https://bootcamp.fjord.jp/products/16181

スクリーンショット 2023-06-27 12 27 25

スクリーンショット 2023-06-27 12 27 56

スクリーンショット 2023-06-27 12 28 22

スクリーンショット 2023-06-27 12 28 54

toke04 commented 1 year ago

カテゴリーの機能は、 reactのtagifyのライブラリを使って実装する予定です https://codesandbox.io/s/tagify-react-wrapper-3m31v?file=/src/index.js

whitelistに、DBに保存されているmethod.categoryの値を利用し、入力補完を実現します。

サジェストは、1文字目の入力から候補を提案するようにします

dropdown: {
      enabled: 1 // a;ways show suggestions dropdown
    }
toke04 commented 1 year ago

また、methodsテーブルが

を持っている事がおかしいのであれば、以下のようにテーブルを分割しようと思います

スクリーンショット 2023-06-27 13 24 19

質問

分割するのと、分割しないの、どちらが良いと思いますか?

以下のようなメリット&デメリットがあると考え、 分割しないほうを選んだ方が良い気がしています🙇‍♂️

[分割するメリット]

[分割するデメリット]

toke04 commented 1 year ago

@yuuu お疲れ様です。 少し設計を見直して、このような設計にしたいのですがよろしいでしょうか?

新しいER図

スクリーンショット 2023-07-10 18 35 33

users

No 論理名称 物理名称 データ型 PK UQ NN 備考
1 id id integer ユーザーのid
2 ユーザーid uid string Githubのuser_id
3 ユーザー名 name string Githubのユーザー名
4 画像url avatar_url string Githubのアバター写真
5 管理者 admin boolean 管理者の場合、ruby_methodsへのアクセス権全てが手に入る。
一般ユーザーは閲覧 & 操作不可
6 登録日 created_at datetime
7 更新日 updated_at datetime

ruby_methods

No 論理名称 物理名称 データ型 PK FK UQ NN 備考
1 id id integer
2 メソッド名 name string メソッドの名前。
違うクラス or モジュールで、同名メソッドがあるので、
nameとcategoryの組み合わせをユニークにする
3 カテゴリー category integer メソッドは、どれかのカテゴリーに属する。
categoriesテーブルは作らず、
選択肢はモデルでenumで持たせる
4 公式サイトのurl official_url string 公式サイトのURLを貼る。自動で入るようにするのでユニーク
5 登録日 created_at datetime
6 更新日 updated_at datetime

user_ruby_methods

No 論理名称 物理名称 データ型 PK FK UQ NN 備考
1 id id integer
2 user_id user_id integer usersテーブルのidを持つ。中間テーブルとしての役割
2 ruby_method_id ruby_method_id integer ruby_methodsテーブルのidを持つ。中間テーブルとしての役割
2 動作説明 description text 紐づいているrubyのメソッドの説明をする
7 覚えた remembered boolean メソッドを覚えたかどうかの管理フラグ
8 登録日 created_at datetime
9 更新日 updated_at datetime
toke04 commented 1 year ago

なぜテーブル名を変更したくなったかと言いますと、

私が用意した

が最初から作られているメソッドに対して、ユーザーが説明を加えて、クイズする

というアプリの仕様に変更したくなったからです🙇‍♂️

説明

管理者用のrubyのメソッドを登録する画面があり、私がこの画面から、メソッドを登録していきます(登録したらruby_methodsテーブルにデータが入る)

[index画面には登録したメソッド一覧と、新しいrubyのメソッドを登録するボタンが設置されている] スクリーンショット_2023-07-10_17_19_11

[新しくメソッドを追加する所で、管理者である私はカテゴリーとメソッド名のみを入力] スクリーンショット 2023-07-10 17 24 52

スクリーンショット 2023-07-10 17 24 30

[登録すると自動でURLが生成される] スクリーンショット 2023-07-10 17 27 13

[一般ユーザーの、rubyメソッド一覧画面 http://localhost:3000/user_ruby_methods] スクリーンショット 2023-07-10 17 29 30

[管理者(私)が登録したメソッドに対し、ユーザーが説明を入れる] スクリーンショット 2023-07-10 17 30 51

[リンクを踏むと公式に飛べる。ユーザーは正しい情報を確認しながらメソッドを覚えられる] スクリーンショット 2023-07-10 17 31 46

[登録したメソッドをユーザーはクイズで確認できる http://localhost:3000/ruby_quiz/new] スクリーンショット 2023-07-10 17 34 58

[クイズの設定画面 http://localhost:3000/ruby_quiz/new] スクリーンショット 2023-07-10 17 30 51

[先ほどユーザーが登録したメソッドをクイズで確かめることができる] スクリーンショット 2023-07-10 17 36 49

[「回答を見る」ボタンを押すと、このように前回の答えと、公式のリンクがあり、確かめることが出来る。 また、今回の内容の方が良かったら「内容を更新する」ボタンで更新できる。 また、「おぼえた!」ボタンを押すとおぼえた!に移動し、復習モードで復習できる。] スクリーンショット 2023-07-10 17 39 00

toke04 commented 1 year ago

補足

ユーザーが登録するrubyのメソッドの扱いについて

サービスリリース時、いくつかのメソッドを私の方で

等を使い、データを流し込む予定です🙇‍♂️

また、サービスが継続していく中で、定期的に私の方で、

事によってメソッドを追加しようと思っています🙇‍♂️

[rails_admin_importのメソッドをcsv形式でインポートできる画面] スクリーンショット 2023-07-10 17 52 37

toke04 commented 1 year ago

@yuuu お疲れ様です。 町田さんと話し合った結果、最終的にこのような設計になりました。 よろしいでしょうか?

新しいER図

スクリーンショット 2023-07-12 22 19 18

users

No 論理名称 物理名称 データ型 PK UQ NN 備考
1 id id integer ユーザーのid
2 ユーザーid uid string Githubのuser_id
3 ユーザー名 name string Githubのユーザー名
4 画像url avatar_url string Githubのアバター写真
5 管理者 admin boolean 管理者の場合、ruby_methodsへのアクセス権全てが手に入る。
一般ユーザーは閲覧 & 操作不可
6 登録日 created_at datetime
7 更新日 updated_at datetime

ruby_methods

No 論理名称 物理名称 データ型 PK FK UQ NN 備考
1 id id integer
2 メソッド名 name string メソッドの名前。
違うクラス or モジュールで、同名メソッドがあるので、
nameとcategoryの組み合わせをユニークにする
3 カテゴリー category integer メソッドは、どれかのカテゴリーに属する。
categoriesテーブルは作らず、
選択肢はモデルでenumで持たせる
4 公式サイトのurl official_url string 公式サイトのURLを貼る。自動で入るようにするのでユニーク
5 登録日 created_at datetime
6 更新日 updated_at datetime

user_ruby_methods

user_ruby_methods
No 論理名称 物理名称 データ型 PK FK UQ NN 備考
1 id id integer
2 user_id user_id integer usersテーブルのidを持つ。中間テーブルとしての役割
2 ruby_method_id ruby_method_id integer ruby_methodsテーブルのidを持つ。中間テーブルとしての役割
2 説明 memo text 紐づいているrubyのメソッドの説明をする
7 覚えた remembered integer integerだが、メソッドを覚えたかどうかの管理フラグ。
3択で管理する
0: not_yet (未着手)
1: yes (覚えた)
2: no (覚えてない)
8 登録日 created_at datetime
9 更新日 updated_at datetime
yuuu commented 1 year ago

@syo-tokeshi 見直しありがとうございます。いくつか確認させてください。

toke04 commented 1 year ago

ruby_methods の category という名前はどこかで使われている名前でしょうか?

はい!使っておりました🙇‍♂️

ここはModuleまたはClassが該当すると思っていて、Ruby的にはClassもModuleなのでここは module という名前が適切なのかなと推測していました。

かしこまりました🙇‍♂️ categoryからmoduleという名前に変更します🙇‍♂️

ruby_methods の category は enum で管理するとのことですが、将来的に扱うクラス名が増えた場合はコードを修正するということでしょうか?

はい、その運用を想定しておりました🙇‍♂️

ここもテーブルにして、画面上から追加・削除できるようにする余地を残しておいた方が良い気がしています

こちらなんですが、 [本番環境にデプロイする際]

  1. テーブルにする -> 初期のcategoryのデータはseedファイルで最初に作成(ruby_methodsテーブルと依存関係にあるのでcategoryをデータを作らないと、ruby_methodsテーブルのデータを挿入できない)。
  2. enumにする -> webの画面上から追加・削除できないが、
    • seedで流し込む必要がない
    • 今回のアプリではあくまで「よく使うRubyのメソッド」に限定するので、そこまでcategoryが増えない

といった条件なのですが、それでもテーブルを作成して管理した方が良さそうでしょうか? 私自身は「enumにした方が簡単そうだ」と考えているのですが、どうでしょうか?

今回は

みたいなもののみを想定しているので、クラス自体へのリンクは想定していないです🙇‍♂️ yuuuさんの認識と違ってますでしょうか?😀

user_ruby_methods に「覚えた日」を表すカラムは不要でしょうか?

「覚えた日」の概念をアプリで使う予定が今の所ないです🙇‍♂️

  1. クイズの選択条件
  2. メソッド一覧の絞り込み機能

でも、「覚えた日」の概念は今の所いらなそうだなーと思ってます。 また、ユーザー自身も「メソッドを覚えた日」というのを知ることにそこまで旨みがない気がしてます🙇‍♂️

スクリーンショット 2023-07-13 10 43 15 スクリーンショット 2023-07-13 10 43 28
yuuu commented 1 year ago

@syo-tokeshi 回答ありがとうございます。

それでもテーブルを作成して管理した方が良さそうでしょうか? 私自身は「enumにした方が簡単そうだ」と考えているのですが、どうでしょうか?

「今は仕様を最小限にしているから、このテーブル設計でもイケる」という判断はデータ設計をする上で本末転倒に感じました。「良いデータ設計」とは「仕様変更が発生しても対応しやすいテーブル構造」であり、ここではそれを目指している認識です。

自分はenumにした方が簡単とは思えないです。懸念点を列挙しますね。

「覚えた日」の概念をアプリで使う予定が今の所ないです🙇‍♂️

こちらは承知です。万が一必要となったとしてもカラムを増やすだけなので、こちらは現時点で追加しなくても大丈夫です 👍

toke04 commented 1 year ago

@yuuu

「良いデータ設計」とは「仕様変更が発生しても対応しやすいテーブル構造」であり、ここではそれを目指している認識です。

理解しました🙇‍♂️ 今回は、enumをテーブルに変更して作成します🙇‍♂️

を考えると、テーブルで最初に作るのが無難そうですね😊 作った後に見える世界もあると思うので、それを楽しみにしつつテーブルにします😊

toke04 commented 1 year ago

新しいデータ設計を貼ります

新しいER図

スクリーンショット 2023-07-14 10 17 46

users

No 論理名称 物理名称 データ型 PK UQ NN 備考
1 id id integer ユーザーのid
2 ユーザーid uid string Githubのuser_id
3 ユーザー名 name string Githubのユーザー名
4 画像url avatar_url string Githubのアバター写真
5 管理者 admin boolean 管理者の場合、ruby_methodsへのアクセス権全てが手に入る。
一般ユーザーは閲覧 & 操作不可
6 登録日 created_at datetime
7 更新日 updated_at datetime

ruby_modules

No 論理名称 物理名称 データ型 PK FK UQ NN 備考
1 id id integer
2 モジュール名 name string rubyのモジュールの名前。
rubyではクラスもモジュールに含まれる
3 登録日 created_at datetime
4 更新日 updated_at datetime

ruby_methods

No 論理名称 物理名称 データ型 PK FK UQ NN 備考
1 id id integer
3 モジュールid ruby_module_id integer rubyのメソッドは、どれかのモジュールに紐づく
2 メソッド名 name string メソッドの名前。
4 公式サイトのurl official_url string 公式サイトのURLを貼る。自動で入るようにする
5 登録日 created_at datetime
6 更新日 updated_at datetime

user_ruby_methods

No 論理名称 物理名称 データ型 PK FK UQ NN 備考
1 id id integer
2 user_id user_id integer usersテーブルのidを持つ。中間テーブルとしての役割
3 ruby_method_id ruby_method_id integer ruby_methodsテーブルのidを持つ。中間テーブルとしての役割
4 説明 memo text 紐づいているrubyのメソッドの説明をする
5 覚えた remembered integer integerだが、メソッドを覚えたかどうかの管理フラグ。
3択で管理する
0: not_yet (未着手)
1: yes (覚えた)
2: no (覚えてない)
6 登録日 created_at datetime
7 更新日 updated_at datetime
yuuu commented 1 year ago

修正ありがとうございました 🙏 データ設計も問題なさそうです!