43テーブルのDB設計をしてみて思った、DB設計する上で認識しておくべきこと。ちゃんと設計することで、シンプルなSQLクエリだけで開発できるようになる。
覚えておいたほうがいいこと
- テーブル名は複数形にする
- IDをidにしない
- NOT NULL制約
- UNIQUE制約
- 外部キー制約
- テーブルをちゃんと分ける
- UUID / ULID
- カラムを無駄に増やさない
- 予備カラムを設定しない
テーブル名は複数形にする
以下のようにusers
やdepartments
など複数形にして名前を決定する。
CREATE TABLE users ( username VARCHAR(50) NOT NULL password CHAR(36) NOT NULL department_id CHAR(36) NOT NULL solt CHAR(36) NOT NULL PRIMARY KEY (username) FOREIGN KEY (department_id) REFERENCES departments (department_id) )
CREATE TABLE departments ( department_id CHAR(36) NOT NULL department_name VARCHAR(50) NOT NULL PRIMARY KEY (department_id) )
IDをidにしない
IDのカラム名をidにしない。user_id
、role_id
など。○○_idにする。
例外として、独自にコーディング規約がid
として付けると記載があるならコーディング規約に従う。
NOT NULL制約
なるべくNULL値を入れない。
UNIQUE制約
重複バグがおきない。DISTINCTが必要ない。データ追加(INSERT)時ラク。
WHERE句での条件一致で役に立つ。無駄なSQLを発行しなくてよい。
INSERT INTO calender (date) VALUES ('2022-12-25');
個人的にはUNIQUE制約が一番好き。
外部キー制約
複数の箇所にデータ(文字列など)を保存しない。idを付けて外部キーを設定する。
テーブルをちゃんと分ける
テーブル構造(カラム)が同じになっていてもテーブルを分ける。
UUID / ULID
UUID、ULIDを使う。むやみにAUTO INCREMENTしない。
カラムを無駄に増やさない
わざわざ年月日を分けているテーブル。意味ない。
CREATE TABLE calender ( date DATE NOT NULL UNIQUE -- 日付 year VARCHAR(4) NOT NULL -- 年 month VARCHAR(2) NOT NULL -- 月 day VARCHAR(2) NOT NULL -- 日 PRIMARY KEY (date) )
SELECT concat(year, '/', month, '/', day) FROM calender; -- 結果: 2022/12/25
これだけ。クエリで対応すべき。
CREATE TABLE calender ( date DATE NOT NULL UNIQUE -- 日付 PRIMARY KEY (date) )
SELECT DATE_FORMAT(date, %Y/%m/%d) FROM calender; -- 結果: 2022/12/25
予備カラムを設定しない
いつ使うかも分からない予備のカラムを設定しない。その都度ALTERを使って対応すること。
/* データ型、制約も不明な予備1、予備2。とりあえずVARCHAR(255)設定 運用後、予備1が数値だけのデータだったらVARCHARで運用? */ CREATE TABLE calender ( date DATE NOT NULL UNIQUE -- 日付 reserve1 VARCHAR(255) -- 予備1 reserve2 VARCHAR(255) -- 予備2 PRIMARY KEY (date) )
予備を設定している時点で設計がちゃんとできていない証拠。だいたい文字列型で設定しがち。不安だからで設定してはいけない。無駄は省こう。
予備が本当にほしいなら、どんな用途で使用するか?など、ちゃんと要件を確定して具体的なカラム名と型を決めること。