LoginSignup
348
389

More than 3 years have passed since last update.

【初心者向け】データベースのテーブル設計で僕が意識している6つのこと

Last updated at Posted at 2020-09-22

はじめまして、himakuroです。

2017年ぐらいからQiitaに記事を投下しようと考えていたのですが、なかなか筆が乗らずようやく初投稿です:relaxed:

軽く自己紹介をしておくと、普段は社内SEとしてPHP、Ruby、Golangを書いたり、
趣味の個人ブログ方ではプログラミング初心者に向けた記事や雑記的なものを書いたりしています。

今回は記念すべき1つ目の記事と言う事で
僕が普段テーブル設計(主に命名)で気をつけている6つの事を書きました。

僕の好みも含まれていますが、初心者の方がテーブルやカラム名を決める際の参考になればなと思います。

テーブル名は必ず複数形にする

テーブルは一つしかないから単数形を使うべき!
Modelも単数形で定義するじゃん!

みたいな反論が聞こえてきそうですが、僕は複数形で定義する派です。

また複数形にする場合に、テーブル名の途中の部分を複数形にしている物をたまに見かけますが、僕は末尾を複数形で統一するのが好きです。

x user_bank
x users_bank
o user_banks

Railsで開発をしている方は、僕と同じ様に末尾が複数形の方が好きという人が多い(はず?)

カラム名のsuffixとして_idを無闇に使わない

suffix(サフィックス)とは user_idpost_id で言う _id の部分を指しています。
要は末尾に付ける物ですね。

そしてこの _id は、他テーブルの主キーを指すのに利用して行きたいので 
categoriesテーブルが存在しないのに、 category_id をpostsテーブルに追加するなんて事はしません。

また命名規則としては テーブル名(単数形)_id で統一するのがおすすめです。

x categories_id
x id_category
o category_id

同じものを指すカラムは型を統一する

※ コメントでご指摘を頂いたため2020-09-24に内容を更新しました

1つ前の内容に少し関連しているのですが
他テーブルのauto incrementなid列と関連付けるための
テーブル名(単数形)_id カラムを定義する際には型はunsignedのbigintで統一しています。

理由としてはRailsやLaravelなどでauto incrementのid列を定義すると, id はunsigned bigintになるからです。

本来ならカラムの型はどのようなデータが入るかを意識した上で選定するべきですが
フレームワークを使っていると自動で型が確定するものがあり、今回の内容がそれに該当します。

自動で型が確定するカラムは実際にどのような型になっているかを確認するのを疎かにしがちで、
今まで携わったLaravelやRailsのプロジェクトでも、 auto incrementな他テーブルのidを参照する xxx_id をbigintではなくintで定義しているのを多数見てきました。 

xxx_id に限らず同じ意味を持つカラムは同じ型で定義するように意識していきましょう。

履歴テーブルはhistory、ログテーブルはlog

履歴テーブルとログテーブルって何が違うの?

と聞かれたら僕は

履歴テーブルは画面に表示して ユーザー(利用者)に見せるもの
ログテーブルは エンジニア(開発者)などが調査に使用するもの

と答えます。

また命名に関しては、例えばゲーム開発などでユーザーがゲーム画面で閲覧する事が出来るプレゼント履歴用のテーブルを作る場合は user_present_histories と名付けます。

ユーザーからアイテム消えたんだけど?みたいなお問い合わせが来た場合に、エンジニアが調査が出来るようにユーザーのアイテム利用ログを残しておく場合は user_item_logs と名付けます。

人によっては historylog をprefix(プレフィックス)として先頭に持って来る方もいると思いますが、この辺りは好みかなと思います。

o user_item_logs
o log_user_items

booleanのカラムはひと目で分かるようにする

型がbooleanのカラムはひと目でわかるように
is_ can_ has_ の様なprefixを付けるようにしています。

例: is_active, has_owner

こうすることで、これらのカラム名を見ただけで
型がbooleanであることが推測でき、更にtrueやfalseなどの値が入っていた時に
何を意味するのかが明確になります。

ちなみに型がbooleanで check_xxx の様なカラムをたまに見かけますが
これでは true の場合にはチェックが必要なのか、それともチェックが終わっているのかが明確ではないので、booleanのカラム名として check はおすすめしません。

日付を保持するカラムの命名方法

日付を保持するカラムを命名する際に finish_at にするか finished_at にするかで迷ったことはありませんか?

これを迷わなくするためには カラムで保持するデータが未来を指すのか、過去のものを指すのか を考慮すると良いです。

過去形を使わない例

例えばゲーム開発でイベント情報を持つテーブルがあり、そのテーブルにはイベント開始時刻と、終了時刻を持つカラムがあるとします。

イベントの開催情報は事前告知するのが一般的であり、イベント開始時刻と終了時刻には未来の時間を保持することになります。

よって、カラム名も過去形にはせずに start_atfinish_at の様に命名をしていきます。

過去形を使う例

続いて過去形で命名をする場合を見ていきます。

user_quests と言うユーザーのクエスト情報を管理するテーブルがあり、そこにはユーザーがクエストを開始した時刻と終了した時刻を保持するカラムがあるとします。

これらのカラムにデータが入るのはユーザーがクエストを開始した時、終了した時なので、データとしては過去の時間を指していることになります。

よってカラム名は started_at finished_at のように過去形で命名をします。

レコードの作成時間や更新時間を保持するカラムとして created_atupdated_at などがあると思いますが、これらのカラムのデータも作成された時間、更新された時間を保持するので過去形ですね。

テーブルの設計って大変

一般的にテーブル設計って聞くと、正規化とかパフォーマンスを意識したインデックスの貼り方とか難しい事ばかりを意識しがちですが、それ以前にテーブル名やカラム名を意識するのも大切だよというのを伝えたかったのでこの記事を書きました。

これが正解と言うわけではありませんが、テーブル名やカラム名はとても重要なので
ネーミングセンスが無いから適当につけよ…とは思わずに、しっかりと考えて命名をするようにしましょう。

初投稿 完

348
389
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
348
389