今日もプログラミング

IT技術とかプログラミングのこととか特にJavaを中心に書いていきます

データベースのテーブル名は大文字と小文字のどちらで管理される?

以前、「データベースのテーブル名で大文字と小文字は区別される?」という記事を書いたが、もう少し調査を進めてみた。

 

Oracle

SQL> create table "case_test" (id1 char(2));

表が作成されました。

SQL> select table_name from user_tables;

TABLE_NAME
--------------------------------------------------------------------------------

case_test

1行が選択されました。

SQL> create table case_test (id2 char(2));

表が作成されました。

SQL> select table_name from user_tables;

TABLE_NAME
--------------------------------------------------------------------------------

case_test
CASE_TEST

2行が選択されました。

引用符で囲まない場合は大文字/小文字は区別されないが、大文字に変換されているようだ。

なお、java.sql.DatabaseMetaData#getColumnsでは、大文字/小文字は区別されていた。

(つまり、case_testではCASE_TESTのテーブル情報を取得できなかった)

 

MySQL (Windows)

mysql> create table CASE_TEST (id1 char(2));
Query OK, 0 rows affected (0.09 sec)

mysql> show tables;
+------------------+
| Tables_in_testdb |
+------------------+
| case_test        |
+------------------+
1 rows in set (0.00 sec)

mysql> create table `CASE_TEST` (id2 char(2));
ERROR 1050 (42S01): Table 'case_test' already exists
mysql>

MySQLでは、Windowsの場合は、大文字/小文字が区別されないが、小文字に変換されているようだ。

引用符を付けても、大文字/小文字は区別されない。

なお、java.sql.DatabaseMetaData#getColumnsでは、大文字/小文字は区別されなかった。

 

PostgreSQL

testdb=# create table CASE_TEST (id1 char(2));
CREATE TABLE
testdb=# \d
                        リレーションの一覧
 スキーマ |              名前              |    型    |  所有者
----------+--------------------------------+----------+-----------
 public   | case_test                      | テーブル | test_user
testdb=# create table "CASE_TEST" (id2 char(2));
CREATE TABLE
testdb=# \d
                        リレーションの一覧
 スキーマ |              名前              |    型    |  所有者
----------+--------------------------------+----------+-----------
 public   | CASE_TEST                      | テーブル | test_user
 public   | case_test                      | テーブル | test_user
testdb=#

引用符で囲まない場合は大文字/小文字は区別されないが、小文字に変換されているようだ。

なお、java.sql.DatabaseMetaData#getColumnsでは、大文字/小文字は区別されていた。

(つまり、case_testではCASE_TESTのテーブル情報を取得できなかった)

 

SQL Server (照合順序CI)

1> create table case_test (id1 char(2))
2> go
1> create table [CASE_TEST] (id2 char(2))
2> go
メッセージ 2714、レベル 16、状態 6、サーバー xxxxxxxx\SQLEXPRESS、行 1
データベースに 'CASE_TEST' という名前のオブジェクトが既に存在します。
1> select name from sys.tables
2> go
 name

 -------------------------------------------------------------------------------

        -------------------------------------------------

 case_test

(1 行処理されました)
1>

1> create table CASE_TEST2 (id3 char(2))
2> go
1> create table [case_test2] (id4 char(2))
2> go
メッセージ 2714、レベル 16、状態 6、サーバー xxxxxxxx\SQLEXPRESS、行 1
データベースに 'case_test2' という名前のオブジェクトが既に存在します。
1> select name from sys.tables
2> go
 name

 -------------------------------------------------------------------------------

        -------------------------------------------------

 case_test

 CASE_TEST2

(2 行処理されました)
1>

SQL Serverでは、照合順序がCIを含む場合は、大文字/小文字が区別されない。

引用符で囲んだ場合でも、大文字/小文字は区別されない。

大文字でテーブルを作成すれば大文字のまま、小文字でテーブルを作成すれば小文字のままで、変換はされていないようだ。

なお、java.sql.DatabaseMetaData#getColumnsでは、大文字/小文字は区別されなかった。

 

まとめ

DBMSDBMS内でのテーブル名引用符で囲んだ場合java.sql.DatabaseMetaData #getColumns
Oracle 大文字 大文字/小文字は区別される 大文字/小文字は区別される
MySQL (Windows) 小文字 *1 大文字/小文字は区別されない 大文字/小文字は区別されない
PostgreSQL 小文字 大文字/小文字は区別される 大文字/小文字は区別される
SQL Server (照合順序CI) CREATE文に指定したまま 大文字/小文字は区別されない 大文字/小文字は区別されない

*1 MySQL 5.6 リファレンスマニュアルによると、lower_case_table_names システム変数により大文字にも変えられるようだ。

OraclePostgreSQLは、引用符で囲めば大文字と小文字のテーブル名は混在可能だ。

従って、java.sql.DatabaseMetaData#getColumnsでも大文字と小文字は区別される。

実験はしていないが、MySQL(Linux)やSQL Server(照合順序CIでない)も大文字と小文字は区別されるはずだ。

 

Oracle 12c
MySQL 5.6
PostgreSQL 9.4
SQL Server 2012