LCL Engineers' Blog

夜行バス比較なび(高速バス比較)・格安移動・バスとりっぷを運営する LCLの開発者ブログ

Railsアプリケーションで採用しているDBスキーマ設計ガイドライン

Webエンジニアの森脇です。 Railsアプリケーションで採用しているDB設計(スキーマ定義)について紹介します。

※ Railsでは当たり前もの、Railsに依存していない内容も含んでいます。

前提

環境違えば、採用するルールも異なると思いますので、まずは弊社で利用している環境を記載します。

  • DBはPostgreSQL 9.x
  • 開発言語は、Rails 4.x,5.xを利用

命名ルール

Railsの規約に沿う命名を採用しています。DB設計にこだわりがあるメンバーにとっては、異論があるルールもあるのですが、アプリケーション開発の生産性も考慮しRailsの規約に寄り添うのがよいと判断をしました。

テーブル

  • 動詞は使用せず、名詞とする
  • 複数形とする
  • 1:n のテーブル名は「単数形_複数形」 とする
  • n:n のテーブル名は「複数形_複数形」とする

カラム

  • カラム名にテーブル名のprefixは付与しない
    • usersテーブルのユーザ名は「user_name」ではなく「name」とする
  • 主キーは、idとする
  • 外部キーは、「JOIN先のテーブル名(単数系)_id」とする
  • boolean型は、true/falseが自明な名称にする
    • xxxx_flagなど、true/falseの意味が自明ではないため利用しない
    • is_xxxxやcan_xxxxなどの明確な名称にする
  • 時間を記録するカラムは 受動態on、受動態atとする
    • DATE型は「受動態_on」 とする
    • TIMESTAMP型は「受動態_at」とする

インデックス

  • 原則、Railsのmigrationでの自動生成ルールに任せる
  • 自動生成で桁数オーバーする場合は、idx_<テーブル名>_on_<カラム名>をベースとして収まるように適宜調整

型もRailsのMigrationから生成される標準の型を利用しています。

数値

  • 整数
    • 特別な理由がない場合は、integerを利用する
  • 浮動小数
    • 特別な理由がない場合は、numericを利用する
    • numeric とdecimalは同一のため使い分け不要

文字列

日付

  • dateを利用する

時刻

  • timeを利用する

日時

  • timestampを利用する

制約など

データ整合性を担保するための制約は、極力利用する方針としています。

外部キー制約

使用する

  • テストデータ作成が若干手間なのは否めないが、不整合があるデータを作ってしまい結局ハマることもあるので、DB側でガードしたい
  • SQLで直接データ修正する場合も考慮すると、アプリケーションだけでのデータチェックでは不十分

ユニーク制約

使用する

  • DB側で、データ整合性を担保するため

NOT NULL制約

付与可能なカラムには、必ず付与する

  • DB側で、データ整合性を担保するため
  • 既存テーブルへのカラム追加の場合は、以下の手順をとる
    • NOT NULL 制約なしでカラム追加
    • 該当カラムに値を設定
    • NOT NULL 制約を追加

デフォルト値

利用しない

  • デフォルト値に頼らず、アプリケション側で明確な意図を持って設定したい

Check制約

利用しない

  • 複雑なチェック条件は、Check制約では対応できないため、利用しても中途半端になると判断

ON DELETE CASCADE

利用しない

  • データの削除は、アプリケーション側で明確にコントロールしたい

最後に

以前はレビューの都度、制約などのあるべき論を議論をしてしまい、レビューに時間がかかってしまっていました。ガイドラインを整備することでチーム内の意識統一が容易になり、より本質的なレビューができるようになりました。