命名規則のベストプラクティス
同じ「利用者の ID」が、あるテーブルでは user_id、別のテーブルでは userId、さらに別のところでは uid と書かれている。JOIN を書くたびに定義を確認しに行く数十秒が、チームの人数ぶん毎日積み上がります。
どちらが正しいかではなく、そろっていない
命名の話は「複数形にすべきか」「is_ を付けるべきか」で止まりがちですが、現場で実際に困るのはそこではありません。困るのは混ざっていることです。users と order_item が同じスキーマに並んでいると、テーブル名を書くたびに単数か複数かを思い出す必要が出ます。どちらの流儀でも、全部そろっていれば思い出す必要はありません。
決め方そのものに正解はありません。決めたら全部そろえる。これだけが本質です。迷うなら、使っているフレームワークや ORM の既定に寄せておくと、ライブラリ側の想定と衝突しません。
混ざったスキーマを、1 つの流儀に寄せる
書き方が混ざった定義です。
SQL クエリ
CREATE TABLE Customer (
CustomerID INT PRIMARY KEY,
customerName VARCHAR(100),
RegDate TIMESTAMP,
isActiveFlg BOOLEAN
);テーブル名は単数、列名は大文字始まりと小文字始まりが混在し、RegDate と Flg は書いた人以外に読めません。ここでは「テーブルは複数形、語はすべて小文字で下線区切り」と決めた場合の姿を出します。
SQL クエリ
CREATE TABLE customers (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR(100) NOT NULL,
registered_at TIMESTAMP NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT TRUE
);テーブル名に customer が入っているので、列を customer_name にする必要はありません。customers.name で十分に伝わります。
中身を言っていない名前と、予約語を置かない
避けたいのは data info flag value のような、何が入っているか言っていない名前です。作った直後は分かっていても、3 か月後に開くと中身を見ないと判断できません。is_active なら真偽値、registered_at なら日時だと名前だけで読めます。型と意味が名前から読めるかどうかが、そろえるときの実際の基準になります。
もう 1 つ、予約語は避けます。order user group key は使いたくなりますが、SQL の構文語と衝突します。
SQL クエリ
CREATE TABLE order (id INT);
-- 構文エラーになる DB がある
-- "order" と囲めば通るが、以後すべてのクエリで囲み続けることになるorders にしておけば、この面倒は最初から発生しません。
名前は本番に出た瞬間、改名のコストが跳ね上がります。アプリのコード、バッチ、BI のクエリ、ダッシュボードまで追いかけることになるので、テーブルを作る前の 5 分がいちばん安く直せるタイミングです。
テーブル構造
CREATE TABLE column_metadata (
id INT PRIMARY KEY,
table_name VARCHAR(50) NOT NULL,
column_name VARCHAR(50) NOT NULL,
data_type VARCHAR(20) NOT NULL
);
INSERT INTO column_metadata VALUES
(1, 'users', 'id', 'BIGINT'),
(2, 'users', 'email', 'VARCHAR'),
(3, 'users', 'createdAt', 'DATETIME'),
(4, 'orders', 'id', 'BIGINT'),
(5, 'orders', 'UserID', 'BIGINT'),
(6, 'orders', 'total_amount', 'DECIMAL'),
(7, 'products', 'ProductName', 'VARCHAR'),
(8, 'products', 'price', 'DECIMAL'),
(9, 'reviews', 'id', 'BIGINT'),
(10, 'reviews', 'rating', 'INT');期待される出力
| table_name | column_name |
|---|---|
| users | createdAt |
| orders | UserID |
| products | ProductName |