blog 開発

【全然ダメ】テーブル定義書のレビューが返ってきた!

こんにちは、すずきです。
テーブル定義書のレビューが返ってきたので、反省と学んだこと、テーブル定義書の必ず必要なものを再度おさらいしていきます!

テーブル定義書とは

すずき

テーブル定義書とは、データベース内の各テーブルの情報をまとめたもの!

▶︎▶︎要件定義(タスク管理アプリ)
▶︎▶︎テーブル定義書の書き方

上記が前回書いたテーブル定義書になります。
かなり指摘があったので、前回のテーブル定義書も比較しながら書いていきます。

上記が作成したテーブル定義書になります。
まずご指摘内容を見てみましょう。

ご指摘

ユーザーTBL

  • ユーザー名は入れないんですね?
  • DATE型で形式YYYY-MM-DDは本当に可能ですか?

タスクTBL

  • タスク名は、画面から入力するんですよね?タスクの名前として
  • 状態の「処理済み」はどういう時に使いますか?(実際のシーンを教えてください)
  • 期限表示用のガントチャートは、基本的に開始予定日と終了予定日を図示すると思いますが、今回は開始予定日が「開始日」で終了予定日が「期限日」としていますか?
  • データとして、タスクの終了日(=完了日)は不要ですか?

全体

  • 登録日時、更新日時を入れてください
  • 論理削除フラグは不要ですか?
  • 今のテーブル定義ですが、ユーザーAさんでログインしてタスクを登録した後、ユーザーBさんでログインしてタスク登録する流れがあると思います。
    ここ場合、登録されたタスクがどのユーザーのものかきちんと分けられるようになっていますか?
すずき

全体的に修正を行いました!そこで、大事なポイントを紹介していきます!

【指摘1】DATE型で形式YYYY-MM-DDは本当に可能ですか?

このレビューですが、最初何が悪いのか正直わかりませんでした。

結論から言うと、これ答えはyyyy/MM/dd」形式にしなければいけません。なぜyは小文字でMは大文字dは小文字にしなければいけないのか下記引用をご覧ください。

日時パターン

日時フォーマットは日時パターン文字列で指定されます。日時パターン文字列内では、引用符で囲まれていない'A' - 'Z'および'a' - 'z'は、日付または時間文字列のコンポーネントを表すパターン文字として解釈されます。テキストは単一引用符(')で囲むことで解釈を回避できます。"''"は単一引用符を表します。ほかのすべての文字は解釈されず、フォーマット中に出力文字列へ単純にコピーされるか、解析中に入力文字列に対して一致させられます。

次のパターン文字が定義されます(ほかの'A' - 'Z'および'a' - 'z'のすべての文字は予約済み)。

文字日付または時刻のコンポーネント表示
G紀元テキストAD
y199696
Y暦週の基準年200909
M年における月(状況依存)JulyJul07
L年における月(スタンドアロン形式)JulyJul07
w年における週数値27
W月における週数値2
D年における日数値189
d月における日数値10
F月における曜日数値2
E曜日の名前テキストTuesdayTue
u曜日の番号(1 =月曜、...、7 =日曜)数値1
a午前/午後テキストPM
H一日における時(0 - 23)数値0
k一日における時(1 - 24)数値24
K午前/午後の時(0 - 11)数値0
h午前/午後の時(1 - 12)数値12
m数値30
s数値55
Sミリ秒数値978
zタイムゾーン一般的なタイムゾーンPacific Standard TimePSTGMT-08:00
ZタイムゾーンRFC 822タイムゾーン-0800
XタイムゾーンISO 8601タイムゾーン-08-0800-08:00
クラスSimpleDateFormat

これをみてもらったら分かるとおり、まったくといっていいほどに意味が変わってしまいます。
そのため、形式は必ず「yyyy(年)/MM(年における月(状況依存))/dd(月における日)」形式に揃えましょう。

【指摘2】登録日時、更新日時を入れてください

すずき

うわ、忘れてたタスクのテーブルに追加しよ!

と思いタスクテーブルにだけ追加したら、「あと、登録日時、更新日時は基本的に必ず入れるもので、そしてこういうものは一般的な書き方等あります。」とのご指摘をユーザーテーブルにもいただきました。「なぜ必要なのか」が腑に落ちてなかったので調べてみました。

登録日時、更新日時が必要な理由

  • ユーザーのデータがいつ作成され、いつ変更されたかを追跡するため
  • 不正アクセスや変更の検出が簡単になるから
  • 古いデータを利用して誤った判断をするリスクが減るから
  • 何か問題が発生した場合、登録日時と更新日時を参照することで、問題の発生時期や原因を特定しやすくなる

上記が主な理由ですね。例えば今回はユーザーテーブルについてですが、どの時期にユーザーが増えているかが後で見たときにわかりやすいなどの利点があります。

なので基本は、登録日時と更新日時は追加します。

created_atとupdated_atを使おう

登録日時と更新日時の物理名は、「created_at」と「updated_at」です。
基本的には、この物理名を使用しましょう。

【指摘3】論理削除フラグは不要ですか?

すずき

論理削除フラグって何??

まず存在すらも知りませんでした。なので、しっかり勉強していきましょう。

論理削除フラグとは

論理削除フラグとは、テーブルから特定の行を"論理的に"削除することを表すフラグなんです。
もっと簡単な言い方をすると、削除したテーブルを履歴に残す機能のことです。

ちなみに物理削除の意味と論理削除の違いは以下です。

削除方式意味
物理削除ハードディスクなどの記憶媒体から当該行のデータを削除すること
論理削除当該行が削除されたことをデータとして表現することで削除されたものとみなすこと
(=データは記憶媒体に残ったまま)
1分でわかる論理削除 -メリットとデメリットを考える-

削除方式は理解できたと思います。なんで論理削除が必要なのか。その理由を見ていきましょう。

論理削除が必要な理由

論理削除が必要な理由は

  • ユーザーからは非表示にしたいが、残しておきたいデータがある場合
  • 間違って削除してしまってもすぐに復元できるようにしたいから

上記2つのようなケースがほとんどです。
タスク管理とかでも間違って消しちゃったものが、すぐ復元できなかったらかなりストレスです。なので、そういった面でも論理削除フラグは、登録日時・更新日時の用に記載する必要があります。

【指摘4】登録されたタスクがどのユーザーのものか分別できていますか?

これは、まったく考えれていませんでした。基本的には、多数の方がアプリを使う前提で作らなければいけないのにその意識が足りていませんでした。
下記が修正版です。ユーザーIDをタスクテーブルにも追加しました。変更点は、論理名を「登録ユーザーID」に変更とFKに◯をつけました。

ちなみにPKとFKは下記です。

PK・FK

PK(Primary Key)は、テーブル内の各レコードを一意に識別するためのカラムです。PKは必ず一意であり、Null値を取ることはできません。FK(Foreign Key)は、他のテーブルとのリレーションを定義するためのカラムであり、データの整合性を保つために使用されます。

【基本設計】テーブル定義書の書き方

簡単にいうと、他のテーブルの特定の列と関連付けるためのものと思っていてください!
ここで重要なのが、物理名です。
ユーザーテーブル(users)ではユーザーIDを「id」と表記し、関連付けするタスクテーブルの登録ユーザーIDを「users_id」という表記にしてFKに丸をつければOKです!

修正後のテーブル定義書

上記の修正をし、テーブル定義書を作成しました!こちらで一度Rv依頼してみます!

ぜひ皆さんもテーブル定義書を作成する際に確認してみてください!
また記事にご指摘があればぜひお願いします!鈴木の勉強の励みになります!

  • この記事を書いた人

鈴木陽介

現役Javaエンジニア

2000年生まれ

もうすぐ書籍を出版します。

-blog, 開発