何かを開発するにあたり、DB設計についてのインプットが甘かったためここに再度メモ書きとして残しておく。
この記事は開発する前に行なっておくべきことを備忘録としてまとめ、初学者である自分や周りの方の助けになることが目的です。
開発(コード書く)前にDB設計しろ
「〇〇が作りたい」
「これを開発してみたい」
と思わず手を動かしてしまうんですが、まずはDB設計をした方がいい。
なぜかというと、
進めていくうちに沼にハマるから。
「あれ、ここはどうしよう?」
「いまどこのエンティティに対しての実装を行なってるの?」
と迷子になってしまって僕はコードを書き進められませんでした。
まずはDB設計を行いましょう。
DB設計は家を建てる時の設計図に他なりません。
図面がないとプロの職人でも、
「これはどこの柱だっけ?」
と一々思案する必要がでて時間を消費します。
どういう順番がいいのか
- エンティティの抽出と定義
- 正規化
- ER図の作成
細かく行うと、仕様書の作成から要件定義と行なっていく必要があり、RailsならどんなGemを使うべきか考える必要が出てくるでしょう。
ただ、初心者のうちにそれらを盤石に固めてしまおうと頑張ると工数(時間)が余計にかかってしまい時間の浪費へとつながってしまいます。
※僕は時間を浪費しました( ・∇・)
なのでざっくりと、
まずは形になるものを作って、要所要所で追加していっても大丈夫だと思うんですよね。
もちろん、実際の業務で行うときにそれが通用するかと言われると難しいし、余計な手間となってしまうので避けた方がいいと思います。
ただ、初学者のうちは
「どうやったらこれが作れるのか」
という小さな成功体験が早い段階で必要だと感じます。
プログラミング学習は沼ることが多く、挫折する原因にもなりうるので早い段階で手を動かす方がいいと個人的に感じますし、インプット学習を長時間し続けても結局忘れてしまう。
一番はインプット(学習)とアウトプット(成果物)のバランスが良好な経験を生む。
そもそもエンティティってなんだっけ?
エンティティは開発しようとしているシステムのためにどんなデータ(エンティティ)が必要かを明記したものだと考えます。
別の言い方だと「テーブル」。
例えばECサイトなら
「ユーザー」「商品」「管理者」などがエンティティと表現できるでしょう。
作りたいもののざっくりとした仕様書や要件定義を決めたら、
そのエンティティが「何」を示したものなのかを細かく細分化する必要が出てきます。
まずはエンティティを考え、次に「どんなデータを保有しているか(属性)」について思案します。
属性とはなんぞや
属性とはエンティティに含まれているデータのことをいいます。
例えば、「商品」エンティティには何が含まれているかを考えた時ざっくりと以下の内容が思いつくわけです。
エクセルで商品に関するテーブルを作ると想定すると以下のようになるとします。
例)商品テーブル(エンティティ)
商品ID | 商品名 | 商品説明 | 価格 | 在庫 | 登録日 | 更新日 |
---|---|---|---|---|---|---|
1 | 〇〇 | これは〇〇です | 1,000円 | 10 | 2023/09/15 12:00 | 2023/09/18 12:00 |
上記のテーブルには「商品ID」「商品名」などの各カラム(列)ごとにタイトルが設定せれていてそれに沿った内容のデータが登録されています。
このカラムのタイトルが「属性(データ)」となります。
最初に触れたDB設計の順番では
エンティティの抽出と定義を掲げました。
つまり、どんなシステムを作ろうか目的が明確になれば必要なエンティティが何かもある程度把握できるというこですね。
開発経験のない初学者である僕や周りの方は詰まる時もあると思いますが、
まずは自分がどんなシステムを作る必要があり、そこにはどんなデータ(エンティティ及び属性)が必要かをリストアップしておくと開発に着手するときのスピード感が段違いだと思います。
ただ、より深くエンティティを細分化(正規化)するとなると「key」にも触れる必要があります。
主キーはなんであるか、外部キーは何かなど細かく設計を行わなくてはなりません。
正規化は必要か?
正規化はエンティティ(テーブル)を整理整頓する作業で、主にデータの更新(登録や削除)が整合的に行えるようにエンティティのフォーマットを整理することが重要な目的となっています。
単に開発しようとしているシステムに必要なエンティティの抽出と定義だけだと、このエンティティはシステムでの利用に適合した状態ではないことが多いです。
エンティティが冗長だとサーバーのストレージを圧迫し、レスポンスの低下を招いてしまう原因になります。
だから正規化を行なってシステムでの利用に適合した形へとエンティティを整理する必要があります。
正規化は第3正規形まで理解すれば十分
正規化のレベルは第5までありますが、第3正規形まで行えば十分とされています。
反対に、
「第3正規形までは理解しておく必要がある」
ともいえます。
そもそも正規形の定義はDBで保持するデータの冗長性を排除して、一貫性と効率性を保持するためのデータ形式のことを指しています。
第1正規形と非正規形
第1正規形の定義は
「1つのセルの中には1つの値しか含まない」
というルールがあります。
最もレベルが低い第1正規形を最初に行なって、次に第2→第3とステップを踏んでいく必要があります。
非正規形のままのエンティティでシステムを開発していこうとすると不要な冗長性の発生や一貫性を欠く設計でシステムを作ってしまうため非常に効率が悪く、
データの更新などで障害が発生するリスクが高まります。
エンティティの抽出と定義ができたら、まずは第1正規形を行いましょう。
第2正規形は部分関数従属を解消するもの
第1正規形でエンティティを正規化しても、
テーブルにおける関数従属が「完全」でないものを第2正規形では「完全関数従属」へと直していきます。
第3正規形で推移的関数従属を除外する
第2正規形でもまだ不十分とされており、エンティティをさらに分割していきます。
主な目的はエンティティのキー列に対してのみ非キー列が従属している状態へと持っていくのが主な目的となります。
例えば、商品テーブルだと「在庫」は商品テーブルに含めず、在庫テーブルを作成しデータの更新を効率よく行うことが可能となりそうです。
元々のテーブル↓
商品ID | 商品名 | 商品説明 | 価格 | 在庫 | 登録日 | 更新日 |
---|---|---|---|---|---|---|
1 | 〇〇 | これは〇〇です | 1,000円 | 10 | 2023/09/15 12:00 | 2023/09/18 12:00 |
商品テーブル
商品ID | 商品名 | 価格 | 商品説明 | 登録日 | 更新日 |
---|---|---|---|---|---|
1 | 〇〇 | これは〇〇です | 1,000円 | 2023/09/15 12:00 | 2023/09/18 12:00 |
在庫テーブル
在庫ID | 商品ID | 在庫数 | 登録日 | 更新日 |
---|---|---|---|---|
001 | 1 | 10 | 2023/09/15 12:00 | 2023/09/18 12:00 |
ER図
ER図はテーブル同士の関係性を表した図。
完璧でなくていいので、どんな関係性なのかをわかりやすくホワイトボードや紙などに書き出すと実装する時の目安になって便利です。
ER図を作ることのできるサービスはありますが、
Githubでポートフォリオの公開などを行うことも多いかと思います。
Diagramsというツールを用いるといいでしょう。
https://diagrams.mingrammer.com/
まとめ
開発を進める前にはDB設計をざっくりでいいので行なった方がよいことをまとめました。
DB設計がまったくできていないと実装スピードが雲泥の差が発生します。
実際、僕はDB設計をせず行き当たりばったりで実装を行おうとしたところ
DB設計を行なって着手した他の方に比べると大きなスピードダウンを感じました。
面倒でも最初にDB設計をおこなっておく方がよいと感じ、
初心に戻ってDB設計に必要な要素をざっくりとまとめてみました。
この記事が誰かの役に立てれば幸いです。