ぱと隊長日誌

ブログ運用もエンジニアとしての生き方も模索中

データベースはレコード・フィールドではなく、行・列と表現すべき

概要

Joe Celko はデータベースにおいて、行 (row)・列 (column) という用語を使うべきであり、レコード (record)・フィールド (field) という表現は適切でないと主張しています。これは論理的存在と物理的存在を分けるべきとの考えからです。

はじめに

先日、Twitterにて奥野さん(@nippondanji)と私(@pato_taityo)の間でこんなやり取りがありました。

【奥野さん】

DB業界に飛び込んだ当初は、何の疑いもなく「レコード」という用語を使ってしまっていたんだけど、後からこれはRDBでは使うべきではないと思うようになった。はっきり言って誤用。RDBerは「行」という用語をきっちり使うべき。同様にフィールドではなく列(カラム)を使うべき。

https://twitter.com/nippondanji/status/1103218605511008256

【私】

無知で申し訳ないのですが、「レコード」という用語を使うべきでは無い、という理由を教えていただけないでしょうか…?ググってみたものの行き当たれず。また、英語表記であれば何とすべきでしょうか?

https://twitter.com/pato_taityo/status/1103226485123346432

【奥野さん】

SQLにそのような用語はないからです。行(row)、列(column)を使いましょう。

https://twitter.com/nippondanji/status/1103226704573587457

このやり取りをきっかけに用語 (row, column, record, field) の違いを調べることにしました。

奥野さんからは参考書籍として以下の2冊をお勧めされました。

SQL and Relational Theory: How to Write Accurate SQL Code

SQL and Relational Theory: How to Write Accurate SQL Code

  • 作者:Date, C. J.
  • 発売日: 2015/11/16
  • メディア: ペーパーバック

上記2冊の本は手持ちになかったのですが、「プログラマのためのSQL 第4版」(以下、「プログラマのためのSQL」)でも今回のテーマに関する記述がありました。

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

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

そこで今回は「プログラマのためのSQL」をベースに考察を進めることにしました。

Joe Celko による行と列の定義

Joe Celko は「プログラマのためのSQL」の著者です。

Joe Celko はこんな言葉を残しています。

Columns are not fields. Rows are not records. Tables are not files,

Joe Celko - Wikipedia

まさに今回のテーマそのものの言葉です。

この Joe Celko が「プログラマのためのSQL」で行と列をどのように定義したのかを確認します。

行 (row) はレコードではない。レコードはアプリケーションが読み込むことで初めて意味を持つ。レコードはシーケンシャルで、最初、最後、次、その前といった順序が意味を持つ。行はいかなる物理的な順序も持たない(ORDER BY はカーソルにおける句であって、SQLの一部ではない)。
プログラマのためのSQL 第4版 1. データベース VS ファイルシステム

行はレコードではない。レコードはそれを読み込むアプリケーションプログラムの中で定義される。行はデータベーススキーマの中で定義されるのであって、それが意味を持つためにプログラムを必要としない。フィールドの名前は、アプリケーションのREAD文やINPUT文の中で定義されるのに対し、行はデータベーススキーマの中で名付けられる。同様に、READ文におけるフィールド名の物理的順序は絶対である(READ a, b, c は、READ c, a, b ではない。しかし、SELECT a, b, c は SELECT c, a, b と同じデータである)。
プログラマのためのSQL 第4版 1.3 行 VS レコード

列 (column) はフィールドではない。フィールドはそれを読み込むアプリケーションから意味を得る。またアプリケーションによっては複数の意味を持つことがある。フィールドはレコードの中で順序づけられており、データ型も制約もデフォルト値も持っていない。すなわち、列とフィールドの違いは、前者が能動的データであるのに対し、後者は受動的データである、という点が大きな違いである!
プログラマのためのSQL 第4版 1. データベース VS ファイルシステム

データベースは能動的にすべてのデータの正しさを保つように動く。そのための道具は、トリガー、制約、そして宣言整合性制約である。
プログラマのためのSQL 第4版 1.4 列 VS フィールド

この定義の意味をCSVファイルとテーブルを例に確認します。

CSVファイル

100, 10

◆ テーブル

値段 数量
100 10

READ a, b がCSVファイルの1列目を変数a、2列目を変数bに格納する命令であったとします。

引数の順序の異なるREAD文でCSVファイルを読み込んだときの結果を示します。

READ命令 値段 数量
READ 値段, 数量 100 10
READ 数量, 値段 10 100

READ の引数の順序とCSVファイルのフィールドの順序は対応しています。よって、引数の順序が変われば、その値が意味することも変わってきます。

これに対し、以下の2つのクエリの結果は変わりません。
SELECT 値段, 数量 FROM テーブル
SELECT 数量, 値段 FROM テーブル
プログラムで列番号を指定して値を取得すれば、2つのクエリの間で結果が変わると思うかもしれません。ですが、列番号は物理的な順序を意識しています。属性(例では値段・数量)を指定すれば順序を意識する必要はありません。つまり、結果が変わらないといえます。

では、CSVファイルにヘッダをつければフィールドではなく列として扱えるのでしょうか?

値段, 数量
100, 10

これは依然としてフィールドです。なぜなら、ヘッダも含めてその意味するところはアプリケーションによって決まるからです。アプリケーションがヘッダを参考に値を読むことも、ヘッダを無視して値を読むことも可能です。

また、このCSVファイルを表計算ソフトに読み込むのか、テキストエディタで読み込むのかによってもファイルの意味するところが変わります。表計算ソフトであれば表データとして扱うでしょうし、テキストエディタであれば単なるテキストとして扱うでしょう。

このようにアプリケーションが意味を決めるという点で受動的データであり、フィールドといえます。

議論

用語を区別する必要はあるのか?

行とレコードを同一視している記事が多くあります。また、私たちは会話でもこれらの用語を区別することなく用いています。それだけ頻繁に区別なく用いられるこれらの用語を区別する必要はあるのでしょうか?

私はあると考えています。なぜなら、理論を議論する際に定義のあいまいさが解釈の妨げとなるからです。これは勉強会で議論する際に痛感したことでした。題材とした本の用語の定義が明確になっておらず、議論の度にまずはそこでの用語の使い方から議論が始まることになったのです。

用語の定義は議論する際だけに気を付ければよいものではありません。普段から意識しなければ急に切り替えられるものではありませんし、アウトプットも混在したものになります。いざ正しい定義で扱おうとしたときに混乱することになるでしょう。

用語の定義は妥当なのか?

今回参考にした用語の定義は Joe Celko の主張ともいえます。データベースの用語として行 (row) とレコードが混在して用いられているこの状況で、用語の定義は果たして妥当といえるのでしょうか?

この疑問に対するヒントを以下のQ&Aから見つけることができます。
terminology - What is the difference between a "record" and a "row" in SQL Server? - Database Administrators Stack Exchange

このQ&Aで回答者の Aaron Bertrand は以下の回答をしています。

In any case, say what you will about the guy's online character, but he wrote the standard, and the fact that such an authority dictates that there is a distinction should tell you something.

terminology - What is the difference between a "record" and a "row" in SQL Server? - Database Administrators Stack Exchange

Joe Celko は ANSI/ISO SQL 標準化委員会の委員を務めてきました。その彼が用語を区別して用いるべきだと主張しています。

また、回答者の Phil は回答の中で、SQL標準(ドラフト版のようですが)に record より row という単語のほうが多く登場していること、テーブルの説明に row という用語が繰り返し登場していることを挙げています。

このほか、PostgreSQLのマニュアルでも "row" という用語を用いてSQL言語の概念を説明をしています。

Each table is a named collection of rows. Each row of a given table has the same set of named columns, and each column is of a specific data type. Whereas columns have a fixed order in each row, it is important to remember that SQL does not guarantee the order of the rows within the table in any way (although they can be explicitly sorted for display).

PostgreSQL: Documentation: 11: 2.2. Concepts

これらを用語の定義の妥当性とするには根拠が弱いです。ですが、無視できない事実でもあります。

まとめ

行とレコードを区別することなく用いられている現状を踏まえると、データベースの用語として行 (row)・列 (column) を用いるべきという主張にコンセンサスが取れているとはいいがたいです。

ですが、私は論理的存在と物理的存在を用語として明確に分離すべきと考えています。なぜなら、それらは異なる存在だからです。そして、データベースの用語として Joe Celko は行 (row)・列 (column) を提案しました。

あいまいな定義は議論の妨げとなります。より適切な用語を選択するべきという観点から、データベースにおいては用語として行 (row)・列 (column) を積極的に利用すべきではないでしょうか。