各データベースのテーブル名とカラム名の大文字/小文字の扱い


まとめ

各データベースでテーブル名やカラム名の大文字/小文字の扱いが異なる。

DB 引用符なし 引用符あり
PostgreSQL 小文字に正規化(名前の比較は大文字小文字を区別) 大文字小文字を区別
Oracle 大文字に正規化(名前の比較は大文字小文字を区別) 大文字小文字を区別
MySQL データベース名, テーブル名, トリガー名は OS 依存(Windowsでは区別なし、Unixでは区別あり)。カラム名などは常に区別なし 同左
SQL Server 照合順序依存(CIの場合は区別なし、CSの場合は区別あり) 同左
h2 大文字に正規化(名前の比較は大文字小文字を区別) 大文字小文字を区別


予約語と重複する 例えば user テーブルなどを作成したい場合は以下のように引用符で囲むことで対応できる。

create table "user" (...);

この場合、多くのデータベースでは user というテーブルが作成できるが、SQLでは常に引用符で囲む必要がある。

予約語では無くとも "users" のように引用符で囲んでテーブルを作成した場合、例えば Oracle ではSQLが大文字に正規化されUSERS と解釈されてしまうため、常に "users" ように引用符で囲む必要がでてきてしまう。


PostgreSQL

PostgreSQL では、SQL中の識別子を読み取るとき、大文字を小文字に正規化する。 識別子が引用符で囲まれていた場合は、正規化を行わずそのまま処理するため、大文字と小文字が区別される。


Oracle

Oracle では、SQL文は実行時にすべて大文字に変換される。 識別子が引用符で囲まれていた場合は、正規化を行わずそのまま処理するため、大文字と小文字が区別される。


My SQL

MySQL では、データベースはデータディレクトリ内のディレクトリに対応し、テーブルもデータベースディレクトリ内のファイルに対応する。よってデータベース名やテーブル名は基になるオペレーティングシステムで大文字と小文字が区別されるかどうかに影響を受ける( Windows では大文字と小文字が区別されず、ほとんどの Unix 系システムでは大文字と小文字が区別される)。

lower_case_table_names システム変数を 0とするとCREATE TABLEで指定した通りの名前で格納され、名前の比較では大文字と小文字が区別される(Unix におけるデフォルト)。

lower_case_table_names システム変数を 1 とするとテーブル名はディスクに小文字で格納され、名前の比較では小文字に正規化される(Windows におけるデフォルト)。

lower_case_table_names システム変数を 2とするとCREATE TABLEで指定した通りの名前で格納され、名前の比較では、大文字と小文字は区別されない(macOS におけるデフォルト)。


SQL Server

テーブル名、ビュー名、列名など、データベース内のオブジェクトの識別子には、データベースの既定の照合順序の影響を受ける。

照合順序がCS(大文字と小文字を区別する照合順序)の場合は、同じ名前で大文字と小文字のみが異なる 2 つのテーブルを作成できる。

照合順序がCI(大文字と小文字を区別しない照合順序)の場合は、同じ名前で大文字と小文字のみが異なる 2 つのテーブルを作成できない。


h2

データベース設定 DATABASE_TO_UPPER がデフォルトの true の場合、引用符で囲まれていない識別子とデータベースの短縮名が大文字に変換される。

データベース設定 DATABASE_TO_LOWER (デフォルト: false) を true に設定すると、引用符で囲まれていない識別子とデータベースの短縮名が小文字に変換される(実験的機能)。

引用符で囲まれていた場合は大文字と小文字は区別される。


Jakarta Persistence で引用符を強制する

persistence.xml の横に以下の orm.xml を置いておけば、全体で識別子を引用符で囲むように構成できる。

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings version="3.1"
        xmlns="https://jakarta.ee/xml/ns/persistence/orm"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence/orm https://jakarta.ee/xml/ns/persistence/orm_3_1.xsd">
    <persistence-unit-metadata>
        <persistence-unit-defaults>
            <delimited-identifiers/>
        </persistence-unit-defaults>
    </persistence-unit-metadata>
</entity-mappings>

しかし、制約の自動生成などのSQLで不要な引用符が付いたりと、あまり上手く機能しない。

ので、必要な場合には以下のようにアノテーションで個別に設定した方が無難。

@Table(name="\"customer\"")

その場合も、それぞれのデータベースで大文字/小文字の扱いが異なりトラブルの元になるので、極力引用符に頼らない実装に変更した方が良い。