blog.osa.in.net

テーブル名は単数形で良いのではないか

2023-05-14

2,736文字

背景

多くのフレームワークや ORM でテーブル名を複数形にするという規約が採用されているが、実は単数形の方が良いのではないかと思い始めたので雑にメモ。

念のために書いておくと、複数形のテーブル名を前提とするフレームワークや ORM を使っている環境でも単数形にするべきだという話ではない。

いくつかの論点

テーブルという概念

「テーブルはレコードが複数集まっているものだから複数形の方が自然」という論がある。

users には user が複数含まれている」が自然なのはわかるが、テーブルというのは基本的に複数行あるものなので「user テーブルには user が複数含まれている」とすればテーブル名が単数形でも大きな問題はないように感じる。

また、少し違う例になるが、この種の意識の切り替えは User クラスと user インスタンスで日頃からやっているはずなので、一見同じ名前である user テーブルと user レコードを区別するのもそれほど不自然ではない気がしている。

ただ、このあたりの英語の感覚の微妙な違いとなると正直わからない。

単複変換の困難さ

単数形と複数形の相互変換がただただ単純に難しく、規則変化・不規則変化・単複同形・不可算名詞など、単数形と複数形の相互変換を考えたときに考慮すべきことが多すぎる。

不可算名詞も含めて一律で複数形にするべきかというと疑問が残るし、不可算名詞としての意味がある単語でも意味によっては可算名詞であることもあって単複どちらにすべきかは字面からは定まらない。

また、index の複数形は意味によって indexes と indices の2種類があるなど、単数形から複数形への変換自体も字面からは一意に定まらないことすらある。

適切な変換を定義することがあまりにも困難だし、そういった相互変換をおこなうためのコードや知識をメンテする労力が果たして割に合うものなのか疑問に感じている。

命名時の単複判断の難しさ

テーブル名を命名する際に、ある単語が複数形になるのかどうかの判断が難しい。

わからないときはもちろん辞書を引いて調べるわけだが、概念自体は不可算名詞であるものの、個々の事例については可算名詞になるケースなども多く、命名の際に単数形にするか複数形にするかの判断をするのが難しい。 個人でも難しいのでチームで揃えるのはもっと難しい。

クエリの自然さ

SQL の中で複数登場する table_name.column_name という形式において、複数形テーブル名だと users.id といったようにコレクションに対してカラムの呼び出しをしているように見える。単数形テーブル名だと user.id と自然に呼び出せる。

とはいえ、現実的なクエリではテーブルに別名をつけると思うので、この点についてはどちらでも良いのかもしれない。

-- 複数形(現実的なクエリ)
select
    u.id
  , u.name
from
    users u
;

予約語との衝突

SQL や RDBMS の予約語には、テーブル名を単数形にすると容易に衝突しそうなものがいくつかある。 網羅的ではないし RDBMS によっても異なるが、たとえば以下のようなものがある。

  • CAST
  • GROUP
  • LIKE
  • ORDER
  • TRANSACTION

この観点では単数形よりも複数形のほうが衝突しにくいと言える。

ただ、テーブル名を複数形にした場合でも、以下のような単語は予約語に含まれているため依然注意が必要ではある。

  • REFERENCES
  • VALUES

したがって、根本的な対策としては、

  • テーブル名は "" などで囲う
  • テーブル名は単語ではなく2単語以上にして衝突を避ける
    • group ではなく user_group にするなど
    • 衝突する可能性は下がるが、SESSION_USER とかとぶつかる可能性は残る

などをおこなうしかない。

事例

気になって調べたのでまとめておく。パラパラと見ただけなので、各事例の中で例外などもあると思う。

PostgresQL ドキュメント

films, distributors あたりの複数形テーブル名が基本だが、measurement という単数形のテーブルも存在している。
https://www.postgresql.jp/document/14/html/sql-createtable.html

MySQL ドキュメント

users, tournament など単複両方ある。ただ、全体としては mytable, t1 など抽象的な記述が多い。
https://dev.mysql.com/doc/refman/8.0/ja/select.html

『プログラマのためのSQL 第4版』

単数形・複数形ともに使われている。ひとつのクエリの中で StudentsGradebook が登場するなど、意図的に両方使っているようにも見える。
https://amzn.to/3pBSnp8

『SQLアンチパターン』

Products, Bugs など基本的に複数形で書かれている。
https://amzn.to/41yYPKS

『理論から学ぶデータベース実践入門』

orders, order_summary, course_registration など単数形・複数形ともに登場する。
https://amzn.to/3nTtt3R

『達人に学ぶDB設計 徹底指南書 初級者で終わりたくないあなた』

サンプルコードは「社員」など日本語で書かれている。
https://amzn.to/42QHM7Y

ただし、p.71 に

たとえば、先ほどのテーブルの例なら「Employees」、商品を集めたテーブルなら「Items」、注文履歴であれば「Orders」など、すべて複数形で書ける、ということです。

と書いてあるので、主に複数形のテーブル名を想定していると思われる。

『SQL and Relational Theory』

T, P など無味乾燥な名前が並んでいる。
https://amzn.to/3M6XQvw

おわりに

「テーブル名は単数形で良いのではないか」という考えについて書いてきた。

現時点で「単数形であるべきだ」とまでは思っていないが、単数形・複数形のどちらにするかの判断や相互変換の難しさを抱えてまで複数形にしたい気持ちがなくなってきているというのが正直なところ。

手触りを確かめるために、テーブル名を単数形にしたデータベースを実際に運用してみようと思っている。