データベース 設計

観光地紹介サービスを作るの要件を読み取り、サービスに必要なテーブルを設計します。
なお、ユーザー登録に必要なテーブルは Laravel が生成するものを利用するため、設計する必要はありません。

テーブルを設計する

要件をもとに、データを分類してみましょう。
新規登録画面で考えてみましょう。
まず、登録するデータを列挙します。

  • 観光地名
  • 観光地画像
  • 住所
  • サイト URL
  • 電話番号
  • 紹介文

次に、それぞれのデータをどういう形で保存するのかを考えます。

  • 観光地名
    • 文字列
  • 観光地画像
    • ファイルを BLOB として保存?
    • ファイルのパスを文字列で保存?
    • 履歴はどうする?
  • 住所
    • 文字列
    • 都道府県や市町村、番地や郵便番号は一緒に登録していいの?
  • サイト URL
    • 任意登録なので、入力されていない場合は何を保存するのか?
  • 電話番号
    • どういう形式で保存するのか?
      • 000-0000-0000 とか 00000000000 とか
  • 紹介文
    • 最大文字数は何文字に設定するか

データの持ち方が決まったら、今度はデータを表で表現できるかを確認します。
大雑把に定義すると、

  • 行と列がある
  • 列には名前(データの項目名)が付けられている
  • ヘッダー以外の行には列名に対応したデータが設定されている
  • 1セル(行列が交わるマス目)につき1つのデータが設定されている

になると思います。
では、新規登録画面のデータを表で表現してみます。

id 観光地名 画像 住所 URL 電話番号 紹介文
1 貴船神社 image.png, image2.png 京都府京都市左京区 http://kifunejinja.jp/ 075-741-2016 とても綺麗なところです

上記は画像列が1セルに対して1つのデータという条件を満たしていません。
ではどうすればいいでしょうか。
画像列以外のデータが全く同じな行を作ってみます。

id 観光地名 画像 住所 URL 電話番号 紹介文
1 貴船神社 image.png 京都府京都市左京区 http://kifunejinja.jp/ 075-741-2016 とても綺麗なところです
2 貴船神社 image2.png 京都府京都市左京区 http://kifunejinja.jp/ 075-741-2016 とても綺麗なところです

これで表としては正しくなりました。
ですが、このままでは問題があります。
例えば、URL が http から https に変わったとします。
当然登録されている URL も変更しなければいけません。
ここで問題になるのは、情報としては同一なのにも関わらず、2行変更しなければ整合性を保てないところです。
この例では2行だけですが、画像履歴がどんどん増えていった場合、またそれが複数データに及んだ場合、管理が煩雑になるだけではなく、パフォーマンスも悪くなってしまいます。

この問題を解決するためにはどうすればいいでしょうか?
解決方法としては、画像履歴テーブルを作るという方法が簡単かつ妥当でしょう。

観光地テーブル

id 観光地名 住所 URL 電話番号 紹介文
1 貴船神社 京都府京都市左京区 http://kifunejinja.jp/ 075-741-2016 とても綺麗なところです

画像履歴テーブル

id 画像
1 image.png
2 image2.png

最新画像テーブル

id spot_id (観光地テーブルの ID) history_id (履歴テーブルの ID)
1 1 2

画像履歴テーブルにはアップロードされた画像の履歴を持ち、観光地テーブルから画像列を削除、最新画像を保存するテーブルを作成して、観光地と画像履歴の識別子をペアで保存することで、データがいくら変更されようが、1行のみの更新で済むようになりました。
また、画像データが10増えようが、100増えようが、観光地テーブルには影響は出ません。
このように、データの一貫性の維持と効率的なデータアクセスを可能にする設計を正規化と呼びます。
正規化にもいくつか段階があり、第5正規化までありますが、特殊な場合を除き、第3正規化までで必要十分です。
上記の例では、第1正規化を行いました。

この例を参考に、サービスに必要なテーブルを設計してみましょう。

results matching ""

    No results matching ""