テーブル構成を考える時に重視すべき点

エキサイト株式会社のAです。 今回はデータベースの構成を考える上で、特に重視すべき点を事例を用いて紹介します。

アクティブか否かのフラグや表示非表示の状態を極力カラムで管理しない

事例として、enabled_flgという記事データが有効か無効かを表すフラグがカラムに存在していました。 しかし、後から有効無効以外にも「許可非許可」以外にも「未承認」の状態が欲しいと言った要件が発生しました。

その時には既にテーブルのデータが増えすぎておりカラムの追加も容易にできなくなっていたため、 当時の担当はenabled_flgカラムを「0:未承認 1:許可 -1:非許可」と言った状態にしてフラグ管理カラムに複数の意味を持たせてしまい 非常に運用もしづらく、分かりづらい作りになっていました。

1テーブルに載せるカラム数は極力少なくしておかないと、後々テーブルのデータが肥大化して行った時に データ量が多すぎて簡単にalter tableを流すことができない状態にもなりかねません。

カラムを追加しすぎて肥大化したテーブルの例

これを防ぐためにはカラムにenabled_flg や active_flgなどは極力付けずに、activeテーブルなどを用意してテーブル別に管理するようにします。 上記の事例で言うと、表示非表示はactiveテーブルで管理しつつ、承認か未承認かの状態も承認用の管理テーブルを用意します。

そうすることで一つ一つのテーブル構成がシンプルになり、新たな要件が来た時も簡単に拡張を行うことができます。 また、テーブルのカラムに複数の意味を持つことがなくなるため、後に他の人が見たとしても理解しやすくなります。

注意点としてはテーブルの数が多くなりがちなため、しっかりと命名規則を決め見やすくする必要があることと、 JOINのコストは発生するためINDEXの付け方や各テーブルにいれるカラム数などはケースに合わせて工夫する必要はあります。

コメントを必ずつける

当たり前のことではありますが、テーブルを作る際に各テーブルがどのようなテーブルなのか、各カラムがどのようなカラムなのかを必ず記入しましょう。 コメントがないと後々DBの運用する人が変わった際に、どのカラムが何に使われているか分からなくなることが多くなります。

上記を踏まえた例

CREATE TABLE `information_seq` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `info_code` varchar NOT NULL,
  `infoday` date NOT NULL,
  `infoseq` tinyint(4) unsigned NOT NULL DEFAULT '1',
  `sort_order` tinyint(1) unsigned NOT NULL DEFAULT '1',
  `version` tinyint(1) unsigned NOT NULL,
  `opt_var1` varchar(10) DEFAULT NULL,
  `opt_var2` varchar(10) DEFAULT NULL,
  `opt_int1` int(10) unsigned DEFAULT NULL,
  `opt_int2` int(10) unsigned DEFAULT NULL,
  `insert_time` datetime NOT NULL,
  `update_time` datetime NOT NULL,
  `active_flg` tinyint(1) unsigned NOT NULL DEFAULT '1',
...

上記の例で言うと、infodayinfoseqがどのようなデータなのかこれを見ただけでは全く検討もつきません。 また、opt_var1opt_int1と言った状態もカラムで持ってしまっており、尚且つコメントもないためこちらもどのようなデータかわかりません。 そのためコメントは必ず追加し、状態を持つ場合はテーブルを分けることで非常にシンプルになり機能の実装や改修が早くなります。

終わりに

コメントなどは惰性で書いたりして軽視しがちですが、プロジェクトに新規で人が入った場合などでも明らかに開発効率がよくなるため、シンプルなDB構成は重要です。